private static void CheckConvertFilesStatus(Object obj)
        {
            lock (LockerTimer)
            {
                _timer.Change(Timeout.Infinite, Timeout.Infinite);
            }
            try
            {
                List <File> filesIsConverting;

                lock (LockerStatus)
                {
                    ConversionFileStatus.Where(x => ((!String.IsNullOrEmpty(x.Value.Processed) &&
                                                      DateTime.Now.Subtract(x.Value.StopDateTime) > TimeSpan.FromMinutes(30))))
                    .ToList().ForEach(x => ConversionFileStatus.Remove(x));

                    filesIsConverting = ConversionFileStatus.Where(x => String.IsNullOrEmpty(x.Value.Processed)).Select(x => x.Key).ToList();
                }

                if (filesIsConverting.Count == 0)
                {
                    lock (LockerTimer)
                    {
                        _timer.Dispose();
                        _timer = null;
                    }
                    return;
                }

                foreach (var file in filesIsConverting)
                {
                    var    fileUri = file.ID.ToString();
                    string convetedFileUrl;
                    int    operationResultProgress;
                    object folderId;
                    var    currentFolder = false;

                    try
                    {
                        int      tenantId;
                        IAccount account;

                        lock (LockerStatus)
                        {
                            var operationResult = ConversionFileStatus[file];
                            if (operationResult == null)
                            {
                                continue;
                            }
                            tenantId = operationResult.TenantId;
                            account  = operationResult.Account;
                        }

                        CoreContext.TenantManager.SetCurrentTenant(tenantId);
                        SecurityContext.AuthenticateMe(account);

                        var user    = CoreContext.UserManager.GetUsers(account.ID);
                        var culture = string.IsNullOrEmpty(user.CultureName)
                                          ? CoreContext.TenantManager.GetCurrentTenant().GetCulture()
                                          : CultureInfo.GetCultureInfo(user.CultureName);
                        Thread.CurrentThread.CurrentCulture   = culture;
                        Thread.CurrentThread.CurrentUICulture = culture;

                        var fileSecurity = Global.GetFilesSecurity();
                        if (!fileSecurity.CanRead(file) &&
                            file.RootFolderType != FolderType.BUNCH)    //No rights in CRM after upload before attach
                        {
                            throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_ReadFile);
                        }
                        if (file.ContentLength > SetupInfo.AvailableFileSize)
                        {
                            throw new Exception(string.Format(FilesCommonResource.ErrorMassage_FileSizeConvert, FileSizeComment.FilesSizeToString(SetupInfo.AvailableFileSize)));
                        }

                        folderId = Global.FolderMy;
                        using (var folderDao = Global.DaoFactory.GetFolderDao())
                        {
                            var parent = folderDao.GetFolder(file.FolderID);
                            if (parent != null &&
                                fileSecurity.CanCreate(parent))
                            {
                                folderId      = parent.ID;
                                currentFolder = true;
                            }
                        }
                        if (Equals(folderId, 0))
                        {
                            throw new SecurityException(FilesCommonResource.ErrorMassage_FolderNotFound);
                        }

                        fileUri = PathProvider.GetFileStreamUrl(file);

                        var toExtension   = FileUtility.GetInternalExtension(file.Title);
                        var fileExtension = file.ConvertedType ?? FileUtility.GetFileExtension(file.Title);
                        var docKey        = DocumentServiceHelper.GetDocKey(file.ID, file.Version, file.ModifiedOn);

                        operationResultProgress = DocumentServiceConnector.GetConvertedUri(fileUri, fileExtension, toExtension, docKey, true, out convetedFileUrl);
                    }
                    catch (Exception exception)
                    {
                        lock (LockerStatus)
                        {
                            var operationResult = ConversionFileStatus[file];
                            if (operationResult != null)
                            {
                                if (operationResult.Delete)
                                {
                                    ConversionFileStatus.Remove(file);
                                }
                                else
                                {
                                    operationResult.Result       = FileJsonSerializer(file);
                                    operationResult.Processed    = "1";
                                    operationResult.StopDateTime = DateTime.Now;
                                    operationResult.Error        = exception.Message;
                                }
                            }
                        }

                        var strExc = exception.Message + " in file " + fileUri;
                        Global.Logger.Error(strExc, exception);

                        continue;
                    }

                    if (operationResultProgress < 100)
                    {
                        lock (LockerStatus)
                        {
                            var operationResult = ConversionFileStatus[file];
                            if (operationResult != null)
                            {
                                operationResult.Progress = operationResultProgress;
                            }
                        }
                        continue;
                    }

                    using (var fileDao = Global.DaoFactory.GetFileDao())
                        using (var folderDao = Global.DaoFactory.GetFolderDao())
                        {
                            var newFileTitle = FileUtility.ReplaceFileExtension(file.Title, FileUtility.GetInternalExtension(file.Title));

                            File newFile = null;
                            if (FilesSettings.UpdateIfExist && (!currentFolder || !file.ProviderEntry))
                            {
                                newFile = fileDao.GetFile(folderId, newFileTitle);
                                if (newFile != null &&
                                    Global.GetFilesSecurity().CanEdit(newFile) &&
                                    !EntryManager.FileLockedForMe(newFile.ID) &&
                                    !FileTracker.IsEditing(newFile.ID))
                                {
                                    newFile.Version++;
                                }
                                else
                                {
                                    newFile = null;
                                }
                            }

                            if (newFile == null)
                            {
                                newFile = new File {
                                    FolderID = folderId
                                }
                            }
                            ;

                            newFile.Title         = newFileTitle;
                            newFile.ConvertedType = FileUtility.GetInternalExtension(file.Title);

                            var operationResultError = string.Empty;
                            try
                            {
                                var req = (HttpWebRequest)WebRequest.Create(convetedFileUrl);

                                using (var convertedFileStream = new ResponseStream(req.GetResponse()))
                                {
                                    newFile.ContentLength = convertedFileStream.Length;
                                    newFile.Comment       = string.Empty;
                                    newFile = fileDao.SaveFile(newFile, convertedFileStream);
                                }

                                FileMarker.MarkAsNew(newFile);

                                using (var tagDao = Global.DaoFactory.GetTagDao())
                                {
                                    var tags = tagDao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList();
                                    if (tags.Any())
                                    {
                                        tags.ForEach(r => r.EntryId = newFile.ID);
                                        tagDao.SaveTags(tags.ToArray());
                                    }
                                }

                                operationResultProgress = 100;
                            }
                            catch (WebException e)
                            {
                                using (var response = e.Response)
                                {
                                    var httpResponse = (HttpWebResponse)response;
                                    var errorString  = String.Format("Error code: {0}", httpResponse.StatusCode);

                                    if (httpResponse.StatusCode != HttpStatusCode.NotFound)
                                    {
                                        using (var data = response.GetResponseStream())
                                        {
                                            var text = new StreamReader(data).ReadToEnd();
                                            errorString += String.Format(" Error message: {0}", text);
                                        }
                                    }

                                    operationResultError = errorString;

                                    Global.Logger.Error(errorString + "  ConvertUrl : " + convetedFileUrl + "    fromUrl : " + fileUri, e);
                                    throw new Exception(errorString);
                                }
                            }
                            finally
                            {
                                var fileSecurity   = Global.GetFilesSecurity();
                                var removeOriginal = !FilesSettings.StoreOriginalFiles &&
                                                     fileSecurity.CanDelete(file) &&
                                                     currentFolder &&
                                                     !EntryManager.FileLockedForMe(file.ID);

                                var folderTitle = folderDao.GetFolder(newFile.FolderID).Title;

                                lock (LockerStatus)
                                {
                                    var operationResult = ConversionFileStatus[file];

                                    if (operationResult.Delete)
                                    {
                                        ConversionFileStatus.Remove(file);
                                    }
                                    else
                                    {
                                        operationResult.Result       = FileJsonSerializer(newFile, removeOriginal, folderTitle);
                                        operationResult.Processed    = "1";
                                        operationResult.StopDateTime = DateTime.Now;
                                        operationResult.Progress     = operationResultProgress;
                                        if (!string.IsNullOrEmpty(operationResultError))
                                        {
                                            operationResult.Error = operationResultError;
                                        }
                                    }
                                }

                                if (removeOriginal)
                                {
                                    FileMarker.RemoveMarkAsNewForAll(file);
                                    fileDao.DeleteFile(file.ID);
                                }
                            }
                        }
                }

                lock (LockerTimer)
                {
                    _timer.Change(0, TimerConvertPeriod);
                }
            }
            catch (Exception exception)
            {
                Global.Logger.Error(exception.Message, exception);
                lock (LockerTimer)
                {
                    _timer.Dispose();
                    _timer = null;
                }
            }
        }
