Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2022
1,262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.57 KB | None | 0 0
  1. using System.Web;
  2. using System.Xml.Serialization;
  3.  
  4. namespace DataContract
  5. {
  6.     [XmlRoot(ElementName = "post")]
  7.     public class Post
  8.     {
  9.         [XmlElement(ElementName = "image")]
  10.         public string Image { get; set; }
  11.  
  12.         [XmlElement(ElementName = "tags")]
  13.         public string Tags { get; set; }
  14.  
  15.         [XmlElement(ElementName = "file_url")]
  16.         public string File_url { get; set; }
  17.     }
  18.  
  19.     [XmlRoot(ElementName = "posts")]
  20.     public class Posts
  21.     {
  22.         [XmlElement(ElementName = "post")]
  23.         public List<Post>? Post { get; set; }
  24.  
  25.         [XmlAttribute(AttributeName = "limit")]
  26.         public int Limit { get; set; }
  27.  
  28.         [XmlAttribute(AttributeName = "offset")]
  29.         public int Offset { get; set; }
  30.  
  31.         [XmlAttribute(AttributeName = "count")]
  32.         public int Count { get; set; }
  33.     }
  34. }
  35.  
  36. public static class Scheduler
  37. {
  38.     public static void Process<T>(IEnumerable<T> ie, int delay, Func<T, Task<bool>> job)
  39.     {
  40.         const int concurrency = 4;
  41.  
  42.         var count = 0;
  43.         var total = ie.Count();
  44.  
  45.         var mutex = new object();
  46.         void ReportProgress(int current)
  47.         {
  48.             lock (mutex)
  49.             {
  50.                 if (current == count)
  51.                 {
  52.                     var progress = Math.Round((float)current / total * 100, 2);
  53.                     Console.WriteLine($"{current}/{total}: {progress}%");
  54.                 }
  55.             }
  56.         }
  57.  
  58.         Parallel.ForEach(ie, new ParallelOptions() { MaxDegreeOfParallelism = concurrency }, x =>
  59.         {
  60.             var didWork = true;
  61.             try
  62.             {
  63.                 didWork = job(x).GetAwaiter().GetResult();
  64.             }
  65.             catch (Exception _)
  66.             {
  67.                 Console.WriteLine($"Task failed :(");
  68.  
  69.             }
  70.             finally
  71.             {
  72.                 ReportProgress(Interlocked.Increment(ref count));
  73.                 if (didWork) Thread.Sleep(delay);
  74.             }
  75.         });
  76.     }
  77. }
  78.  
  79. public class Entrypoint
  80. {
  81.  
  82.     private static HttpClient _hc = new HttpClient();
  83.     private static XmlSerializer _xml = new XmlSerializer(typeof(DataContract.Posts));
  84.  
  85.     private static string ConstructGelbooruURL(int page, int limit, IEnumerable<string> tags)
  86.     {
  87.         var encodedTags = HttpUtility.UrlEncode(string.Join(" ", tags));
  88.         return $"https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit={limit}&pid={page}&tags={encodedTags}";
  89.     }
  90.  
  91.     private static async Task<DataContract.Posts?> GetPosts(int page, int limit, IEnumerable<string> tags)
  92.     {
  93.         var get = await _hc.GetAsync(ConstructGelbooruURL(page, limit, tags));
  94.         var content = await get.Content.ReadAsStringAsync();
  95.         using (var sr = new StringReader(content))
  96.             return (DataContract.Posts?)_xml.Deserialize(sr);
  97.     }
  98.  
  99.     public static void Main(string[] args)
  100.     {
  101.         const string output_dir = "OUT";
  102.         if (!Directory.Exists(output_dir))
  103.             Directory.CreateDirectory(output_dir);
  104.  
  105.         var tags = new[] { "belko", "paizuri" };
  106.         var mre = new ManualResetEvent(false);
  107.  
  108.         Task.Factory.StartNew(async () =>
  109.         {
  110.             var page = 0;
  111.             var postsPerPage = 20;
  112.             var getTotal = await GetPosts(0, 1, tags);
  113.             var totalPosts = getTotal.Count;
  114.  
  115.  
  116.             var pages = (int)Math.Ceiling((float)totalPosts / postsPerPage);
  117.             for(var i = 0; i < pages; i++)
  118.             {
  119.                 Console.WriteLine($"Fetching page {i + 1}");
  120.                 var posts = await GetPosts(i, postsPerPage, tags);
  121.                 Scheduler.Process(posts.Post, 5000, async post =>
  122.                 {
  123.                     var didWork = false;
  124.                     if (post == null) return false;
  125.                     var tagPath = Path.Combine(output_dir, Path.GetFileNameWithoutExtension(post.Image) + ".txt");
  126.                     if (!File.Exists(tagPath))
  127.                     {
  128.                         File.WriteAllText(tagPath, string.Join(", ", post.Tags.Split(" ")));
  129.                     }
  130.                     var imagePath = Path.Combine(output_dir, post.Image);
  131.                     if (!File.Exists(imagePath))
  132.                     {
  133.                         didWork = true;
  134.                         var data = await _hc.GetByteArrayAsync(post.File_url);
  135.                         File.WriteAllBytes(imagePath, data);
  136.                     }
  137.                     return didWork;
  138.                 });
  139.                 await Task.Delay(5000);
  140.             }
  141.            
  142.             mre.Set();
  143.         });
  144.        
  145.  
  146.         Console.ReadLine();
  147.     }
  148.  
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement