Пример #1
0
 public async Task <bool> Login(CancellationToken ct = default(CancellationToken))
 {
     Config.Log.LogOut("\t[Login]");
     if (string.IsNullOrEmpty(Config.refresh_token))
     {
         Thread t = new Thread(new ThreadStart(() =>
         {
             Authkey = new FormLogin().Login(ct);
         }));
         t.SetApartmentState(System.Threading.ApartmentState.STA);
         t.IsBackground = true;
         t.Start();
         while (t.IsAlive)
         {
             await Task.Delay(1000).ConfigureAwait(false);
         }
         if (Authkey != null && !string.IsNullOrEmpty(Authkey.access_token))
         {
             key_timer = DateTime.Now;
             DriveData.RemoveCache();
             return(true);
         }
         return(false);
     }
     else
     {
         return(await Refresh(ct).ConfigureAwait(false));
     }
 }
Пример #2
0
        static FileMetadata_Info[] FindItems(string[] path_str, bool recursive = false, FileMetadata_Info root = null)
        {
            List <FileMetadata_Info> ret = new List <FileMetadata_Info>();

            if (root == null)
            {
                root = DriveData.AmazonDriveTree[DriveData.AmazonDriveRootID].info;
            }
            if (!(path_str?.Length > 0))
            {
                ret.Add(root);
                return(ret.ToArray());
            }
            while (path_str.Length > 0 && string.IsNullOrEmpty(path_str.First()))
            {
                path_str = path_str.Skip(1).ToArray();
            }
            if (path_str.Length == 0)
            {
                ret.Add(root);
                return(ret.ToArray());
            }

            var children = DriveData.AmazonDriveTree[root.id].children.Select(x => x.Value);

            foreach (var c in children)
            {
                if (c.DisplayName == path_str[0]
                    ||
                    ((path_str[0].Contains('*') || path_str[0].Contains('?')) &&
                     Regex.IsMatch(c.DisplayName, Regex.Escape(path_str[0]).Replace("\\*", ".*").Replace("\\?", "."))))
                {
                    if (c.info.kind == "FOLDER")
                    {
                        ret.AddRange(FindItems((recursive && path_str[0] == "*") ? path_str : path_str.Skip(1).ToArray(), recursive, c.info));
                    }
                    else
                    {
                        if (path_str[0] == c.DisplayName
                            ||
                            (((path_str[0].Contains('*') || path_str[0].Contains('?')) &&
                              Regex.IsMatch(c.DisplayName, Regex.Escape(path_str[0]).Replace("\\*", ".*").Replace("\\?", ".")))))
                        {
                            ret.Add(c.info);
                        }
                    }
                }
            }
            if (recursive)
            {
                ret.Sort((x, y) => (DriveData.GetFullPathfromId(x.id)).CompareTo(DriveData.GetFullPathfromId(y.id)));
                return(ret.ToArray());
            }
            else
            {
                ret.Sort((x, y) => x.name.CompareTo(y.name));
                return(ret.ToArray());
            }
        }
Пример #3
0
 private void listBox_remote_Format(object sender, ListControlConvertEventArgs e)
 {
     e.Value = DriveData.GetFullPathfromId((e.ListItem as FileMetadata_Info).id);
 }
