Esempio n. 1
0
File: Get.cs Progetto: snzen/Files
        public int Run(RunArgs ra)
        {
            bool interactive = !ra.InArgs.ContainsKey("-ni");
            var  baseUrl     = string.Empty;
            var  linksFile   = string.Empty;
            var  reqPerSec   = 5.0;
            var  fromIdx     = 0;
            var  toIdx       = -1;
            var  url         = string.Empty;

            ra.State.DestinationDir = ra.RootDir.FullName;

            if (interactive)
            {
                Utils.ReadString("destination dir: ", ref ra.State.DestinationDir);
                Utils.ReadString("url: ", ref url);

                if (string.IsNullOrWhiteSpace(url))
                {
                    Utils.ReadString("base url: ", ref baseUrl);
                    Utils.ReadString("links file: ", ref linksFile, true);
                    Utils.ReadDouble("req/sec: ", ref reqPerSec);
                    Utils.ReadInt("from row: ", ref fromIdx);
                    Utils.ReadInt("to row: ", ref toIdx);
                }
            }
            else
            {
                if (ra.InArgs.ContainsKey("-f"))
                {
                    linksFile = ra.InArgs.GetFirstValue("-f");
                }
                if (ra.InArgs.ContainsKey("-base"))
                {
                    baseUrl = ra.InArgs.GetFirstValue("-base");
                }
                if (ra.InArgs.ContainsKey("-url"))
                {
                    url = ra.InArgs.GetFirstValue("-url");
                }
                if (ra.InArgs.ContainsKey("-dest"))
                {
                    ra.State.DestinationDir = ra.InArgs.GetFirstValue("-dest");
                }
                if (ra.InArgs.ContainsKey("-rps"))
                {
                    reqPerSec = double.Parse(ra.InArgs.GetFirstValue("-rps"));
                }
                if (ra.InArgs.ContainsKey("-from"))
                {
                    fromIdx = int.Parse(ra.InArgs.GetFirstValue("-from"));
                }
                if (ra.InArgs.ContainsKey("-to"))
                {
                    toIdx = int.Parse(ra.InArgs.GetFirstValue("-to"));
                }
            }

            string[] links = null;

            if (!string.IsNullOrWhiteSpace(url))
            {
                links = new string[] { url }
            }
            ;
            else
            {
                links = File.ReadAllLines(linksFile);
            }
            if (toIdx < 0)
            {
                toIdx = links.Length;
            }

            if (fromIdx > 0 && fromIdx > links.Length)
            {
                throw new ArgumentOutOfRangeException("from");
            }
            if (toIdx > 0 && (toIdx > links.Length || toIdx <= fromIdx))
            {
                throw new ArgumentOutOfRangeException("to");
            }

            links = links.Skip(fromIdx).Take(toIdx - fromIdx).ToArray();

            var LINKS_COUNT = links.Length;
            var c           = 0;
            var counter     = new CountdownEvent(LINKS_COUNT);
            var startTime   = DateTime.Now;


            if (links != null && LINKS_COUNT > 0)
            {
                for (int i = 0; i < LINKS_COUNT; i++)
                {
                    var rps = i / DateTime.Now.Subtract(startTime).TotalSeconds;

                    while (rps > reqPerSec)
                    {
                        Thread.Sleep(100);
                        rps = i / DateTime.Now.Subtract(startTime).TotalSeconds;
                    }

                    new Task(async(o) =>
                    {
                        var idx = (int)o;
                        Uri uri = null;
                        var fn  = string.Empty;

                        try
                        {
                            using (var webClient = new HttpClient())
                            {
                                var link = links[idx];

                                if (!string.IsNullOrEmpty(baseUrl))
                                {
                                    uri = new Uri(string.Format("{0}/{1}", baseUrl, link));
                                    fn  = Path.Combine(ra.State.DestinationDir, link);
                                }
                                else
                                {
                                    uri = new Uri(link);
                                    fn  = Path.Combine(ra.State.DestinationDir, uri.Segments[uri.Segments.Length - 1]);
                                }

                                var bytes = await webClient.GetByteArrayAsync(uri);
                                using (var fs = new FileStream(
                                           fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, bytes.Length, true))
                                    await fs.WriteAsync(bytes, 0, bytes.Length);
                                string.Format("{0, 6}/{1}| {2, 6}|K {3}",
                                              Interlocked.Increment(ref c), LINKS_COUNT, bytes.Length / 1000, fn).PrintInfo(true);
                            }
                        }
                        catch (Exception ex)
                        {
                            $"@ link {links[idx]}".PrintSysError(true);
                            ex.Message.PrintSysError(true);
                        }
                        finally
                        {
                            counter.Signal();
                        }
                    }, i).Start();
                }
            }

            counter.Wait();
            var dur = DateTime.Now.Subtract(startTime);

            $"{Environment.NewLine}Done [{dur.Hours}h {dur.Minutes}m {dur.Seconds}s].".PrintInfo(true);

            return(0);
        }