advent_of_ruby 0.3.5 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/data/solutions/github/ZogStriP/2024/01_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/01_2.yml +7 -0
- data/data/solutions/github/ZogStriP/2024/02_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/02_2.yml +9 -0
- data/data/solutions/github/ZogStriP/2024/03_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/03_2.yml +7 -0
- data/data/solutions/github/ZogStriP/2024/04_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/04_2.yml +15 -0
- data/data/solutions/github/ZogStriP/2024/05_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/05_2.yml +16 -0
- data/data/solutions/github/ZogStriP/2024/06_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/06_2.yml +38 -0
- data/data/solutions/github/ZogStriP/2024/07_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/07_2.yml +9 -0
- data/data/solutions/github/ZogStriP/2024/08_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/08_2.yml +27 -0
- data/data/solutions/github/ZogStriP/2024/09_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/09_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/10_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/10_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/11_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/11_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/12_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/12_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/13_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/13_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/14_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/14_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/15_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/15_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/16_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/16_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/17_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/17_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/18_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/18_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/19_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/19_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/20_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/20_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/21_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/21_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/22_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/22_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/23_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/23_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/24_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/24_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2024/25_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/01_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/01_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/02_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/02_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/03_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/03_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/04_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/04_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/05_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/05_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/06_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/06_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/07_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/07_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/08_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/08_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/09_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/09_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/10_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/10_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/11_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/11_2.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/12_1.yml +1 -0
- data/data/solutions/github/ZogStriP/2025/12_2.yml +1 -0
- data/data/solutions/github/ahorner/2025/01_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/01_2.yml +37 -0
- data/data/solutions/github/ahorner/2025/02_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/02_2.yml +41 -0
- data/data/solutions/github/ahorner/2025/03_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/03_2.yml +24 -0
- data/data/solutions/github/ahorner/2025/04_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/04_2.yml +39 -0
- data/data/solutions/github/ahorner/2025/05_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/05_2.yml +48 -0
- data/data/solutions/github/ahorner/2025/06_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/06_2.yml +44 -0
- data/data/solutions/github/ahorner/2025/07_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/07_2.yml +56 -0
- data/data/solutions/github/ahorner/2025/08_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/08_2.yml +59 -0
- data/data/solutions/github/ahorner/2025/09_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/09_2.yml +101 -0
- data/data/solutions/github/ahorner/2025/10_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/10_2.yml +72 -0
- data/data/solutions/github/ahorner/2025/11_1.yml +1 -0
- data/data/solutions/github/ahorner/2025/11_2.yml +45 -0
- data/data/solutions/github/ahorner/2025/12_1.yml +1 -0
- data/data/solutions/github/eregon/2025/01_1.yml +17 -0
- data/data/solutions/github/eregon/2025/01_2.yml +14 -0
- data/data/solutions/github/eregon/2025/02_1.yml +22 -0
- data/data/solutions/github/eregon/2025/02_2.yml +58 -0
- data/data/solutions/github/eregon/2025/03_1.yml +13 -0
- data/data/solutions/github/eregon/2025/03_2.yml +13 -0
- data/data/solutions/github/eregon/2025/04_1.yml +14 -0
- data/data/solutions/github/eregon/2025/04_2.yml +16 -0
- data/data/solutions/github/eregon/2025/05_1.yml +1 -0
- data/data/solutions/github/eregon/2025/05_2.yml +1 -0
- data/data/solutions/github/eregon/2025/06_1.yml +1 -0
- data/data/solutions/github/eregon/2025/06_2.yml +1 -0
- data/data/solutions/github/eregon/2025/07_1.yml +1 -0
- data/data/solutions/github/eregon/2025/07_2.yml +1 -0
- data/data/solutions/github/eregon/2025/08_1.yml +1 -0
- data/data/solutions/github/eregon/2025/08_2.yml +1 -0
- data/data/solutions/github/eregon/2025/09_1.yml +1 -0
- data/data/solutions/github/eregon/2025/09_2.yml +1 -0
- data/data/solutions/github/eregon/2025/10_1.yml +1 -0
- data/data/solutions/github/eregon/2025/10_2.yml +1 -0
- data/data/solutions/github/eregon/2025/11_1.yml +1 -0
- data/data/solutions/github/eregon/2025/11_2.yml +1 -0
- data/data/solutions/github/eregon/2025/12_1.yml +1 -0
- data/data/solutions/github/erikw/2025/01_1.yml +1 -0
- data/data/solutions/github/erikw/2025/01_2.yml +1 -0
- data/data/solutions/github/erikw/2025/02_1.yml +1 -0
- data/data/solutions/github/erikw/2025/02_2.yml +1 -0
- data/data/solutions/github/erikw/2025/03_1.yml +1 -0
- data/data/solutions/github/erikw/2025/03_2.yml +1 -0
- data/data/solutions/github/erikw/2025/04_1.yml +1 -0
- data/data/solutions/github/erikw/2025/04_2.yml +1 -0
- data/data/solutions/github/erikw/2025/05_1.yml +1 -0
- data/data/solutions/github/erikw/2025/05_2.yml +1 -0
- data/data/solutions/github/erikw/2025/06_1.yml +1 -0
- data/data/solutions/github/erikw/2025/06_2.yml +1 -0
- data/data/solutions/github/erikw/2025/07_1.yml +1 -0
- data/data/solutions/github/erikw/2025/07_2.yml +1 -0
- data/data/solutions/github/erikw/2025/08_1.yml +1 -0
- data/data/solutions/github/erikw/2025/08_2.yml +1 -0
- data/data/solutions/github/erikw/2025/09_1.yml +1 -0
- data/data/solutions/github/erikw/2025/09_2.yml +1 -0
- data/data/solutions/github/erikw/2025/10_1.yml +1 -0
- data/data/solutions/github/erikw/2025/10_2.yml +1 -0
- data/data/solutions/github/erikw/2025/11_1.yml +1 -0
- data/data/solutions/github/erikw/2025/11_2.yml +1 -0
- data/data/solutions/github/erikw/2025/12_1.yml +1 -0
- data/data/solutions/github/erikw/2025/12_2.yml +1 -0
- data/data/solutions/github/gchan/2025/01_1.yml +25 -0
- data/data/solutions/github/gchan/2025/01_2.yml +32 -0
- data/data/solutions/github/gchan/2025/02_1.yml +18 -0
- data/data/solutions/github/gchan/2025/02_2.yml +21 -0
- data/data/solutions/github/gchan/2025/03_1.yml +15 -0
- data/data/solutions/github/gchan/2025/03_2.yml +23 -0
- data/data/solutions/github/gchan/2025/04_1.yml +27 -0
- data/data/solutions/github/gchan/2025/04_2.yml +40 -0
- data/data/solutions/github/gchan/2025/05_1.yml +20 -0
- data/data/solutions/github/gchan/2025/05_2.yml +36 -0
- data/data/solutions/github/gchan/2025/06_1.yml +11 -0
- data/data/solutions/github/gchan/2025/06_2.yml +28 -0
- data/data/solutions/github/gchan/2025/07_1.yml +33 -0
- data/data/solutions/github/gchan/2025/07_2.yml +29 -0
- data/data/solutions/github/gchan/2025/08_1.yml +48 -0
- data/data/solutions/github/gchan/2025/08_2.yml +48 -0
- data/data/solutions/github/gchan/2025/09_1.yml +16 -0
- data/data/solutions/github/gchan/2025/09_2.yml +60 -0
- data/data/solutions/github/gchan/2025/10_1.yml +49 -0
- data/data/solutions/github/gchan/2025/10_2.yml +154 -0
- data/data/solutions/github/gchan/2025/11_1.yml +43 -0
- data/data/solutions/github/gchan/2025/11_2.yml +33 -0
- data/data/solutions/github/gchan/2025/12_1.yml +51 -0
- data/data/solutions/reddit/ruby/2017/06.yml +0 -2
- data/data/solutions/reddit/ruby/2020/02.yml +0 -1
- data/data/solutions/reddit/ruby/2024/02.yml +0 -1
- data/data/solutions/reddit/ruby/2025/01.yml +187 -0
- data/data/solutions/reddit/ruby/2025/02.yml +185 -0
- data/data/solutions/reddit/ruby/2025/03.yml +369 -0
- data/data/solutions/reddit/ruby/2025/04.yml +217 -0
- data/data/solutions/reddit/ruby/2025/05.yml +324 -0
- data/data/solutions/reddit/ruby/2025/06.yml +246 -0
- data/data/solutions/reddit/ruby/2025/07.yml +213 -0
- data/data/solutions/reddit/ruby/2025/08.yml +73 -0
- data/data/solutions/reddit/ruby/2025/09.yml +26 -0
- data/data/solutions/reddit/ruby/2025/10.yml +73 -0
- data/data/solutions/reddit/ruby/2025/11.yml +69 -0
- data/data/solutions/reddit/ruby/2025/12.yml +1 -0
- data/lib/arb/arb.rb +0 -5
- data/lib/arb/cli/bootstrap.rb +1 -1
- data/lib/arb/cli/commit.rb +1 -1
- data/lib/arb/cli/progress.rb +4 -8
- data/lib/arb/cli/run.rb +1 -1
- data/lib/arb/cli/shared/git.rb +3 -4
- data/lib/arb/cli/shared/year_day_validator.rb +3 -8
- data/lib/arb/files/spec.rb +2 -2
- data/lib/arb/util.rb +58 -0
- data/lib/arb/version.rb +1 -1
- metadata +184 -23
- data/lib/download_solutions/api/github/repos.rb +0 -54
- data/lib/download_solutions/api/github.rb +0 -164
- data/lib/download_solutions/api/reddit/add_missing_replies.rb +0 -43
- data/lib/download_solutions/api/reddit/clean_bodies.rb +0 -64
- data/lib/download_solutions/api/reddit/filter_by_language.rb +0 -32
- data/lib/download_solutions/api/reddit/get_initial_response.rb +0 -30
- data/lib/download_solutions/api/reddit/get_serial_comments.rb +0 -145
- data/lib/download_solutions/api/reddit/megathread_ids.rb +0 -19
- data/lib/download_solutions/api/reddit/params.rb +0 -40
- data/lib/download_solutions/api/reddit/reject_unwanted_replies.rb +0 -31
- data/lib/download_solutions/api/reddit/remove_ids.rb +0 -26
- data/lib/download_solutions/api/reddit/remove_language_tags.rb +0 -29
- data/lib/download_solutions/api/reddit.rb +0 -101
- data/lib/download_solutions/cli/cli/shared.rb +0 -35
- data/lib/download_solutions/cli/github.rb +0 -107
- data/lib/download_solutions/cli/reddit.rb +0 -64
- data/lib/download_solutions/download_solutions.rb +0 -18
- data/lib/download_solutions/reverse_markdown/converters/br.rb +0 -15
- data/lib/download_solutions/reverse_markdown/converters/pre.rb +0 -46
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: advent_of_ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Felipe Vogel
|
|
@@ -626,6 +626,79 @@ files:
|
|
|
626
626
|
- data/solutions/github/ZogStriP/2023/24_1.yml
|
|
627
627
|
- data/solutions/github/ZogStriP/2023/24_2.yml
|
|
628
628
|
- data/solutions/github/ZogStriP/2023/25_1.yml
|
|
629
|
+
- data/solutions/github/ZogStriP/2024/01_1.yml
|
|
630
|
+
- data/solutions/github/ZogStriP/2024/01_2.yml
|
|
631
|
+
- data/solutions/github/ZogStriP/2024/02_1.yml
|
|
632
|
+
- data/solutions/github/ZogStriP/2024/02_2.yml
|
|
633
|
+
- data/solutions/github/ZogStriP/2024/03_1.yml
|
|
634
|
+
- data/solutions/github/ZogStriP/2024/03_2.yml
|
|
635
|
+
- data/solutions/github/ZogStriP/2024/04_1.yml
|
|
636
|
+
- data/solutions/github/ZogStriP/2024/04_2.yml
|
|
637
|
+
- data/solutions/github/ZogStriP/2024/05_1.yml
|
|
638
|
+
- data/solutions/github/ZogStriP/2024/05_2.yml
|
|
639
|
+
- data/solutions/github/ZogStriP/2024/06_1.yml
|
|
640
|
+
- data/solutions/github/ZogStriP/2024/06_2.yml
|
|
641
|
+
- data/solutions/github/ZogStriP/2024/07_1.yml
|
|
642
|
+
- data/solutions/github/ZogStriP/2024/07_2.yml
|
|
643
|
+
- data/solutions/github/ZogStriP/2024/08_1.yml
|
|
644
|
+
- data/solutions/github/ZogStriP/2024/08_2.yml
|
|
645
|
+
- data/solutions/github/ZogStriP/2024/09_1.yml
|
|
646
|
+
- data/solutions/github/ZogStriP/2024/09_2.yml
|
|
647
|
+
- data/solutions/github/ZogStriP/2024/10_1.yml
|
|
648
|
+
- data/solutions/github/ZogStriP/2024/10_2.yml
|
|
649
|
+
- data/solutions/github/ZogStriP/2024/11_1.yml
|
|
650
|
+
- data/solutions/github/ZogStriP/2024/11_2.yml
|
|
651
|
+
- data/solutions/github/ZogStriP/2024/12_1.yml
|
|
652
|
+
- data/solutions/github/ZogStriP/2024/12_2.yml
|
|
653
|
+
- data/solutions/github/ZogStriP/2024/13_1.yml
|
|
654
|
+
- data/solutions/github/ZogStriP/2024/13_2.yml
|
|
655
|
+
- data/solutions/github/ZogStriP/2024/14_1.yml
|
|
656
|
+
- data/solutions/github/ZogStriP/2024/14_2.yml
|
|
657
|
+
- data/solutions/github/ZogStriP/2024/15_1.yml
|
|
658
|
+
- data/solutions/github/ZogStriP/2024/15_2.yml
|
|
659
|
+
- data/solutions/github/ZogStriP/2024/16_1.yml
|
|
660
|
+
- data/solutions/github/ZogStriP/2024/16_2.yml
|
|
661
|
+
- data/solutions/github/ZogStriP/2024/17_1.yml
|
|
662
|
+
- data/solutions/github/ZogStriP/2024/17_2.yml
|
|
663
|
+
- data/solutions/github/ZogStriP/2024/18_1.yml
|
|
664
|
+
- data/solutions/github/ZogStriP/2024/18_2.yml
|
|
665
|
+
- data/solutions/github/ZogStriP/2024/19_1.yml
|
|
666
|
+
- data/solutions/github/ZogStriP/2024/19_2.yml
|
|
667
|
+
- data/solutions/github/ZogStriP/2024/20_1.yml
|
|
668
|
+
- data/solutions/github/ZogStriP/2024/20_2.yml
|
|
669
|
+
- data/solutions/github/ZogStriP/2024/21_1.yml
|
|
670
|
+
- data/solutions/github/ZogStriP/2024/21_2.yml
|
|
671
|
+
- data/solutions/github/ZogStriP/2024/22_1.yml
|
|
672
|
+
- data/solutions/github/ZogStriP/2024/22_2.yml
|
|
673
|
+
- data/solutions/github/ZogStriP/2024/23_1.yml
|
|
674
|
+
- data/solutions/github/ZogStriP/2024/23_2.yml
|
|
675
|
+
- data/solutions/github/ZogStriP/2024/24_1.yml
|
|
676
|
+
- data/solutions/github/ZogStriP/2024/24_2.yml
|
|
677
|
+
- data/solutions/github/ZogStriP/2024/25_1.yml
|
|
678
|
+
- data/solutions/github/ZogStriP/2025/01_1.yml
|
|
679
|
+
- data/solutions/github/ZogStriP/2025/01_2.yml
|
|
680
|
+
- data/solutions/github/ZogStriP/2025/02_1.yml
|
|
681
|
+
- data/solutions/github/ZogStriP/2025/02_2.yml
|
|
682
|
+
- data/solutions/github/ZogStriP/2025/03_1.yml
|
|
683
|
+
- data/solutions/github/ZogStriP/2025/03_2.yml
|
|
684
|
+
- data/solutions/github/ZogStriP/2025/04_1.yml
|
|
685
|
+
- data/solutions/github/ZogStriP/2025/04_2.yml
|
|
686
|
+
- data/solutions/github/ZogStriP/2025/05_1.yml
|
|
687
|
+
- data/solutions/github/ZogStriP/2025/05_2.yml
|
|
688
|
+
- data/solutions/github/ZogStriP/2025/06_1.yml
|
|
689
|
+
- data/solutions/github/ZogStriP/2025/06_2.yml
|
|
690
|
+
- data/solutions/github/ZogStriP/2025/07_1.yml
|
|
691
|
+
- data/solutions/github/ZogStriP/2025/07_2.yml
|
|
692
|
+
- data/solutions/github/ZogStriP/2025/08_1.yml
|
|
693
|
+
- data/solutions/github/ZogStriP/2025/08_2.yml
|
|
694
|
+
- data/solutions/github/ZogStriP/2025/09_1.yml
|
|
695
|
+
- data/solutions/github/ZogStriP/2025/09_2.yml
|
|
696
|
+
- data/solutions/github/ZogStriP/2025/10_1.yml
|
|
697
|
+
- data/solutions/github/ZogStriP/2025/10_2.yml
|
|
698
|
+
- data/solutions/github/ZogStriP/2025/11_1.yml
|
|
699
|
+
- data/solutions/github/ZogStriP/2025/11_2.yml
|
|
700
|
+
- data/solutions/github/ZogStriP/2025/12_1.yml
|
|
701
|
+
- data/solutions/github/ZogStriP/2025/12_2.yml
|
|
629
702
|
- data/solutions/github/ahorner/2015/01_1.yml
|
|
630
703
|
- data/solutions/github/ahorner/2015/01_2.yml
|
|
631
704
|
- data/solutions/github/ahorner/2015/02_1.yml
|
|
@@ -1116,6 +1189,29 @@ files:
|
|
|
1116
1189
|
- data/solutions/github/ahorner/2024/24_1.yml
|
|
1117
1190
|
- data/solutions/github/ahorner/2024/24_2.yml
|
|
1118
1191
|
- data/solutions/github/ahorner/2024/25_1.yml
|
|
1192
|
+
- data/solutions/github/ahorner/2025/01_1.yml
|
|
1193
|
+
- data/solutions/github/ahorner/2025/01_2.yml
|
|
1194
|
+
- data/solutions/github/ahorner/2025/02_1.yml
|
|
1195
|
+
- data/solutions/github/ahorner/2025/02_2.yml
|
|
1196
|
+
- data/solutions/github/ahorner/2025/03_1.yml
|
|
1197
|
+
- data/solutions/github/ahorner/2025/03_2.yml
|
|
1198
|
+
- data/solutions/github/ahorner/2025/04_1.yml
|
|
1199
|
+
- data/solutions/github/ahorner/2025/04_2.yml
|
|
1200
|
+
- data/solutions/github/ahorner/2025/05_1.yml
|
|
1201
|
+
- data/solutions/github/ahorner/2025/05_2.yml
|
|
1202
|
+
- data/solutions/github/ahorner/2025/06_1.yml
|
|
1203
|
+
- data/solutions/github/ahorner/2025/06_2.yml
|
|
1204
|
+
- data/solutions/github/ahorner/2025/07_1.yml
|
|
1205
|
+
- data/solutions/github/ahorner/2025/07_2.yml
|
|
1206
|
+
- data/solutions/github/ahorner/2025/08_1.yml
|
|
1207
|
+
- data/solutions/github/ahorner/2025/08_2.yml
|
|
1208
|
+
- data/solutions/github/ahorner/2025/09_1.yml
|
|
1209
|
+
- data/solutions/github/ahorner/2025/09_2.yml
|
|
1210
|
+
- data/solutions/github/ahorner/2025/10_1.yml
|
|
1211
|
+
- data/solutions/github/ahorner/2025/10_2.yml
|
|
1212
|
+
- data/solutions/github/ahorner/2025/11_1.yml
|
|
1213
|
+
- data/solutions/github/ahorner/2025/11_2.yml
|
|
1214
|
+
- data/solutions/github/ahorner/2025/12_1.yml
|
|
1119
1215
|
- data/solutions/github/eregon/2015/01_1.yml
|
|
1120
1216
|
- data/solutions/github/eregon/2015/01_2.yml
|
|
1121
1217
|
- data/solutions/github/eregon/2015/02_1.yml
|
|
@@ -1606,6 +1702,29 @@ files:
|
|
|
1606
1702
|
- data/solutions/github/eregon/2024/24_1.yml
|
|
1607
1703
|
- data/solutions/github/eregon/2024/24_2.yml
|
|
1608
1704
|
- data/solutions/github/eregon/2024/25_1.yml
|
|
1705
|
+
- data/solutions/github/eregon/2025/01_1.yml
|
|
1706
|
+
- data/solutions/github/eregon/2025/01_2.yml
|
|
1707
|
+
- data/solutions/github/eregon/2025/02_1.yml
|
|
1708
|
+
- data/solutions/github/eregon/2025/02_2.yml
|
|
1709
|
+
- data/solutions/github/eregon/2025/03_1.yml
|
|
1710
|
+
- data/solutions/github/eregon/2025/03_2.yml
|
|
1711
|
+
- data/solutions/github/eregon/2025/04_1.yml
|
|
1712
|
+
- data/solutions/github/eregon/2025/04_2.yml
|
|
1713
|
+
- data/solutions/github/eregon/2025/05_1.yml
|
|
1714
|
+
- data/solutions/github/eregon/2025/05_2.yml
|
|
1715
|
+
- data/solutions/github/eregon/2025/06_1.yml
|
|
1716
|
+
- data/solutions/github/eregon/2025/06_2.yml
|
|
1717
|
+
- data/solutions/github/eregon/2025/07_1.yml
|
|
1718
|
+
- data/solutions/github/eregon/2025/07_2.yml
|
|
1719
|
+
- data/solutions/github/eregon/2025/08_1.yml
|
|
1720
|
+
- data/solutions/github/eregon/2025/08_2.yml
|
|
1721
|
+
- data/solutions/github/eregon/2025/09_1.yml
|
|
1722
|
+
- data/solutions/github/eregon/2025/09_2.yml
|
|
1723
|
+
- data/solutions/github/eregon/2025/10_1.yml
|
|
1724
|
+
- data/solutions/github/eregon/2025/10_2.yml
|
|
1725
|
+
- data/solutions/github/eregon/2025/11_1.yml
|
|
1726
|
+
- data/solutions/github/eregon/2025/11_2.yml
|
|
1727
|
+
- data/solutions/github/eregon/2025/12_1.yml
|
|
1609
1728
|
- data/solutions/github/erikw/2015/01_1.yml
|
|
1610
1729
|
- data/solutions/github/erikw/2015/01_2.yml
|
|
1611
1730
|
- data/solutions/github/erikw/2015/02_1.yml
|
|
@@ -1949,6 +2068,30 @@ files:
|
|
|
1949
2068
|
- data/solutions/github/erikw/2021/24_1.yml
|
|
1950
2069
|
- data/solutions/github/erikw/2021/24_2.yml
|
|
1951
2070
|
- data/solutions/github/erikw/2021/25_1.yml
|
|
2071
|
+
- data/solutions/github/erikw/2025/01_1.yml
|
|
2072
|
+
- data/solutions/github/erikw/2025/01_2.yml
|
|
2073
|
+
- data/solutions/github/erikw/2025/02_1.yml
|
|
2074
|
+
- data/solutions/github/erikw/2025/02_2.yml
|
|
2075
|
+
- data/solutions/github/erikw/2025/03_1.yml
|
|
2076
|
+
- data/solutions/github/erikw/2025/03_2.yml
|
|
2077
|
+
- data/solutions/github/erikw/2025/04_1.yml
|
|
2078
|
+
- data/solutions/github/erikw/2025/04_2.yml
|
|
2079
|
+
- data/solutions/github/erikw/2025/05_1.yml
|
|
2080
|
+
- data/solutions/github/erikw/2025/05_2.yml
|
|
2081
|
+
- data/solutions/github/erikw/2025/06_1.yml
|
|
2082
|
+
- data/solutions/github/erikw/2025/06_2.yml
|
|
2083
|
+
- data/solutions/github/erikw/2025/07_1.yml
|
|
2084
|
+
- data/solutions/github/erikw/2025/07_2.yml
|
|
2085
|
+
- data/solutions/github/erikw/2025/08_1.yml
|
|
2086
|
+
- data/solutions/github/erikw/2025/08_2.yml
|
|
2087
|
+
- data/solutions/github/erikw/2025/09_1.yml
|
|
2088
|
+
- data/solutions/github/erikw/2025/09_2.yml
|
|
2089
|
+
- data/solutions/github/erikw/2025/10_1.yml
|
|
2090
|
+
- data/solutions/github/erikw/2025/10_2.yml
|
|
2091
|
+
- data/solutions/github/erikw/2025/11_1.yml
|
|
2092
|
+
- data/solutions/github/erikw/2025/11_2.yml
|
|
2093
|
+
- data/solutions/github/erikw/2025/12_1.yml
|
|
2094
|
+
- data/solutions/github/erikw/2025/12_2.yml
|
|
1952
2095
|
- data/solutions/github/gchan/2015/01_1.yml
|
|
1953
2096
|
- data/solutions/github/gchan/2015/01_2.yml
|
|
1954
2097
|
- data/solutions/github/gchan/2015/02_1.yml
|
|
@@ -2439,6 +2582,29 @@ files:
|
|
|
2439
2582
|
- data/solutions/github/gchan/2024/24_1.yml
|
|
2440
2583
|
- data/solutions/github/gchan/2024/24_2.yml
|
|
2441
2584
|
- data/solutions/github/gchan/2024/25_1.yml
|
|
2585
|
+
- data/solutions/github/gchan/2025/01_1.yml
|
|
2586
|
+
- data/solutions/github/gchan/2025/01_2.yml
|
|
2587
|
+
- data/solutions/github/gchan/2025/02_1.yml
|
|
2588
|
+
- data/solutions/github/gchan/2025/02_2.yml
|
|
2589
|
+
- data/solutions/github/gchan/2025/03_1.yml
|
|
2590
|
+
- data/solutions/github/gchan/2025/03_2.yml
|
|
2591
|
+
- data/solutions/github/gchan/2025/04_1.yml
|
|
2592
|
+
- data/solutions/github/gchan/2025/04_2.yml
|
|
2593
|
+
- data/solutions/github/gchan/2025/05_1.yml
|
|
2594
|
+
- data/solutions/github/gchan/2025/05_2.yml
|
|
2595
|
+
- data/solutions/github/gchan/2025/06_1.yml
|
|
2596
|
+
- data/solutions/github/gchan/2025/06_2.yml
|
|
2597
|
+
- data/solutions/github/gchan/2025/07_1.yml
|
|
2598
|
+
- data/solutions/github/gchan/2025/07_2.yml
|
|
2599
|
+
- data/solutions/github/gchan/2025/08_1.yml
|
|
2600
|
+
- data/solutions/github/gchan/2025/08_2.yml
|
|
2601
|
+
- data/solutions/github/gchan/2025/09_1.yml
|
|
2602
|
+
- data/solutions/github/gchan/2025/09_2.yml
|
|
2603
|
+
- data/solutions/github/gchan/2025/10_1.yml
|
|
2604
|
+
- data/solutions/github/gchan/2025/10_2.yml
|
|
2605
|
+
- data/solutions/github/gchan/2025/11_1.yml
|
|
2606
|
+
- data/solutions/github/gchan/2025/11_2.yml
|
|
2607
|
+
- data/solutions/github/gchan/2025/12_1.yml
|
|
2442
2608
|
- data/solutions/reddit/ruby/2015/01.yml
|
|
2443
2609
|
- data/solutions/reddit/ruby/2015/02.yml
|
|
2444
2610
|
- data/solutions/reddit/ruby/2015/03.yml
|
|
@@ -2689,6 +2855,18 @@ files:
|
|
|
2689
2855
|
- data/solutions/reddit/ruby/2024/23.yml
|
|
2690
2856
|
- data/solutions/reddit/ruby/2024/24.yml
|
|
2691
2857
|
- data/solutions/reddit/ruby/2024/25.yml
|
|
2858
|
+
- data/solutions/reddit/ruby/2025/01.yml
|
|
2859
|
+
- data/solutions/reddit/ruby/2025/02.yml
|
|
2860
|
+
- data/solutions/reddit/ruby/2025/03.yml
|
|
2861
|
+
- data/solutions/reddit/ruby/2025/04.yml
|
|
2862
|
+
- data/solutions/reddit/ruby/2025/05.yml
|
|
2863
|
+
- data/solutions/reddit/ruby/2025/06.yml
|
|
2864
|
+
- data/solutions/reddit/ruby/2025/07.yml
|
|
2865
|
+
- data/solutions/reddit/ruby/2025/08.yml
|
|
2866
|
+
- data/solutions/reddit/ruby/2025/09.yml
|
|
2867
|
+
- data/solutions/reddit/ruby/2025/10.yml
|
|
2868
|
+
- data/solutions/reddit/ruby/2025/11.yml
|
|
2869
|
+
- data/solutions/reddit/ruby/2025/12.yml
|
|
2692
2870
|
- lib/arb/api/aoc.rb
|
|
2693
2871
|
- lib/arb/api/other_solutions.rb
|
|
2694
2872
|
- lib/arb/arb.rb
|
|
@@ -2706,26 +2884,8 @@ files:
|
|
|
2706
2884
|
- lib/arb/files/solution.rb
|
|
2707
2885
|
- lib/arb/files/spec.rb
|
|
2708
2886
|
- lib/arb/formatters/rubocop.rb
|
|
2887
|
+
- lib/arb/util.rb
|
|
2709
2888
|
- lib/arb/version.rb
|
|
2710
|
-
- lib/download_solutions/api/github.rb
|
|
2711
|
-
- lib/download_solutions/api/github/repos.rb
|
|
2712
|
-
- lib/download_solutions/api/reddit.rb
|
|
2713
|
-
- lib/download_solutions/api/reddit/add_missing_replies.rb
|
|
2714
|
-
- lib/download_solutions/api/reddit/clean_bodies.rb
|
|
2715
|
-
- lib/download_solutions/api/reddit/filter_by_language.rb
|
|
2716
|
-
- lib/download_solutions/api/reddit/get_initial_response.rb
|
|
2717
|
-
- lib/download_solutions/api/reddit/get_serial_comments.rb
|
|
2718
|
-
- lib/download_solutions/api/reddit/megathread_ids.rb
|
|
2719
|
-
- lib/download_solutions/api/reddit/params.rb
|
|
2720
|
-
- lib/download_solutions/api/reddit/reject_unwanted_replies.rb
|
|
2721
|
-
- lib/download_solutions/api/reddit/remove_ids.rb
|
|
2722
|
-
- lib/download_solutions/api/reddit/remove_language_tags.rb
|
|
2723
|
-
- lib/download_solutions/cli/cli/shared.rb
|
|
2724
|
-
- lib/download_solutions/cli/github.rb
|
|
2725
|
-
- lib/download_solutions/cli/reddit.rb
|
|
2726
|
-
- lib/download_solutions/download_solutions.rb
|
|
2727
|
-
- lib/download_solutions/reverse_markdown/converters/br.rb
|
|
2728
|
-
- lib/download_solutions/reverse_markdown/converters/pre.rb
|
|
2729
2889
|
homepage: https://github.com/fpsvogel/advent_of_ruby
|
|
2730
2890
|
licenses:
|
|
2731
2891
|
- MIT
|
|
@@ -2736,18 +2896,19 @@ metadata:
|
|
|
2736
2896
|
rdoc_options: []
|
|
2737
2897
|
require_paths:
|
|
2738
2898
|
- lib
|
|
2899
|
+
- dev
|
|
2739
2900
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
2740
2901
|
requirements:
|
|
2741
|
-
- - "
|
|
2902
|
+
- - ">="
|
|
2742
2903
|
- !ruby/object:Gem::Version
|
|
2743
|
-
version: 3.4
|
|
2904
|
+
version: '3.4'
|
|
2744
2905
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
2745
2906
|
requirements:
|
|
2746
2907
|
- - ">="
|
|
2747
2908
|
- !ruby/object:Gem::Version
|
|
2748
2909
|
version: '0'
|
|
2749
2910
|
requirements: []
|
|
2750
|
-
rubygems_version: 3.6.
|
|
2911
|
+
rubygems_version: 3.6.9
|
|
2751
2912
|
specification_version: 4
|
|
2752
2913
|
summary: CLI for Advent of Code in Ruby, via the `arb` command.
|
|
2753
2914
|
test_files: []
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
module DownloadSolutions
|
|
2
|
-
module Api
|
|
3
|
-
class Github
|
|
4
|
-
REPOS = {
|
|
5
|
-
"ahorner" => {
|
|
6
|
-
repo: "advent-of-code",
|
|
7
|
-
year_directory: "lib/%<year>d",
|
|
8
|
-
both_parts: "%<day>.2d.rb"
|
|
9
|
-
},
|
|
10
|
-
"eregon" => {
|
|
11
|
-
repo: "adventofcode",
|
|
12
|
-
part_1: ->(day:) {
|
|
13
|
-
/\A#{day}(?:a.*)?\.rb\z/
|
|
14
|
-
},
|
|
15
|
-
part_2: ->(day:) {
|
|
16
|
-
/\A#{day}(?:b.*|\D*)\.rb\z/
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"erikw" => {
|
|
20
|
-
repo: "advent-of-code-solutions",
|
|
21
|
-
day_directory: "%<day>.2d",
|
|
22
|
-
part_1: "part1.rb",
|
|
23
|
-
part_2: "part2.rb",
|
|
24
|
-
edits: ->(file_contents) {
|
|
25
|
-
# Remove the first 3 lines (boilerplate).
|
|
26
|
-
file_contents.lines[3..].join
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"gchan" => {
|
|
30
|
-
repo: "advent-of-code-ruby",
|
|
31
|
-
day_directory: "day-%<day>.2d",
|
|
32
|
-
part_1: "day-%<day>.2d-part-1.rb",
|
|
33
|
-
part_2: "day-%<day>.2d-part-2.rb",
|
|
34
|
-
# rarely, e.g. https://github.com/gchan/advent-of-code-ruby/tree/main/2023/day-17
|
|
35
|
-
both_parts: "day-%<day>.2d-part-1-and-2.rb",
|
|
36
|
-
edits: ->(file_contents) {
|
|
37
|
-
# Remove the first 5 lines (boilerplate).
|
|
38
|
-
file_contents.lines[5..].join
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"ZogStriP" => {
|
|
42
|
-
repo: "adventofcode-old",
|
|
43
|
-
both_parts: ->(day:) {
|
|
44
|
-
/\A#{day.to_s.rjust(2, "0")}_.+\.rb\z/
|
|
45
|
-
},
|
|
46
|
-
edits: ->(file_contents) {
|
|
47
|
-
# Remove input at the end of the file.
|
|
48
|
-
file_contents.split("\n__END__").first
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
module DownloadSolutions
|
|
2
|
-
module Api
|
|
3
|
-
class Github
|
|
4
|
-
UnexpectedResponseError = Class.new(StandardError)
|
|
5
|
-
NotFoundResponseError = Class.new(StandardError)
|
|
6
|
-
|
|
7
|
-
private attr_reader :user_agent, :auth_token
|
|
8
|
-
|
|
9
|
-
# @param auth_token [String]
|
|
10
|
-
def initialize(auth_token:)
|
|
11
|
-
@user_agent = "AdventOfRubyScript/#{Arb::VERSION} by fpsvogel"
|
|
12
|
-
@auth_token = auth_token
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# @param author [String]
|
|
16
|
-
# @param year [Integer]
|
|
17
|
-
# @param day [Integer]
|
|
18
|
-
# @param max_day [Integer]
|
|
19
|
-
# @param force [Boolean]
|
|
20
|
-
# @param existing_solutions [Array<Array(Integer, Integer)>]
|
|
21
|
-
# @return [Array<Hash>, nil] nil if the year directory doesn't exist for the author.
|
|
22
|
-
def get_solutions(author:, year:, input_day: nil, max_day: 25, force: false, existing_solutions: [])
|
|
23
|
-
solutions = {new: {}, skipped: [], not_found: []}
|
|
24
|
-
|
|
25
|
-
year_directory = (REPOS[author][:year_directory] || "%<year>d") % {year:}
|
|
26
|
-
year_files = get_year_files!(solutions:, year_directory:, author:, year:) || (return solutions)
|
|
27
|
-
|
|
28
|
-
(input_day || 1).upto(input_day || max_day) do |day|
|
|
29
|
-
if REPOS[author][:day_directory]
|
|
30
|
-
day_files = get_day_files!(solutions:, year_directory:, author:, year:, day:, force:, existing_solutions:) || next
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
1.upto(2) do |part|
|
|
34
|
-
next if day == 25 && part == 2
|
|
35
|
-
|
|
36
|
-
if !force && existing_solutions.include?([day, part])
|
|
37
|
-
solutions[:skipped] << [day, part]
|
|
38
|
-
else
|
|
39
|
-
solution = get_part(author:, year:, day:, part:, year_files:, day_files:)
|
|
40
|
-
|
|
41
|
-
if solution.empty?
|
|
42
|
-
solutions[:not_found] << [day, part]
|
|
43
|
-
else
|
|
44
|
-
solutions[:new][[day, part]] = solution
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
solutions
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
private
|
|
54
|
-
|
|
55
|
-
def get_year_files!(solutions:, year_directory:, author:, year:)
|
|
56
|
-
year_response = api_connection.get("/repos/#{author}/#{REPOS[author][:repo]}/contents/#{year_directory}")
|
|
57
|
-
|
|
58
|
-
if year_response.status == 404
|
|
59
|
-
solutions[:not_found] = (1..max_day).flat_map { |day|
|
|
60
|
-
[[day, 1], ([day, 2] unless day == 25)]
|
|
61
|
-
}.compact
|
|
62
|
-
|
|
63
|
-
return nil
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
JSON.parse(year_response.body)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def get_day_files!(solutions:, year_directory:, author:, year:, day:, force:, existing_solutions:)
|
|
70
|
-
if !force && existing_solutions.any? { |existing_day, _existing_part| existing_day == day }
|
|
71
|
-
solutions[:skipped] << [day, 1]
|
|
72
|
-
solutions[:skipped] << [day, 1] unless day == 25
|
|
73
|
-
return nil
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
day_directory = REPOS[author][:day_directory] % {day:}
|
|
77
|
-
day_response = api_connection.get("/repos/#{author}/#{REPOS[author][:repo]}/contents/#{year_directory}/#{day_directory}")
|
|
78
|
-
|
|
79
|
-
if day_response.status == 404
|
|
80
|
-
solutions[:not_found] << [day, 1]
|
|
81
|
-
solutions[:not_found] << [day, 2] unless day == 25
|
|
82
|
-
return nil
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
JSON.parse(day_response.body)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def get_part(author:, year:, day:, part:, year_files:, day_files: nil)
|
|
89
|
-
exact_path = (REPOS[author][:"part_#{part}"] || REPOS[author][:both_parts]).is_a?(String)
|
|
90
|
-
|
|
91
|
-
if exact_path
|
|
92
|
-
(day_files || year_files)
|
|
93
|
-
.select {
|
|
94
|
-
if REPOS[author][:both_parts] && it["name"] == REPOS[author][:both_parts] % {year:, day:}
|
|
95
|
-
next if part == 1 && day != 25 # both_parts will be saved in part 2
|
|
96
|
-
true
|
|
97
|
-
elsif REPOS[author][:"part_#{part}"]
|
|
98
|
-
it["name"] == REPOS[author][:"part_#{part}"] % {year:, day:}
|
|
99
|
-
end
|
|
100
|
-
}
|
|
101
|
-
.map { simplify_response(it, author) }
|
|
102
|
-
else # regex-matched paths
|
|
103
|
-
(day_files || year_files)
|
|
104
|
-
.select {
|
|
105
|
-
if REPOS[author][:both_parts] && it["name"].match?(REPOS[author][:both_parts].call(day:))
|
|
106
|
-
next if part == 1 && day != 25 # both_parts will be saved in part 2
|
|
107
|
-
true
|
|
108
|
-
elsif REPOS[author][:part_1] && REPOS[author][:part_2]
|
|
109
|
-
if part == 2
|
|
110
|
-
it["name"].match?(REPOS[author][:part_2].call(day:)) &&
|
|
111
|
-
!it["name"].match?(REPOS[author][:part_1].call(day:))
|
|
112
|
-
else
|
|
113
|
-
it["name"].match?(REPOS[author][:part_1].call(day:))
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
}
|
|
117
|
-
.map { simplify_response(it, author) }
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def simplify_response(response, author)
|
|
122
|
-
solution = raw_connection.get(response["download_url"]).body
|
|
123
|
-
solution = REPOS[author][:edits].call(solution) if REPOS[author][:edits]
|
|
124
|
-
{
|
|
125
|
-
name: response["name"],
|
|
126
|
-
url: response["html_url"].rpartition("/").first,
|
|
127
|
-
solution: solution.strip
|
|
128
|
-
}
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def api_connection
|
|
132
|
-
@api_connection ||= Faraday.new(
|
|
133
|
-
url: "https://api.github.com",
|
|
134
|
-
headers: {
|
|
135
|
-
"User-Agent" => user_agent,
|
|
136
|
-
"Accept" => "application/vnd.github+json"
|
|
137
|
-
}
|
|
138
|
-
) do |f|
|
|
139
|
-
f.request :authorization, "token", -> { auth_token }
|
|
140
|
-
f.request :retry, {
|
|
141
|
-
max: 5,
|
|
142
|
-
interval: 0.5,
|
|
143
|
-
interval_randomness: 0.5,
|
|
144
|
-
backoff_factor: 2
|
|
145
|
-
}
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def raw_connection
|
|
150
|
-
@raw_connection ||= Faraday.new(
|
|
151
|
-
url: "https://raw.githubusercontent.com",
|
|
152
|
-
headers: {"User-Agent" => user_agent}
|
|
153
|
-
) do |f|
|
|
154
|
-
f.request :retry, {
|
|
155
|
-
max: 5,
|
|
156
|
-
interval: 0.5,
|
|
157
|
-
interval_randomness: 0.5,
|
|
158
|
-
backoff_factor: 2
|
|
159
|
-
}
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
module DownloadSolutions
|
|
2
|
-
module Api
|
|
3
|
-
class Reddit
|
|
4
|
-
class AddMissingReplies
|
|
5
|
-
# Fetches replies to comments that are not yet loaded, only listed in
|
|
6
|
-
# "more children" nodes.
|
|
7
|
-
#
|
|
8
|
-
# @param params [Reddit::Params]
|
|
9
|
-
# @return [void] params.comments is modified in place.
|
|
10
|
-
def self.call(params:)
|
|
11
|
-
params.comments.each do |comment|
|
|
12
|
-
add_missing_replies!(comment, params)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
params.comments.reject! do |comment|
|
|
16
|
-
comment[:parent_id] != params.thread_id
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private_class_method def self.add_missing_replies!(comment, params)
|
|
21
|
-
comments_from_more_children, more_children_from_more_children =
|
|
22
|
-
GetSerialComments.call(
|
|
23
|
-
params:,
|
|
24
|
-
parent_id: comment[:id]
|
|
25
|
-
)
|
|
26
|
-
params.original_comments += comments_from_more_children
|
|
27
|
-
debugger unless more_children_from_more_children.empty?
|
|
28
|
-
params.original_comments += more_children_from_more_children
|
|
29
|
-
|
|
30
|
-
children = params.original_comments.filter { it[:parent_id] == comment[:id] }
|
|
31
|
-
|
|
32
|
-
comment[:replies] += children
|
|
33
|
-
|
|
34
|
-
children.each do |child|
|
|
35
|
-
add_missing_replies!(child, params)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
comment[:replies].uniq!
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
module DownloadSolutions
|
|
2
|
-
module Api
|
|
3
|
-
class Reddit
|
|
4
|
-
class CleanBodies
|
|
5
|
-
MARKDOWN_PARSER = Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true)
|
|
6
|
-
|
|
7
|
-
# Clean up comment bodies by removing unwanted characters, translating
|
|
8
|
-
# encoded characters, and standardizing to fenced (triple backtick) code
|
|
9
|
-
# blocks.
|
|
10
|
-
#
|
|
11
|
-
# @param params [Reddit::Params]
|
|
12
|
-
# @return [void] params.comments is modified in place.
|
|
13
|
-
def self.call(params:)
|
|
14
|
-
params.comments.each do |comment|
|
|
15
|
-
clean_body!(comment, params.languages)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private_class_method def self.clean_body!(comment, languages)
|
|
20
|
-
comment[:body] = preclean_markdown(comment[:body], languages)
|
|
21
|
-
.then { |body_markdown| MARKDOWN_PARSER.render(body_markdown) }
|
|
22
|
-
.then { |body_html| to_cleaned_markdown(body_html, languages) }
|
|
23
|
-
|
|
24
|
-
comment[:replies].each do |reply|
|
|
25
|
-
clean_body!(reply, languages)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
private_class_method def self.preclean_markdown(initial_body_markdown, languages)
|
|
30
|
-
initial_body_markdown
|
|
31
|
-
.tr("\u00a0", " ") # Non-breaking space
|
|
32
|
-
# Zero-width space (unintentional); do not remove "\u200b" (intentional, e.g. Unihedron's poems in 2019)
|
|
33
|
-
.gsub("#x200B;", "")
|
|
34
|
-
.gsub("&", "&")
|
|
35
|
-
# Mysterious ampersand, on Reddit an empty paragraph
|
|
36
|
-
.gsub("\n\n&\n\n", "\n\n")
|
|
37
|
-
.delete_suffix("\n\n&")
|
|
38
|
-
.gsub("<", "<")
|
|
39
|
-
.gsub(">", ">")
|
|
40
|
-
.gsub("'", "'")
|
|
41
|
-
# Convert one or two backticks on their own line, to three for a code block.
|
|
42
|
-
.gsub(
|
|
43
|
-
/\\?`(?:\\?`)?(?:#{languages.first})?\n(.+?)\n\\?`(?:\\?`)?(?=\n|\z)/m,
|
|
44
|
-
"\n\n```\n\\1\n```\n"
|
|
45
|
-
)
|
|
46
|
-
.gsub(/ ```.*/, "") # Superfluous backticks (already indented)
|
|
47
|
-
# Add an empty line above code blocks, if missing.
|
|
48
|
-
.gsub(/\n{0,2}```(?:#{languages.first})?/, "\n\n```")
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
private_class_method def self.to_cleaned_markdown(body_html, languages)
|
|
52
|
-
body_html
|
|
53
|
-
# https://github.com/xijo/reverse_markdown/blob/14d53d5f914fd926b49e6492fd7bd95e62ef541a/lib/reverse_markdown/converters/pre.rb#L37
|
|
54
|
-
.gsub("<pre>", "<pre class=\"brush:#{languages.first};\">")
|
|
55
|
-
.gsub(/<pre><code class=([^>]+)>/, "<pre class=\\1><code>")
|
|
56
|
-
.then { |cleaned_raw_body|
|
|
57
|
-
ReverseMarkdown.convert(cleaned_raw_body, github_flavored: true)
|
|
58
|
-
}
|
|
59
|
-
.gsub(/ +\n/, "\n") # Strip trailing spaces
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module DownloadSolutions
|
|
2
|
-
module Api
|
|
3
|
-
class Reddit
|
|
4
|
-
class FilterByLanguage
|
|
5
|
-
# Filters comments by the desired programming language(s).
|
|
6
|
-
#
|
|
7
|
-
# @param params [Reddit::Params]
|
|
8
|
-
# @return [Array<Hash>]
|
|
9
|
-
def self.call(params:)
|
|
10
|
-
params.original_comments.filter { |comment|
|
|
11
|
-
comment_body = comment[:body]&.downcase
|
|
12
|
-
next unless comment_body
|
|
13
|
-
|
|
14
|
-
language_specified = comment_body.match?(/\[[[:punct:]]*language:/i)
|
|
15
|
-
|
|
16
|
-
if language_specified
|
|
17
|
-
params.languages.any? { |language|
|
|
18
|
-
comment_body.match?(/\[[[:punct:]]*language:\s*#{language}/i)
|
|
19
|
-
}
|
|
20
|
-
else
|
|
21
|
-
params.languages.any? { |language|
|
|
22
|
-
# "sh:" because of "<pre class=\"brush:ruby", see:
|
|
23
|
-
# https://github.com/xijo/reverse_markdown/blob/14d53d5f914fd926b49e6492fd7bd95e62ef541a/lib/reverse_markdown/converters/pre.rb#L37
|
|
24
|
-
comment_body.match?(/(?<!```|sh:)#{language}/i)
|
|
25
|
-
}
|
|
26
|
-
end
|
|
27
|
-
}
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
module DownloadSolutions
|
|
2
|
-
module Api
|
|
3
|
-
class Reddit
|
|
4
|
-
class GetInitialResponse
|
|
5
|
-
# Equivalent to the initial page load of a Reddit thread, which loads
|
|
6
|
-
# some comments, but (if the thread has many comments) not all of them.
|
|
7
|
-
#
|
|
8
|
-
# @param params [Reddit::Params]
|
|
9
|
-
# @return [Faraday::Response]
|
|
10
|
-
def self.call(params:)
|
|
11
|
-
initial_response = nil
|
|
12
|
-
|
|
13
|
-
loop do
|
|
14
|
-
initial_response = params.connection.get(params.megathread_path)
|
|
15
|
-
|
|
16
|
-
if initial_response.body.empty?
|
|
17
|
-
puts PASTEL.bright_black("Throttled by Reddit. Sleeping for 60 seconds...")
|
|
18
|
-
sleep 60
|
|
19
|
-
else
|
|
20
|
-
puts "Fetching comments for #{params.year}##{params.day.to_s.rjust(2, "0")}..."
|
|
21
|
-
break
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
initial_response
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|