Пример #4
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (SelectedRemoteFiles == null)
            {
                return;
            }

            List <MatchItem> RemoteOnly     = new List <MatchItem>();
            List <MatchItem> LocalOnly      = new List <MatchItem>();
            List <MatchItem> BothAndMatch   = new List <MatchItem>();
            List <MatchItem> BothAndUnmatch = new List <MatchItem>();
            Dictionary <string, LocalItemInfo[]>  LocalDup  = new Dictionary <string, LocalItemInfo[]>();
            Dictionary <string, RemoteItemInfo[]> RemoteDup = new Dictionary <string, RemoteItemInfo[]>();

            var  synchronizationContext = SynchronizationContext.Current;
            bool TreeFlag     = radioButton_Tree.Checked;
            bool FilenameFlag = radioButton_filename.Checked;
            bool MD5Flag      = radioButton_MD5.Checked;

            var job = JobControler.CreateNewJob(JobControler.JobClass.Normal);

            job.DisplayName = "Match";
            job.ProgressStr = "wait for run";
            runningJob      = job;
            bool done = false;

            JobControler.Run(job, (j) =>
            {
                job.ProgressStr = "running...";
                job.Progress    = -1;

                synchronizationContext.Post((o) =>
                {
                    button_start.Enabled = false;
                }, null);

                var remote         = SelectedRemoteFiles.Select(x => new RemoteItemInfo(x, DriveData.GetFullPathfromId(x.id), null)).ToArray();
                var remotebasepath = GetBasePath(remote.Select(x => x.path));

                if (TreeFlag)
                {
                    remote = remote.Select(x => new RemoteItemInfo(x.info, x.path, x.path.Substring(remotebasepath.Length))).ToArray();
                }
                if (FilenameFlag)
                {
                    remote = remote.Select(x => new RemoteItemInfo(x.info, x.path, DriveData.AmazonDriveTree[x.info.id].DisplayName)).ToArray();
                }
                if (MD5Flag)
                {
                    remote = remote.Select(x => new RemoteItemInfo(x.info, x.path, x.info.contentProperties?.md5)).ToArray();
                }

                var localpath     = listBox_local.Items.Cast <string>();
                var localbasepath = GetBasePath(localpath);
                var len           = localpath.Count();
                int i             = 0;
                foreach (var ritem in remote.GroupBy(x => x.name).Where(g => g.Count() > 1))
                {
                    RemoteDup[ritem.Key] = ritem.ToArray();
                }
                var local = ((radioButton_MD5.Checked) ?
                             (localpath.Select(x =>
                {
                    byte[] md5 = null;
                    ++i;
                    synchronizationContext.Post((o) =>
                    {
                        if (runningJob?.ct.IsCancellationRequested ?? true)
                        {
                            return;
                        }
                        label_info.Text = o as string;
                    }, string.Format("{0}/{1} Check file MD5...{2}", i, len, x));
                    using (var md5calc = new System.Security.Cryptography.MD5CryptoServiceProvider())
                        using (var hfile = File.Open(x, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            md5 = md5calc.ComputeHash(hfile);
                            var MD5 = BitConverter.ToString(md5).ToLower().Replace("-", "");
                            return(new LocalItemInfo(x, MD5, hfile.Length, MD5));
                        }
                })) :
                             (radioButton_Tree.Checked) ?
                             localpath.Select(x =>
                {
                    if (checkBox_MD5.Checked)
                    {
                        byte[] md5 = null;
                        ++i;
                        synchronizationContext.Post((o) =>
                        {
                            if (runningJob?.ct.IsCancellationRequested ?? true)
                            {
                                return;
                            }
                            label_info.Text = o as string;
                        }, string.Format("{0}/{1} Check file MD5...{2}", i, len, x));
                        using (var md5calc = new System.Security.Cryptography.MD5CryptoServiceProvider())
                            using (var hfile = File.Open(x, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                md5 = md5calc.ComputeHash(hfile);
                                var MD5 = BitConverter.ToString(md5).ToLower().Replace("-", "");
                                return(new LocalItemInfo(x, x.Substring(localbasepath.Length).Replace('\\', '/'), hfile.Length, MD5));
                            }
                    }
                    else
                    {
                        ++i;
                        synchronizationContext.Post((o) =>
                        {
                            if (runningJob?.ct.IsCancellationRequested ?? true)
                            {
                                return;
                            }
                            label_info.Text = o as string;
                        }, string.Format("{0}/{1} Check file ...{2}", i, len, x));
                        return(new LocalItemInfo(x, x.Substring(localbasepath.Length).Replace('\\', '/'), new FileInfo(x).Length, null));
                    }
                }) :
                             localpath.Select(x =>
                {
                    if (checkBox_MD5.Checked)
                    {
                        byte[] md5 = null;
                        ++i;
                        synchronizationContext.Post((o) =>
                        {
                            if (runningJob?.ct.IsCancellationRequested ?? true)
                            {
                                return;
                            }
                            label_info.Text = o as string;
                        }, string.Format("{0}/{1} Check file MD5...{2}", i, len, x));
                        using (var md5calc = new System.Security.Cryptography.MD5CryptoServiceProvider())
                            using (var hfile = File.Open(x, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                md5 = md5calc.ComputeHash(hfile);
                                var MD5 = BitConverter.ToString(md5).ToLower().Replace("-", "");
                                return(new LocalItemInfo(x, Path.GetFileName(x), hfile.Length, MD5));
                            }
                    }
                    else
                    {
                        ++i;
                        synchronizationContext.Post((o) =>
                        {
                            if (runningJob?.ct.IsCancellationRequested ?? true)
                            {
                                return;
                            }
                            label_info.Text = o as string;
                        }, string.Format("{0}/{1} Check file ...{2}", i, len, x));
                        return(new LocalItemInfo(x, Path.GetFileName(x), new FileInfo(x).Length, null));
                    }
                }))
                            .GroupBy(x => x.name).ToArray();

                i = 0;
                foreach (var litem in local)
                {
                    job.ct.ThrowIfCancellationRequested();
                    var matchitem = remote.Where(x => x.name == litem.FirstOrDefault()?.name).ToArray();

                    if (litem.Count() > 1)
                    {
                        LocalDup[litem.Key] = litem.ToArray();
                    }

                    if (matchitem.Length > 0)
                    {
                        List <RemoteItemInfo> RemoteMatched = new List <RemoteItemInfo>();
                        List <LocalItemInfo> LocalUnMatched = new List <LocalItemInfo>();
                        // match test
                        foreach (var item in litem)
                        {
                            ++i;
                            synchronizationContext.Post((o) =>
                            {
                                if (runningJob?.ct.IsCancellationRequested ?? true)
                                {
                                    return;
                                }
                                label_info.Text = o as string;
                            }, string.Format("{0}/{1} {2}", i, len, item.path));

                            List <RemoteItemInfo> Matched = new List <RemoteItemInfo>();
                            foreach (var ritem in matchitem)
                            {
                                if (item.size == ritem.info.contentProperties?.size)
                                {
                                    if (item.MD5 == null || item.MD5 == ritem.info.contentProperties?.md5)
                                    {
                                        Matched.Add(ritem);
                                    }
                                }
                            }

                            if (Matched.Count() == 0)
                            {
                                LocalUnMatched.Add(item);
                            }

                            BothAndMatch.AddRange(Matched.Select(x => new MatchItem(item, x)));
                            RemoteMatched.AddRange(Matched);
                        }

                        var RemoteUnMatched = matchitem.Except(RemoteMatched);
                        if (RemoteUnMatched.Count() < LocalUnMatched.Count())
                        {
                            BothAndUnmatch.AddRange(RemoteUnMatched.Concat(RemoteMatched).Zip(LocalUnMatched, (r, l) => new MatchItem(l, r)));
                        }
                        else if (RemoteUnMatched.Count() > LocalUnMatched.Count())
                        {
                            BothAndUnmatch.AddRange(LocalUnMatched.Concat(litem).Zip(RemoteUnMatched, (l, r) => new MatchItem(l, r)));
                        }
                        else
                        {
                            if (RemoteUnMatched.Count() > 0)
                            {
                                BothAndUnmatch.AddRange(LocalUnMatched.Zip(RemoteUnMatched, (l, r) => new MatchItem(l, r)));
                            }
                        }
                    }
                    else
                    {
                        //nomatch
                        foreach (var item in litem)
                        {
                            ++i;
                            synchronizationContext.Post((o) =>
                            {
                                if (runningJob?.ct.IsCancellationRequested ?? true)
                                {
                                    return;
                                }
                                label_info.Text = o as string;
                            }, string.Format("{0}/{1} {2}", i, len, item.path));
                            LocalOnly.Add(new MatchItem(item, null));
                        }
                    }
                }
                RemoteOnly.AddRange(remote.Select(x => x.info)
                                    .Except(BothAndMatch.Select(x => x.remote.info))
                                    .Except(BothAndUnmatch.Select(x => x.remote.info))
                                    .Select(x => remote.Where(y => y.info == x).FirstOrDefault())
                                    .Select(x => new MatchItem(null, x)));
                done            = true;
                job.Progress    = 1;
                job.ProgressStr = "done.";
            });
            var afterjob = JobControler.CreateNewJob(JobControler.JobClass.Clean, depends: job);

            afterjob.DisplayName = "clean up";
            afterjob.DoAlways    = true;
            JobControler.Run(afterjob, (j) =>
            {
                afterjob.ProgressStr = "done.";
                afterjob.Progress    = 1;
                runningJob           = null;
                synchronizationContext.Post((o) =>
                {
                    label_info.Text      = "";
                    button_start.Enabled = true;
                    if (done)
                    {
                        var result        = new FormMatchResult();
                        result.RemoteOnly = RemoteOnly;
                        result.LocalOnly  = LocalOnly;
                        result.Unmatch    = BothAndUnmatch;
                        result.Match      = BothAndMatch;
                        result.RemoteDup  = RemoteDup;
                        result.LocalDup   = LocalDup;
                        result.Show();
                    }
                }, null);
            });
        }
Пример #5
0
        static int Download(string[] targetArgs, string[] paramArgs, bool index_mode = false)
        {
            var masterjob = JobControler.CreateNewJob(JobControler.JobClass.ControlMaster);

            masterjob.DisplayName = "Download";
            var ct = masterjob.ct;

            JobControler.Run(masterjob, (j) =>
            {
                string remotepath          = null;
                string localpath           = null;
                string indexpath           = null;
                string ignorespath         = null;
                FileMetadata_Info[] target = null;

                if (index_mode)
                {
                    if (targetArgs.Length > 4)
                    {
                        ignorespath = targetArgs[4];
                    }
                    if (targetArgs.Length > 3)
                    {
                        localpath = targetArgs[3];
                    }
                    if (targetArgs.Length > 2)
                    {
                        remotepath = targetArgs[2];
                        remotepath = remotepath.Replace('\\', '/');
                    }
                    if (targetArgs.Length > 1)
                    {
                        indexpath = targetArgs[1];
                    }
                }
                else
                {
                    if (targetArgs.Length > 3)
                    {
                        ignorespath = targetArgs[3];
                    }
                    if (targetArgs.Length > 2)
                    {
                        localpath = targetArgs[2];
                    }
                    if (targetArgs.Length > 1)
                    {
                        remotepath = targetArgs[1];
                        remotepath = remotepath.Replace('\\', '/');
                    }
                }

                if (string.IsNullOrEmpty(remotepath))
                {
                    masterjob.Result = 0;
                    return;
                }

                bool autodecrypt = true;
                foreach (var p in paramArgs)
                {
                    switch (p)
                    {
                    case "nodecrypt":
                        Console.Error.WriteLine("(--nodecrypt: disable auto decrypt)");
                        autodecrypt = false;
                        break;
                    }
                }
                AmazonDriveControl.autodecrypt = autodecrypt;
                AmazonDriveControl.indexpath   = indexpath;

                string itembasepath;
                try
                {
                    var loginjob = Login();
                    var initjob  = AmazonDriveControl.InitAlltree(loginjob);
                    initjob.Wait(ct: ct);
                    target = FindItems(remotepath?.Split('/'));

                    var target2  = target.SelectMany(x => DriveData.GetAllChildrenfromId(x.id));
                    itembasepath = FormMatch.GetBasePath(target.Select(x => DriveData.GetFullPathfromId(x.id)).Distinct());
                    target       = target2.Where(x => x.kind == "FILE").ToArray();

                    if (target.Length < 1)
                    {
                        masterjob.Result = 2;
                        return;
                    }
                }
                catch (OperationCanceledException)
                {
                    masterjob.Result = -1;
                    return;
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("error: " + ex.ToString());
                    masterjob.Result = 1;
                    return;
                }

                if (ignorespath != null)
                {
                    var targetdict = new ConcurrentDictionary <string, FileMetadata_Info>();
                    Parallel.ForEach(target, item =>
                    {
                        targetdict[DriveData.GetFullPathfromId(item.id)] = item;
                    });
                    Console.WriteLine("ignore list loading...");
                    using (var file = new FileStream(ignorespath, FileMode.Open))
                        using (var sr = new StreamReader(file))
                        {
                            while (!sr.EndOfStream)
                            {
                                var line = sr.ReadLine().Split('\t');
                                FileMetadata_Info o;
                                if (line.Length > 1)
                                {
                                    if (targetdict.TryGetValue(line[0], out o))
                                    {
                                        if (o.contentProperties?.md5 == line[1])
                                        {
                                            if (targetdict.TryRemove(line[0], out o))
                                            {
                                                Console.WriteLine(line[0]);
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    if (targetdict.TryRemove(line[0], out o))
                                    {
                                        Console.WriteLine(line[0]);
                                    }
                                }
                            }
                        }
                    target = targetdict.Values.ToArray();
                    Console.WriteLine("remain target: " + target.Length);

                    if (target.Length < 1)
                    {
                        masterjob.Result = 2;
                        return;
                    }
                }

                bool SelectFullpath = false;
                if (String.IsNullOrEmpty(localpath))
                {
                    Thread t = new Thread(new ThreadStart(() =>
                    {
                        if (target.Length > 1)
                        {
                            using (var save = new FolderBrowserDialog())
                            {
                                save.Description = "Select Save Folder for Download Items";
                                if (save.ShowDialog() != DialogResult.OK)
                                {
                                    return;
                                }
                                localpath = save.SelectedPath;
                            }
                        }
                        else
                        {
                            using (var save = new SaveFileDialog())
                            {
                                var filename  = DriveData.AmazonDriveTree[target[0].id].DisplayName;
                                save.FileName = filename;
                                if (save.ShowDialog() != DialogResult.OK)
                                {
                                    return;
                                }
                                localpath      = save.FileName;
                                SelectFullpath = true;
                            }
                        }
                    }));
                    t.SetApartmentState(System.Threading.ApartmentState.STA);
                    t.Start();
                    t.Join();
                    if (localpath == null)
                    {
                        masterjob.Result = 0;
                        return;
                    }
                }

                try
                {
                    Console.Error.WriteLine("remote:" + remotepath);
                    Console.Error.WriteLine("local:" + localpath);
                    if (indexpath != null)
                    {
                        Console.Error.WriteLine("index:" + indexpath);
                    }

                    if (target.Length == 1)
                    {
                        var filename = DriveData.AmazonDriveTree[target[0].id].DisplayName;
                        if (!SelectFullpath)
                        {
                            localpath = Path.Combine(localpath, filename);
                        }
                    }
                    if (target.Length > 1 && Path.GetFileName(localpath) != "")
                    {
                        localpath += "\\";
                    }

                    ConsoleJobDisp.Run();

                    var jobs = AmazonDriveControl.downloadItems(target, localpath, masterjob);

                    int errorcount = 0;
                    Task.WaitAll(jobs.Select(x => x.WaitTask(ct: ct)).ToArray());
                    foreach (var j2 in jobs)
                    {
                        if (j2.IsError)
                        {
                            errorcount++;
                        }
                    }
                    masterjob.Result = (errorcount == 0) ? 0 : errorcount + 10;
                }
                catch (OperationCanceledException)
                {
                    masterjob.Result = -1;
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("error: " + ex.ToString());
                    masterjob.Result = 1;
                }
            });
            try
            {
                masterjob.Wait(ct: ct);
            }
            catch (OperationCanceledException)
            {
            }
            Config.IsClosing = true;
            Console.Out.Flush();
            return((masterjob.Result as int?) ?? -1);
        }
Пример #6
0
        static int ListItems(string[] targetArgs, string[] paramArgs)
        {
            var job = JobControler.CreateNewJob(JobControler.JobClass.ControlMaster);

            job.DisplayName = "ListItem";
            JobControler.Run(job, (j) =>
            {
                string remotepath          = null;
                FileMetadata_Info[] target = null;

                if (targetArgs.Length > 1)
                {
                    remotepath = targetArgs[1];
                    remotepath = remotepath.Replace('\\', '/');
                }

                bool recursive = false;
                bool showmd5   = false;
                bool nodecrypt = false;
                foreach (var p in paramArgs)
                {
                    switch (p)
                    {
                    case "recursive":
                        Console.Error.WriteLine("(--recursive: recursive mode)");
                        recursive = true;
                        break;

                    case "md5":
                        Console.Error.WriteLine("(--md5: show MD5 hash)");
                        showmd5 = true;
                        break;

                    case "nodecrypt":
                        Console.Error.WriteLine("(--nodecrypt: disable auto decrypt)");
                        nodecrypt = true;
                        break;
                    }
                }

                try
                {
                    var loginjob = Login();
                    var initjob  = AmazonDriveControl.InitAlltree(loginjob);
                    initjob.Wait(ct: job.ct);
                    target = FindItems(remotepath?.Split('/'), recursive: recursive);

                    if (target.Length < 1)
                    {
                        job.Result = 2;
                        return;
                    }

                    Console.Error.WriteLine("Found : " + target.Length);
                    foreach (var item in target)
                    {
                        string detail = "";
                        if (showmd5)
                        {
                            detail = "\t" + item.contentProperties?.md5;
                        }

                        if (recursive)
                        {
                            Console.WriteLine(DriveData.GetFullPathfromId(item.id, nodecrypt) + detail);
                        }
                        else
                        {
                            Console.WriteLine(((nodecrypt) ? item.name : DriveData.AmazonDriveTree[item.id].DisplayName) + ((item.kind == "FOLDER") ? "/" : "") + detail);
                        }
                    }

                    job.Result = 0;
                }
                catch (OperationCanceledException)
                {
                    job.Result = -1;
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("error: " + ex.ToString());
                    job.Result = 1;
                }
            });
            try
            {
                job.Wait(ct: job.ct);
            }
            catch (OperationCanceledException)
            {
            }
            Config.IsClosing = true;
            Console.Out.Flush();
            return((job.Result as int?) ?? -1);
        }
Пример #7
0
        private void ProcessCryption()
        {
            if (IsEncrypted == CryptMethods.Unknown)
            {
                if (info?.name?.StartsWith(Config.CarotDAV_CryptNameHeader) ?? false)
                {
                    IsEncrypted = CryptMethods.Method2_CBC_CarotDAV;
                }
                else if (Regex.IsMatch(info?.name ?? "", ".*?\\.[a-z0-9]{8}\\.enc$"))
                {
                    IsEncrypted  = CryptMethods.Method1_CTR;
                    _DisplayName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(info.name));
                    return;
                }
                else if (Regex.IsMatch(info?.name ?? "", "^[\u2800-\u28ff]+$"))
                {
                    IsEncrypted = CryptMethods.Method1_CTR;
                    var decodename = DriveData.DecryptFilename(info);
                    if (decodename != null)
                    {
                        IsEncrypted  = CryptMethods.Method1_CTR;
                        _DisplayName = Path.GetFileNameWithoutExtension(decodename);
                        return;
                    }
                    _DisplayName = info?.name;
                    CryptError   = true;
                }
                else
                {
                    IsEncrypted = CryptMethods.Method0_Plain;
                }
            }
            switch (IsEncrypted)
            {
            case CryptMethods.Method0_Plain:
                _DisplayName = info?.name;
                break;

            case CryptMethods.Method1_CTR:
                if (Regex.IsMatch(info?.name ?? "", ".*?\\.[a-z0-9]{8}\\.enc$"))
                {
                    _DisplayName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(info.name));
                    CryptError   = false;
                }
                else if (Regex.IsMatch(info?.name ?? "", "^[\u2800-\u28ff]+$"))
                {
                    var decodename = DriveData.DecryptFilename(info);
                    if (decodename != null)
                    {
                        _DisplayName = Path.GetFileNameWithoutExtension(decodename);
                        CryptError   = false;
                    }
                    else
                    {
                        _DisplayName = info?.name;
                        CryptError   = true;
                    }
                }
                else
                {
                    IsEncrypted  = CryptMethods.Method0_Plain;
                    _DisplayName = info?.name;
                }
                break;

            case CryptMethods.Method2_CBC_CarotDAV:
            {
                var decodename = CryptCarotDAV.DecryptFilename(info?.name);
                if (decodename != null)
                {
                    _DisplayName = decodename;
                    CryptError   = false;
                }
                else
                {
                    _DisplayName = info?.name;
                    CryptError   = true;
                }
            }
            break;
            }
        }
Пример #8
0
        private void button_Start_Click(object sender, EventArgs e)
        {
            if (SelectedRemoteFiles == null)
            {
                return;
            }

            button_Start.Enabled = false;
            var synchronizationContext = SynchronizationContext.Current;

            var masterjob = JobControler.CreateNewJob(JobControler.JobClass.Normal);

            masterjob.DisplayName = "Download test";
            masterjob.ProgressStr = "wait for download";
            runningjob            = masterjob;
            var joblist = new ConcurrentBag <JobControler.Job>();

            Parallel.ForEach(SelectedRemoteFiles, (item) =>
            {
                var job         = JobControler.CreateNewJob(JobControler.JobClass.Download, depends: masterjob);
                job.WeekDepend  = true;
                job.DisplayName = DriveData.GetFullPathfromId(item.id);
                job.ProgressStr = "Wait for download";
                joblist.Add(job);
                var ct = CancellationTokenSource.CreateLinkedTokenSource(masterjob.ct, job.ct).Token;
                JobControler.Run(job, (j) =>
                {
                    synchronizationContext.Post(
                        (o) =>
                    {
                        if (ct.IsCancellationRequested)
                        {
                            return;
                        }
                        var listitem = listView1.Items.Find(item.id, false).FirstOrDefault();
                        listitem.SubItems[1].Text = "download...";
                    }, null);
                    (j as JobControler.Job).ProgressStr = "download...";

                    var retry = 5;
                    while (--retry > 0)
                    {
                        ct.ThrowIfCancellationRequested();
                        try
                        {
                            long length = item.contentProperties.size ?? 0;
                            using (var ret = new AmazonDriveBaseStream(DriveData.Drive, item, autodecrypt: false, parentJob: (j as JobControler.Job)))
                                using (var f = new PositionStream(ret, length))
                                {
                                    f.PosChangeEvent += (src, evnt) =>
                                    {
                                        synchronizationContext.Post(
                                            (o) =>
                                        {
                                            if (ct.IsCancellationRequested)
                                            {
                                                return;
                                            }
                                            var eo       = o as PositionChangeEventArgs;
                                            var listitem = listView1.Items.Find(item.id, false).FirstOrDefault();
                                            listitem.SubItems[1].Text = eo.Log;
                                        }, evnt);
                                        (j as JobControler.Job).ProgressStr = evnt.Log;
                                        (j as JobControler.Job).Progress    = (double)evnt.Position / evnt.Length;
                                    };
                                    f.CopyTo(new NullStream());
                                }
                            synchronizationContext.Post(
                                (o) =>
                            {
                                if (ct.IsCancellationRequested)
                                {
                                    return;
                                }
                                var listitem = listView1.Items.Find(item.id, false).FirstOrDefault();
                                listitem.SubItems[1].Text = "Done";
                            }, null);
                            (j as JobControler.Job).ProgressStr = "Done.";
                            (j as JobControler.Job).Progress    = 1;
                            break;
                        }
                        catch (OperationCanceledException)
                        {
                            throw;
                        }
                        catch (Exception ex)
                        {
                            Config.Log.LogOut("Download : Error " + ex.Message);
                            continue;
                        }
                    }
                    if (retry == 0)
                    {
                        // failed
                        synchronizationContext.Post(
                            (o) =>
                        {
                            if (ct.IsCancellationRequested)
                            {
                                return;
                            }
                            var listitem = listView1.Items.Find(item.id, false).FirstOrDefault();
                            listitem.SubItems[1].Text = "Failed";
                        }, null);
                        (j as JobControler.Job).ProgressStr = "Failed";
                        (j as JobControler.Job).Progress    = double.NaN;
                        (j as JobControler.Job).IsError     = true;
                    }
                });
            });
            JobControler.Run(masterjob, (j) =>
            {
                masterjob.ProgressStr = "running...";
                masterjob.Progress    = -1;
                var ct = (j as JobControler.Job).ct;
                Task.WaitAll(joblist.Select(x => x.WaitTask(ct: ct)).ToArray());
                masterjob.Progress    = 1;
                masterjob.ProgressStr = "done.";
            });
            var afterjob = JobControler.CreateNewJob(JobControler.JobClass.Clean, depends: masterjob);

            afterjob.DisplayName = "clean up";
            afterjob.DoAlways    = true;
            JobControler.Run(afterjob, (j) =>
            {
                afterjob.ProgressStr = "done.";
                afterjob.Progress    = 1;
                runningjob           = null;
                synchronizationContext.Post((o) =>
                {
                    button_Start.Enabled = true;
                }, null);
            });
        }
Пример #9
0
        public async Task <Stream> downloadFile(FileMetadata_Info target, long?from = null, long?to = null, string enckey = null, bool autodecrypt = true, CancellationToken ct = default(CancellationToken))
        {
            string       id        = target.id;
            string       filename  = target.name;
            CryptMethods Encrypted = CryptMethods.Method0_Plain;

            if (enckey != null)
            {
                Encrypted = CryptMethods.Method1_CTR;
            }
            else
            {
                if (filename.StartsWith(Config.CarotDAV_CryptNameHeader))
                {
                    Encrypted = CryptMethods.Method2_CBC_CarotDAV;
                    enckey    = "";
                }
                else if (Regex.IsMatch(filename, ".*?\\.[a-z0-9]{8}\\.enc$"))
                {
                    Encrypted = CryptMethods.Method1_CTR;
                    enckey    = Path.GetFileNameWithoutExtension(filename);
                }
                else if (Regex.IsMatch(filename, "^[\u2800-\u28ff]+$"))
                {
                    enckey = DriveData.DecryptFilename(target);
                    if (enckey != null)
                    {
                        Encrypted = CryptMethods.Method1_CTR;
                    }
                }

                if (enckey == null)
                {
                    Encrypted = CryptMethods.Method0_Plain;
                }
            }
            if (!autodecrypt)
            {
                Encrypted = CryptMethods.Method0_Plain;
            }
            Config.Log.LogOut("\t[downloadFile] " + id);
            string error_str = "";
            var    client    = new HttpClient();

            client.Timeout = TimeSpan.FromDays(1);
            try
            {
                long?fix_from = from, fix_to = to;

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Authkey.access_token);
                if (from != null || to != null)
                {
                    if (Encrypted == CryptMethods.Method2_CBC_CarotDAV)
                    {
                        if (fix_from != null)
                        {
                            // ひとつ前のブロックから要求する
                            fix_from -= CryptCarotDAV.BlockSizeByte;
                            if (fix_from < CryptCarotDAV.BlockSizeByte)
                            {
                                // 先頭ブロックを取得するときはファイルの先頭から
                                fix_from = 0;
                            }
                            else
                            {
                                // ブロックにアライメントを合わせる
                                fix_from -= ((fix_from - 1) % CryptCarotDAV.BlockSizeByte + 1);
                                // 途中のブロックを要求された場合は、ヘッダをスキップ
                                fix_from += CryptCarotDAV.CryptHeaderByte;
                            }
                        }
                        if (fix_to != null)
                        {
                            if (fix_to >= target.OrignalLength)
                            {
                                // 末尾まで読み込むときは、ハッシュチェックのために最後まで読み込む
                                fix_to = null;
                            }
                            else
                            {
                                // オリジナルの位置を、暗号化済みの位置に変更
                                fix_to += CryptCarotDAV.CryptHeaderByte;
                            }
                        }
                        if (fix_from != null || fix_to != null)
                        {
                            client.DefaultRequestHeaders.Range = new RangeHeaderValue(fix_from, fix_to);
                        }
                    }
                    else
                    {
                        client.DefaultRequestHeaders.Range = new RangeHeaderValue(from, to);
                    }
                }
                string url      = Config.contentUrl + "nodes/" + id + "/content?download=false";
                var    response = await client.GetAsync(
                    url,
                    HttpCompletionOption.ResponseHeadersRead,
                    ct).ConfigureAwait(false);

                response.EnsureSuccessStatusCode();
                if (Encrypted == CryptMethods.Method1_CTR)
                {
                    return(new CryptCTR.AES256CTR_CryptStream(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct),
                                                              enckey,
                                                              from ?? 0));
                }
                else if (Encrypted == CryptMethods.Method2_CBC_CarotDAV)
                {
                    return(new CryptCarotDAV.CryptCarotDAV_DecryptStream(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct),
                                                                         from ?? 0,
                                                                         fix_from ?? 0,
                                                                         target.contentProperties?.size ?? -1
                                                                         ));
                }
                else
                {
                    return(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct));
                }
            }
            catch (HttpRequestException ex)
            {
                error_str = ex.Message;
                Config.Log.LogOut("\t[downloadFile] " + error_str);
                throw;
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                error_str = ex.ToString();
                Config.Log.LogOut("\t[downloadFile] " + error_str);
                throw;
            }
            throw new SystemException("fileDownload failed. " + error_str);
        }