예제 #1
0
        public async Task <bool> upload(string vdir_path, string filepath, string filename = null)
        {
            string etag = QETag.calcETag(filepath);

            if (filename == null)
            {
                filename = System.IO.Path.GetFileName(filepath);
            }
            var data1 = new { path = vdir_path, hash = etag, name = filename };
            //await post("/v2/user/login", data1);
            var json = await jsonPost("/v2/upload/token", data1);

            bool suc = json["success"].ToObject <bool>();

            if (!suc)
            {
                return(false);
            }
            var cached = json["result"]["hashCached"].ToObject <bool>();

            if (!cached)
            {
                var uploadInfo = json["result"]["uploadInfo"];
                var token      = uploadInfo["uploadToken"].ToString();
                var uploadUrl  = uploadInfo["uploadUrl"].ToString();
                using (var fs = System.IO.File.OpenRead(filepath))
                    await upload_streamAsync2(uploadUrl, fs, token, filename);
            }
            return(true);
        }
예제 #2
0
        private void ProcessClipBoard()
        {
            if (System.Windows.Clipboard.ContainsImage())
            {
                MessageStr = Properties.Resources.UpLoading;

                BmpBitmapEncoder enc = new BmpBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(System.Windows.Clipboard.GetImage()));

                string lFileName     = CreateFileName();
                string lSaveFilePath = System.IO.Path.Combine(Properties.Resources.ImageSavePathDir, lFileName);
                using (FileStream fs = new FileStream(lSaveFilePath, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    enc.Save(fs);
                    fs.Close();
                }

                //because unkown reason, when use wechat snapshot hotkey, the message will process twice, to avoid this, check whether we save the same file
                string lLocalHash = QETag.hash(lSaveFilePath);
                if (historyLog.ContainsKey(lLocalHash))
                {
                    File.Delete(lSaveFilePath);
                    URL           = CreateURL(historyLog[lLocalHash][0]);
                    lSaveFilePath = System.IO.Path.Combine(Properties.Resources.ImageSavePathDir, historyLog[lLocalHash][0]);
                }
                else
                {
                    if (!UpLoadFile(lSaveFilePath))
                    {
                        File.Delete(lSaveFilePath);
                    }
                }
            }
        }