Example #2
0
        private static void CheckConvertFilesStatus(object _)
        {
            if (Monitor.TryEnter(singleThread))
            {
                try
                {
                    List <File> filesIsConverting;
                    lock (locker)
                    {
                        timer.Change(Timeout.Infinite, Timeout.Infinite);

                        conversionQueue.Where(x => !string.IsNullOrEmpty(x.Value.Processed) &&
                                              (x.Value.Progress == 100 && DateTime.Now - x.Value.StopDateTime > TimeSpan.FromMinutes(1) ||
                                               DateTime.Now - x.Value.StopDateTime > TimeSpan.FromMinutes(30)))
                        .ToList()
                        .ForEach(x =>
                        {
                            conversionQueue.Remove(x);
                            cache.Remove(GetKey(x.Key));
                        });

                        Global.Logger.DebugFormat("Run CheckConvertFilesStatus: count {0}", conversionQueue.Count);

                        if (conversionQueue.Count == 0)
                        {
                            return;
                        }

                        filesIsConverting = conversionQueue
                                            .Where(x => String.IsNullOrEmpty(x.Value.Processed))
                                            .Select(x => x.Key)
                                            .ToList();
                    }

                    foreach (var file in filesIsConverting)
                    {
                        var    fileUri = file.ID.ToString();
                        string convertedFileUrl;
                        int    operationResultProgress;
                        object folderId;
                        var    currentFolder = false;

                        try
                        {
                            int      tenantId;
                            IAccount account;

                            lock (locker)
                            {
                                if (!conversionQueue.Keys.Contains(file))
                                {
                                    continue;
                                }

                                var operationResult = conversionQueue[file];
                                if (!string.IsNullOrEmpty(operationResult.Processed))
                                {
                                    continue;
                                }

                                operationResult.Processed = "1";
                                tenantId = operationResult.TenantId;
                                account  = operationResult.Account;

                                cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(30));
                            }

                            CoreContext.TenantManager.SetCurrentTenant(tenantId);
                            SecurityContext.AuthenticateMe(account);

                            var user    = CoreContext.UserManager.GetUsers(account.ID);
                            var culture = string.IsNullOrEmpty(user.CultureName) ? CoreContext.TenantManager.GetCurrentTenant().GetCulture() : CultureInfo.GetCultureInfo(user.CultureName);
                            Thread.CurrentThread.CurrentCulture   = culture;
                            Thread.CurrentThread.CurrentUICulture = culture;

                            var fileSecurity = Global.GetFilesSecurity();
                            if (!fileSecurity.CanRead(file) && file.RootFolderType != FolderType.BUNCH)
                            {
                                //No rights in CRM after upload before attach
                                throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_ReadFile);
                            }
                            if (file.ContentLength > SetupInfo.AvailableFileSize)
                            {
                                throw new Exception(string.Format(FilesCommonResource.ErrorMassage_FileSizeConvert, FileSizeComment.FilesSizeToString(SetupInfo.AvailableFileSize)));
                            }

                            folderId = Global.FolderMy;
                            using (var folderDao = Global.DaoFactory.GetFolderDao())
                            {
                                var parent = folderDao.GetFolder(file.FolderID);
                                if (parent != null &&
                                    fileSecurity.CanCreate(parent))
                                {
                                    folderId      = parent.ID;
                                    currentFolder = true;
                                }
                            }
                            if (Equals(folderId, 0))
                            {
                                throw new SecurityException(FilesCommonResource.ErrorMassage_FolderNotFound);
                            }

                            fileUri = PathProvider.GetFileStreamUrl(file);

                            var toExtension   = FileUtility.GetInternalExtension(file.Title);
                            var fileExtension = file.ConvertedExtension;
                            var docKey        = DocumentServiceHelper.GetDocKey(file.ID, file.Version, file.ModifiedOn);

                            operationResultProgress = DocumentServiceConnector.GetConvertedUri(fileUri, fileExtension, toExtension, docKey, true, out convertedFileUrl);
                            operationResultProgress = Math.Min(operationResultProgress, 100);
                        }
                        catch (Exception exception)
                        {
                            Global.Logger.ErrorFormat("Error convert {0} with url {1}: {2}", file.ID, fileUri, exception);
                            lock (locker)
                            {
                                if (conversionQueue.Keys.Contains(file))
                                {
                                    var operationResult = conversionQueue[file];
                                    if (operationResult.Delete)
                                    {
                                        conversionQueue.Remove(file);
                                        cache.Remove(GetKey(file));
                                    }
                                    else
                                    {
                                        operationResult.Result       = FileJsonSerializer(file);
                                        operationResult.Progress     = 100;
                                        operationResult.StopDateTime = DateTime.Now;
                                        operationResult.Error        = exception.Message;
                                        cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(30));
                                    }
                                }
                            }
                            continue;
                        }

                        if (operationResultProgress < 100)
                        {
                            lock (locker)
                            {
                                if (conversionQueue.Keys.Contains(file))
                                {
                                    var operationResult = conversionQueue[file];
                                    operationResult.Processed = "";
                                    operationResult.Progress  = operationResultProgress;
                                    cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(30));
                                }
                            }
                            continue;
                        }

                        using (var fileDao = Global.DaoFactory.GetFileDao())
                            using (var folderDao = Global.DaoFactory.GetFolderDao())
                            {
                                var newFileTitle = FileUtility.ReplaceFileExtension(file.Title, FileUtility.GetInternalExtension(file.Title));

                                File newFile = null;
                                if (FilesSettings.UpdateIfExist && (!currentFolder || !file.ProviderEntry))
                                {
                                    newFile = fileDao.GetFile(folderId, newFileTitle);
                                    if (newFile != null && Global.GetFilesSecurity().CanEdit(newFile) && !EntryManager.FileLockedForMe(newFile.ID) && !FileTracker.IsEditing(newFile.ID))
                                    {
                                        newFile.Version++;
                                    }
                                    else
                                    {
                                        newFile = null;
                                    }
                                }

                                if (newFile == null)
                                {
                                    newFile = new File {
                                        FolderID = folderId
                                    };
                                }
                                newFile.Title         = newFileTitle;
                                newFile.ConvertedType = null;
                                newFile.Comment       = string.Format(FilesCommonResource.CommentConvert, file.Title);

                                var operationResultError = string.Empty;
                                try
                                {
                                    var req = (HttpWebRequest)WebRequest.Create(convertedFileUrl);

                                    if (WorkContext.IsMono && ServicePointManager.ServerCertificateValidationCallback == null)
                                    {
                                        ServicePointManager.ServerCertificateValidationCallback += (s, c, n, p) => true; //HACK: http://ubuntuforums.org/showthread.php?t=1841740
                                    }

                                    using (var convertedFileStream = new ResponseStream(req.GetResponse()))
                                    {
                                        newFile.ContentLength = convertedFileStream.Length;
                                        newFile = fileDao.SaveFile(newFile, convertedFileStream);
                                    }

                                    FilesMessageService.Send(newFile, MessageInitiator.DocsService, MessageAction.FileConverted, newFile.Title);
                                    FileMarker.MarkAsNew(newFile);

                                    using (var tagDao = Global.DaoFactory.GetTagDao())
                                    {
                                        var tags = tagDao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList();
                                        if (tags.Any())
                                        {
                                            tags.ForEach(r => r.EntryId = newFile.ID);
                                            tagDao.SaveTags(tags.ToArray());
                                        }
                                    }

                                    operationResultProgress = 100;
                                }
                                catch (WebException e)
                                {
                                    using (var response = e.Response)
                                    {
                                        var httpResponse = (HttpWebResponse)response;
                                        var errorString  = String.Format("Error code: {0}", httpResponse.StatusCode);

                                        if (httpResponse.StatusCode != HttpStatusCode.NotFound)
                                        {
                                            using (var data = response.GetResponseStream())
                                            {
                                                var text = new StreamReader(data).ReadToEnd();
                                                errorString += String.Format(" Error message: {0}", text);
                                            }
                                        }

                                        operationResultProgress = 100;
                                        operationResultError    = errorString;

                                        Global.Logger.ErrorFormat("{0} ConvertUrl: {1} fromUrl: {2}: {3}", errorString, convertedFileUrl, fileUri, e);
                                        throw new Exception(errorString);
                                    }
                                }
                                finally
                                {
                                    var fileSecurity   = Global.GetFilesSecurity();
                                    var removeOriginal = !FilesSettings.StoreOriginalFiles && fileSecurity.CanDelete(file) && currentFolder && !EntryManager.FileLockedForMe(file.ID);
                                    var folderTitle    = folderDao.GetFolder(newFile.FolderID).Title;

                                    lock (locker)
                                    {
                                        if (conversionQueue.Keys.Contains(file))
                                        {
                                            var operationResult = conversionQueue[file];
                                            if (operationResult.Delete)
                                            {
                                                conversionQueue.Remove(file);
                                                cache.Remove(GetKey(file));
                                            }
                                            else
                                            {
                                                operationResult.Result       = FileJsonSerializer(newFile, removeOriginal, folderTitle);
                                                operationResult.StopDateTime = DateTime.Now;
                                                operationResult.Processed    = "1";
                                                operationResult.Progress     = operationResultProgress;
                                                if (!string.IsNullOrEmpty(operationResultError))
                                                {
                                                    operationResult.Error = operationResultError;
                                                }
                                                cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(30));
                                            }
                                        }
                                    }

                                    if (removeOriginal)
                                    {
                                        FileMarker.RemoveMarkAsNewForAll(file);
                                        fileDao.DeleteFile(file.ID);
                                    }
                                }
                            }
                    }

                    lock (locker)
                    {
                        timer.Change(TIMER_PERIOD, TIMER_PERIOD);
                    }
                }
                catch (Exception exception)
                {
                    Global.Logger.Error(exception.Message, exception);
                    lock (locker)
                    {
                        timer.Change(Timeout.Infinite, Timeout.Infinite);
                    }
                }
                finally
                {
                    Monitor.Exit(singleThread);
                }
            }
        }