예제 #3
0
        private void uploadFile(string filePath, string fileName, string bucket, string accessKey, string secretKey)
        {
            this.cancelSignal = false;
            updateProgress(0);
            //check if file exists in the bucket
            appendLog("正在检查空间中是否存在同名文件...");
            Mac           mac        = new Mac(accessKey, secretKey);
            BucketManager manager    = new BucketManager(mac);
            StatResult    statResult = manager.stat(bucket, fileName);

            if (!string.IsNullOrEmpty(statResult.Hash))
            {
                appendLog("该文件已存在,如需上传同名文件,请先从远程删除");
            }
            else
            {
                if (statResult.ResponseInfo.StatusCode == 612)
                {
                    appendLog("空间中不存在同名文件,计算文件hash中...");
                    string qetag = QETag.hash(filePath);
                    if (!string.IsNullOrEmpty(qetag))
                    {
                        appendLog("文件hash为:" + qetag);
                        PutPolicy putPolicy = new PutPolicy();
                        putPolicy.Scope = bucket;
                        putPolicy.SetExpires(30 * 24 * 60 * 60);
                        string uploadToken = Auth.createUploadToken(putPolicy, mac);
                        upload(filePath, fileName, qetag, uploadToken);
                    }
                }
                else
                {
                    appendLog("获取同名文件信息失败!" + statResult.ResponseInfo.Error);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// 1.根据设定参数进行必要的配置
        /// 2.检查过滤之后,生成待上传的文件列表并展示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonCheckFilesToUpload_Click(object sender, RoutedEventArgs e)
        {
            #region CHECK_SYNC_SETTINS

            // 检查并设置AK&SK
            if (string.IsNullOrEmpty(this.account.AccessKey) || string.IsNullOrEmpty(this.account.SecretKey))
            {
                this.SettingsErrorTextBlock.Text = "请设置AK&SK";
                return;
            }

            SystemConfig.ACCESS_KEY = this.account.AccessKey;
            SystemConfig.SECRET_KEY = this.account.SecretKey;

            // 检查本地同步目录与远程同步空间
            string syncDirectory = this.SyncLocalFolderTextBox.Text.Trim();
            if (string.IsNullOrEmpty(syncDirectory) || !Directory.Exists(syncDirectory))
            {
                this.SettingsErrorTextBlock.Text = "请设置本地待同步的目录";
                return;
            }
            if (this.SyncTargetBucketsComboBox.SelectedIndex < 0)
            {
                this.SettingsErrorTextBlock.Text = "请设置目标空间";
                return;
            }

            string targetBucket = this.SyncTargetBucketsComboBox.SelectedItem.ToString();

            if (this.syncSetting == null)
            {
                this.syncSetting = new SyncSetting();
            }

            this.syncSetting.LocalDirectory       = syncDirectory;
            this.syncSetting.TargetBucket         = targetBucket;
            this.syncSetting.SyncPrefix           = this.PrefixTextBox.Text.Trim();
            this.syncSetting.SkipPrefixes         = this.SkipPrefixesTextBox.Text.Trim();
            this.syncSetting.SkipSuffixes         = this.SkipSuffixesTextBox.Text.Trim();
            this.syncSetting.CheckNewFiles        = this.CheckNewFilesCheckBox.IsChecked.Value;
            this.syncSetting.UseShortFilename     = this.CheckBoxUseShortFilename.IsChecked.Value;
            this.syncSetting.OverwriteDuplicate   = this.RadioButtonOverwriteDuplicate.IsChecked.Value;
            this.syncSetting.SyncThreadCount      = (int)this.ThreadCountSlider.Value;
            this.syncSetting.ChunkUploadThreshold = (int)this.ChunkUploadThresholdSlider.Value * 1024 * 1024;
            this.syncSetting.DefaultChunkSize     = this.defaultChunkSize;
            this.syncSetting.UploadFromCDN        = this.RadioButtonFromCDN.IsChecked.Value;

            #endregion CHECK_SYNC_SETTINS

            #region SIMULATION

            StatResult statResult = this.bucketManager.stat(this.syncSetting.TargetBucket, "NONE_EXIST_KEY");

            if (statResult.ResponseInfo.isNetworkBroken())
            {
                this.SettingsErrorTextBlock.Text = "网络故障";
                return;
            }

            if (statResult.ResponseInfo.StatusCode == 401)
            {
                //ak & sk not right
                this.SettingsErrorTextBlock.Text = "AK 或 SK 不正确";
                return;
            }
            else if (statResult.ResponseInfo.StatusCode == 631)
            {
                //bucket not exist
                this.SettingsErrorTextBlock.Text = "指定空间不存在";
                return;
            }
            else if (statResult.ResponseInfo.StatusCode == 612 ||
                     statResult.ResponseInfo.StatusCode == 200)
            {
                //file exists or not
                //ignore
            }
            else if (statResult.ResponseInfo.StatusCode == 400)
            {
                if (string.IsNullOrEmpty(statResult.ResponseInfo.Error))
                {
                    this.SettingsErrorTextBlock.Text = "未知错误(状态代码400)";
                }
                else
                {
                    if (statResult.ResponseInfo.Error.Equals("incorrect zone"))
                    {
                        this.SettingsErrorTextBlock.Text = "上传入口机房设置错误";
                    }
                    else
                    {
                        this.SettingsErrorTextBlock.Text = statResult.ResponseInfo.Error;
                    }
                }
                return;
            }
            else
            {
                this.SettingsErrorTextBlock.Text = "未知错误,请联系七牛";
                Log.Error(string.Format("get buckets unknown error, {0}:{1}:{2}:{3}", statResult.ResponseInfo.StatusCode,
                                        statResult.ResponseInfo.Error, statResult.ResponseInfo.ReqId, statResult.Response));
                return;
            }

            #endregion SIMULATION

            int numFiles  = 0; // 总文件数
            int numUpload = 0; // 待上传文件数
            uploadItems.Clear();
            this.FilesToUploadDataGrid.DataContext = null;

            List <string> localFiles   = new List <string>(); // 本地待上传的文件
            List <string> saveKeys     = new List <string>(); // 保存到空间文件名
            List <string> fileEtags    = new List <string>(); // 待上传文件的ETAG
            List <long>   lastModified = new List <long>();   // 文件最后修改时间
            List <bool>   fileSkip     = new List <bool>();   // 是否跳过该文件(不上传)

            long T0 = (TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0))).Ticks;

            #region TRAVERSE_LOCAL_DIRECTORY

            DirectoryInfo di  = new DirectoryInfo(syncDirectory);
            FileInfo[]    ffi = di.GetFiles("*.*", SearchOption.AllDirectories);
            numFiles = ffi.Length;

            string savePrefix = this.PrefixTextBox.Text.Trim();

            if (this.syncSetting.UseShortFilename)
            {
                foreach (var fi in ffi)
                {
                    localFiles.Add(fi.FullName);
                    saveKeys.Add(savePrefix + fi.Name);
                    fileEtags.Add("_");
                    lastModified.Add((fi.LastWriteTime.Ticks - T0) / 10000);
                    fileSkip.Add(false);
                }
            }
            else
            {
                foreach (var fi in ffi)
                {
                    localFiles.Add(fi.FullName);
                    saveKeys.Add(savePrefix + fi.FullName);
                    fileEtags.Add("_");
                    lastModified.Add((fi.LastWriteTime.Ticks - T0) / 10000);
                    fileSkip.Add(false);
                }
            }

            #endregion TRAVERSE_LOCAL_DIRECTORY

            #region CHECK_PREFIX_SUFFX

            string skipPrefixes = this.SkipPrefixesTextBox.Text.Trim();
            string skipSuffixes = this.SkipSuffixesTextBox.Text.Trim();

            for (int i = 0; i < numFiles; ++i)
            {
                string saveKey = saveKeys[i];

                string[] ssPrfx = skipPrefixes.Split(',');
                foreach (string prefix in ssPrfx)
                {
                    if (!string.IsNullOrWhiteSpace(prefix))
                    {
                        if (saveKey.StartsWith(prefix.Trim()))
                        {
                            fileSkip[i] = true;
                            break;
                        }
                    }
                }

                string[] ssSufx = skipSuffixes.Split(',');
                foreach (string suffix in ssSufx)
                {
                    if (!string.IsNullOrWhiteSpace(suffix))
                    {
                        if (saveKey.EndsWith(suffix.Trim()))
                        {
                            fileSkip[i] = true;
                            break;
                        }
                    }
                }
            }
            #endregion CHECK_PREFIX_SUFFX

            string hashDBFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "qsunsync", "local_hash.db");
            if (!File.Exists(hashDBFile))
            {
                CachedHash.CreateCachedHashDB(hashDBFile);
            }
            SQLiteConnection localHashDBConn = new SQLiteConnection(string.Format("data source = {0}", hashDBFile));
            localHashDBConn.Open();
            Dictionary <string, HashDBItem> localHashDict = CachedHash.GetAllItems(localHashDBConn);
            localHashDBConn.Close();

            #region CHECK_LOCAL_DUPLICATE

            if (this.syncSetting.CheckNewFiles)
            {
                for (int i = 0; i < numFiles; ++i)
                {
                    if (fileSkip[i])
                    {
                        continue;
                    }

                    string fileName = localFiles[i];

                    if (localHashDict.ContainsKey(fileName))
                    {
                        string oldEtag = localHashDict[fileName].FileHash;
                        string newEtag = QETag.hash(fileName);

                        if (string.Equals(oldEtag, newEtag))
                        {
                            fileSkip[i] = true;
                        }
                        else
                        {
                            fileEtags[i] = newEtag;
                        }
                    }
                    else
                    {
                        fileEtags[i] = QETag.hash(fileName);
                    }
                }
            }
            else
            {
                for (int i = 0; i < numFiles; ++i)
                {
                    if (fileSkip[i])
                    {
                        continue;
                    }
                    fileEtags[i] = QETag.hash(localFiles[i]);
                }
            }

            #endregion CHECK_LOCAL_DUPLICATE

            #region CHECK_REMOTE_DUPLICATES

            // 如果选择了“强制覆盖”,那么无需进行远程检查
            if (!this.syncSetting.OverwriteDuplicate)
            {
                List <string> remoteHash   = new List <string>();
                List <long>   remoteUpdate = new List <long>();

                try
                {
                    Mac mac = new Mac(this.account.AccessKey, this.account.SecretKey);
                    BucketFileHash.BatchStat(mac, targetBucket, saveKeys, fileSkip, ref remoteHash, ref remoteUpdate);

                    for (int i = 0, k = 0; i < numFiles; ++i)
                    {
                        if (fileSkip[i])
                        {
                            continue;
                        }

                        if (string.Equals(fileEtags[i], remoteHash[k]))
                        {
                            // 云端已存在相同文件,跳过
                            fileSkip[i] = true;
                        }

                        ++k;
                    }
                }
                catch (Exception ex)
                {
                    this.SettingsErrorTextBlock.Text = ex.Message;
                    Log.Error(ex.Message);
                }
            }

            #endregion CHECK_REMOTE_DUPLICATES

            #region SHOW_UPLOAD_DETAILS

            this.SyncSettingTabControl.SelectedItem = this.TabItemFilesToUploadDetail;

            numUpload = numFiles;

            foreach (var b in fileSkip)
            {
                if (b)
                {
                    --numUpload;
                }
            }

            if (numUpload < 1)
            {
                TextBlockFilesToUploadSummery.Text = "没有待上传的文件";
                return;
            }


            double N = 0;

            for (int i = 0; i < numFiles; ++i)
            {
                if (fileSkip[i])
                {
                    continue;
                }

                string fsize = "0";

                long   n = ffi[i].Length;
                double K = 1.0 * n / 1024.0;
                double M = 0.0;
                if (K > 1024.0)
                {
                    M     = K / 1024.0;
                    fsize = string.Format("{0:0.00}MB", M);
                }
                else if (K > 1.0)
                {
                    fsize = string.Format("{0:0.00}KB", K);
                }
                else
                {
                    fsize = string.Format("{0}B", n);
                }

                N += n;

                uploadItems.Add(new UploadItem()
                {
                    LocalFile  = localFiles[i],
                    SaveKey    = saveKeys[i],
                    FileSize   = fsize,
                    FileHash   = fileEtags[i],
                    LastUpdate = lastModified[i].ToString()
                });
            }

            string vol  = "";
            double mega = 1024.0 * 1024;
            double kilo = 1024.0;
            if (N > mega)
            {
                vol = string.Format("{0:0.00}MB", N / mega);
            }
            else if (N > kilo)
            {
                vol = string.Format("{0:0.00}KB", N / kilo);
            }
            else
            {
                vol = string.Format("{0}B", N);
            }

            TextBlockFilesToUploadSummery.Text = string.Format("待上传的文件总数:{0}, 总大小:{1}", numUpload, vol);

            Dispatcher.Invoke(new Action(delegate
            {
                ObservableCollection <UploadItem> dataSource = new ObservableCollection <UploadItem>();
                foreach (var d in uploadItems)
                {
                    dataSource.Add(d);
                }
                this.FilesToUploadDataGrid.DataContext = dataSource;
            }));

            ButtonStartSync.IsEnabled = true;

            #endregion SHOW_UPLOAD_DETAILS
        }
예제 #5
0
        private bool UpLoadFile(string filepath)
        {
            string filename = System.IO.Path.GetFileName(filepath);

            Qiniu.Util.Mac lMac           = new Qiniu.Util.Mac(UserAccount.AccessKey, UserAccount.SecretKey);
            string         lRemoteHash    = RemoteFileInfo.RemoteFileStat(lMac, UserAccount.SpaceName, filename);
            bool           lSkip          = false;
            bool           lUpLoadSuccess = false;
            //check local
            string lLocalHash = String.Empty;

            if (!string.IsNullOrEmpty(lRemoteHash))
            {
                lLocalHash = QETag.hash(filepath);

                if (historyLog.ContainsKey(lLocalHash))
                {
                    if (historyLog[lLocalHash].Contains(filename))
                    {
                        lSkip          = true;
                        URL            = CreateURL(filename);
                        lUpLoadSuccess = true;
                    }
                }
                else if (string.Equals(lLocalHash, lRemoteHash))
                {
                    lSkip          = true;
                    URL            = CreateURL(filename);
                    lUpLoadSuccess = true;
                }
            }
            if (!lSkip)
            {
                putPolicy.Scope = UserAccount.SpaceName;
                putPolicy.SetExpires(3600 * 24 * 30);
                string        lUploadToken = Auth.createUploadToken(putPolicy, lMac);
                UploadManager lUploadMgr   = new UploadManager();
                lUploadMgr.uploadFile(filepath, filename, lUploadToken, null, new UpCompletionHandler(delegate(string key, ResponseInfo responseinfo, string response)
                {
                    if (responseinfo.StatusCode != 200)
                    {
                        MessageStr = Properties.Resources.ErrorMessage;
                    }
                    else
                    {
                        MessageStr = Properties.Resources.SuccessMessage;
                        if (historyLog.ContainsKey(lLocalHash))
                        {
                            historyLog[lLocalHash].Add(filename);
                        }
                        URL            = CreateURL(filename);
                        lUpLoadSuccess = true;
                    }
                }));
            }

            if (lUpLoadSuccess)
            {
                DisplayImage(filepath);
                MessageStr = URL;
            }

            return(lUpLoadSuccess);
        }
예제 #6
0
        public void uploadFile(object file)
        {
            if (syncProgressPage.checkCancelSignal())
            {
                this.doneEvent.Set();
                return;
            }
            string fileFullPath = file.ToString();

            if (!File.Exists(fileFullPath))
            {
                Log.Error(string.Format("file not found error, {0}", fileFullPath));
                this.doneEvent.Set();
                return;
            }
            //check skipped rules
            int    fileRelativePathIndex = fileFullPath.IndexOf(this.syncSetting.SyncLocalDir);
            string fileRelativePath      = fileFullPath.Substring(fileRelativePathIndex + this.syncSetting.SyncLocalDir.Length);

            if (fileRelativePath.StartsWith("\\"))
            {
                fileRelativePath = fileRelativePath.Substring(1);
            }

            string[] skippedPrefixes = this.syncSetting.SkipPrefixes.Split(',');

            foreach (string prefix in skippedPrefixes)
            {
                if (!string.IsNullOrWhiteSpace(prefix))
                {
                    if (fileRelativePath.StartsWith(prefix.Trim()))
                    {
                        //skip by prefix
                        this.syncProgressPage.addFileSkippedLog(string.Format("{0}\t{1}", this.syncSetting.SyncTargetBucket,
                                                                              fileFullPath));
                        this.syncProgressPage.updateUploadLog("按照前缀规则跳过文件不同步 " + fileFullPath);
                        this.syncProgressPage.updateTotalUploadProgress();
                        this.doneEvent.Set();
                        return;
                    }
                }
            }

            string[] skippedSuffixes = this.syncSetting.SkipSuffixes.Split(',');
            foreach (string suffix in skippedSuffixes)
            {
                if (!string.IsNullOrWhiteSpace(suffix))
                {
                    if (fileRelativePath.EndsWith(suffix.Trim()))
                    {
                        //skip by suffix
                        this.syncProgressPage.addFileSkippedLog(string.Format("{0}\t{1}", this.syncSetting.SyncTargetBucket,
                                                                              fileFullPath));
                        this.syncProgressPage.updateUploadLog("按照后缀规则跳过文件不同步 " + fileFullPath);
                        this.syncProgressPage.updateTotalUploadProgress();
                        this.doneEvent.Set();
                        return;
                    }
                }
            }

            //generate the file key
            string fileKey = "";

            if (this.syncSetting.IgnoreDir)
            {
                //check ignore dir
                fileKey = System.IO.Path.GetFileName(fileFullPath);
            }
            else
            {
                string newFileFullPath = fileFullPath.Replace('\\', '/');
                string newLocalSyncDir = this.syncSetting.SyncLocalDir.Replace('\\', '/');
                int    fileKeyIndex    = newFileFullPath.IndexOf(newLocalSyncDir);
                fileKey = newFileFullPath.Substring(fileKeyIndex + newLocalSyncDir.Length);
                if (fileKey.StartsWith("/"))
                {
                    fileKey = fileKey.Substring(1);
                }
            }

            //add prefix
            fileKey = this.syncSetting.SyncPrefix + fileKey;

            //set upload params
            Qiniu.Common.Config.PUT_THRESHOLD = this.syncSetting.ChunkUploadThreshold;
            Qiniu.Common.Config.CHUNK_SIZE    = this.syncSetting.DefaultChunkSize;

            string myDocPath  = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            string recordPath = System.IO.Path.Combine(myDocPath, "qsunsync", "resume");

            if (!Directory.Exists(recordPath))
            {
                Directory.CreateDirectory(recordPath);
            }

            bool overwriteUpload = false;
            Mac  mac             = new Mac(SystemConfig.ACCESS_KEY, SystemConfig.SECRET_KEY);

            //current file info
            FileInfo fileInfo         = new FileInfo(fileFullPath);
            long     fileLength       = fileInfo.Length;
            string   fileLastModified = fileInfo.LastWriteTimeUtc.ToFileTime().ToString();
            //support resume upload
            string recorderKey = string.Format("{0}:{1}:{2}:{3}:{4}", this.syncSetting.SyncLocalDir,
                                               this.syncSetting.SyncTargetBucket, fileKey, fileFullPath, fileLastModified);

            recorderKey = Tools.md5Hash(recorderKey);

            if (syncSetting.CheckRemoteDuplicate)
            {
                //check remotely
                BucketManager bucketManager = new BucketManager(mac);
                StatResult    statResult    = bucketManager.stat(this.syncSetting.SyncTargetBucket, fileKey);

                if (!string.IsNullOrEmpty(statResult.Hash))
                {
                    //file exists in bucket
                    string localHash = "";
                    //cached file info
                    try
                    {
                        CachedHash cachedHash = CachedHash.GetCachedHashByLocalPath(fileFullPath, localHashDB);
                        string     cachedEtag = cachedHash.Etag;
                        string     cachedLmd  = cachedHash.LastModified;
                        if (!string.IsNullOrEmpty(cachedEtag) && !string.IsNullOrEmpty(cachedLmd))
                        {
                            if (cachedLmd.Equals(fileLastModified))
                            {
                                //file not modified
                                localHash = cachedEtag;
                            }
                            else
                            {
                                //file modified, calc the hash and update db
                                string newEtag = QETag.hash(fileFullPath);
                                localHash = newEtag;
                                try
                                {
                                    CachedHash.UpdateCachedHash(fileFullPath, newEtag, fileLastModified, localHashDB);
                                }
                                catch (Exception ex)
                                {
                                    Log.Error(string.Format("update local hash failed {0}", ex.Message));
                                }
                            }
                        }
                        else
                        {
                            //no record, calc hash and insert into db
                            string newEtag = QETag.hash(fileFullPath);
                            localHash = newEtag;
                            try
                            {
                                CachedHash.InsertCachedHash(fileFullPath, newEtag, fileLastModified, localHashDB);
                            }
                            catch (Exception ex)
                            {
                                Log.Error(string.Format("insert local hash failed {0}", ex.Message));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(string.Format("get hash from local db failed {0}", ex.Message));
                        localHash = QETag.hash(fileFullPath);
                    }

                    if (localHash.Equals(statResult.Hash))
                    {
                        //same file, no need to upload
                        this.syncProgressPage.addFileExistsLog(string.Format("{0}\t{1}\t{2}", this.syncSetting.SyncTargetBucket,
                                                                             fileFullPath, fileKey));
                        this.syncProgressPage.updateUploadLog("空间已存在,跳过文件 " + fileFullPath);
                        this.syncProgressPage.updateTotalUploadProgress();

                        //compatible, insert or update sync log for file
                        try
                        {
                            SyncLog.InsertOrUpdateSyncLog(fileKey, fileFullPath, fileLastModified, this.syncLogDB);
                        }
                        catch (Exception ex)
                        {
                            Log.Error(string.Format("insert ot update sync log error {0}", ex.Message));
                        }
                        this.doneEvent.Set();
                        return;
                    }
                    else
                    {
                        if (this.syncSetting.OverwriteFile)
                        {
                            overwriteUpload = true;
                            this.syncProgressPage.updateUploadLog("空间已存在,将覆盖 " + fileFullPath);
                        }
                        else
                        {
                            this.syncProgressPage.updateUploadLog("空间已存在,不覆盖 " + fileFullPath);
                            this.syncProgressPage.addFileNotOverwriteLog(string.Format("{0}\t{1}\t{2}", this.syncSetting.SyncTargetBucket,
                                                                                       fileFullPath, fileKey));
                            this.syncProgressPage.updateTotalUploadProgress();
                            this.doneEvent.Set();
                            return;
                        }
                    }
                }
            }
            else
            {
                //check locally
                try
                {
                    SyncLog syncLog = SyncLog.GetSyncLogByKey(fileKey, this.syncLogDB);
                    if (!string.IsNullOrEmpty(syncLog.Key))
                    {
                        //has sync log and check whether it changes
                        if (syncLog.LocalPath.Equals(fileFullPath) && syncLog.LastModified.Equals(fileLastModified))
                        {
                            this.syncProgressPage.addFileExistsLog(string.Format("{0}\t{1}\t{2}", this.syncSetting.SyncTargetBucket,
                                                                                 fileFullPath, fileKey));
                            this.syncProgressPage.updateUploadLog("本地检查已同步,跳过" + fileFullPath);
                            this.syncProgressPage.updateTotalUploadProgress();
                            this.doneEvent.Set();
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(string.Format("get sync log failed {0}", ex.Message));
                }

                if (this.syncSetting.OverwriteFile)
                {
                    overwriteUpload = true;
                }
            }

            //if file not exists or need to overwrite
            this.syncProgressPage.updateUploadLog("准备上传文件 " + fileFullPath);
            UploadManager uploadManger = new UploadManager(new Qiniu.Storage.Persistent.ResumeRecorder(recordPath),
                                                           new Qiniu.Storage.Persistent.KeyGenerator(delegate() { return(recorderKey); }));
            PutPolicy putPolicy = new PutPolicy();

            if (overwriteUpload)
            {
                putPolicy.Scope = this.syncSetting.SyncTargetBucket + ":" + fileKey;
            }
            else
            {
                putPolicy.Scope = this.syncSetting.SyncTargetBucket;
            }
            putPolicy.SetExpires(24 * 30 * 3600);
            string uptoken = Auth.createUploadToken(putPolicy, mac);

            this.syncProgressPage.updateUploadLog("开始上传文件 " + fileFullPath);
            uploadManger.uploadFile(fileFullPath, fileKey, uptoken, new UploadOptions(null, null, false,
                                                                                      new UpProgressHandler(delegate(string key, double percent)
            {
                this.syncProgressPage.updateSingleFileProgress(taskId, fileFullPath, fileKey, fileLength, percent);
            }), new UpCancellationSignal(delegate()
            {
                return(this.syncProgressPage.checkCancelSignal());
            }))
                                    , new UpCompletionHandler(delegate(string key, ResponseInfo respInfo, string response)
            {
                if (respInfo.StatusCode != 200)
                {
                    this.syncProgressPage.updateUploadLog("上传失败 " + fileFullPath + "," + respInfo.Error);
                    this.syncProgressPage.addFileUploadErrorLog(string.Format("{0}\t{1}\t{2}\t{3}", this.syncSetting.SyncTargetBucket,
                                                                              fileFullPath, fileKey, respInfo.Error + "" + response));

                    //file exists error
                    if (respInfo.StatusCode == 614)
                    {
                        this.syncProgressPage.updateUploadLog("空间已存在,未覆盖 " + fileFullPath);
                        this.syncProgressPage.addFileNotOverwriteLog(string.Format("{0}\t{1}\t{2}", this.syncSetting.SyncTargetBucket,
                                                                                   fileFullPath, fileKey));
                    }
                }
                else
                {
                    //insert or update sync log for file
                    try
                    {
                        SyncLog.InsertOrUpdateSyncLog(fileKey, fileFullPath, fileLastModified, this.syncLogDB);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(string.Format("insert ot update sync log error {0}", ex.Message));
                    }

                    //write new file hash to local db
                    if (!overwriteUpload)
                    {
                        PutRet putRet   = JsonConvert.DeserializeObject <PutRet>(response);
                        string fileHash = putRet.Hash;
                        if (this.localHashDB != null)
                        {
                            try
                            {
                                CachedHash.InsertOrUpdateCachedHash(fileFullPath, fileHash, fileLastModified, this.localHashDB);
                            }
                            catch (Exception ex)
                            {
                                Log.Error(string.Format("insert or update cached hash error {0}", ex.Message));
                            }
                        }
                        Log.Debug(string.Format("insert or update qiniu hash to local: '{0}' => '{1}'", fileFullPath, fileHash));
                    }

                    //update
                    if (overwriteUpload)
                    {
                        this.syncProgressPage.addFileOverwriteLog(string.Format("{0}\t{1}\t{2}", this.syncSetting.SyncTargetBucket,
                                                                                fileFullPath, fileKey));
                    }
                    this.syncProgressPage.updateUploadLog("上传成功 " + fileFullPath);
                    this.syncProgressPage.addFileUploadSuccessLog(string.Format("{0}\t{1}\t{2}", this.syncSetting.SyncTargetBucket,
                                                                                fileFullPath, fileKey));
                    this.syncProgressPage.updateTotalUploadProgress();
                }

                this.doneEvent.Set();
            }));
        }