Module: DownloadSolutions::Cli

Defined in:
lib/download_solutions/cli/github.rb,
lib/download_solutions/cli/reddit.rb,
lib/download_solutions/cli/cli/shared.rb

Class Method Summary collapse

Class Method Details

.github(year: nil, day: nil, author: nil, force: false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/download_solutions/cli/github.rb', line 3

def self.github(year: nil, day: nil, author: nil, force: false)
  validate_year_and_day(year:, day:)

  author_name = author.nil? ? "all authors" : PASTEL.blue(author)
  detail = "by #{author_name}"
  output_initial_message(source: "GitHub", year:, day:, force:, detail:)

  github_directory = File.join("data", "solutions", "github")

  repos = Api::Github::REPOS
  if author
    if repos.key?(author)
      repos = repos.select { it == author }
    else
      raise InputError, "Repo author #{PASTEL.blue(author)} not found."
    end
  end

  max_year, max_day = max_year_and_day(year:, day:)

  authors = repos.keys
  authors.each do |author|
    author_directory = File.join(github_directory, author)
    Dir.mkdir(author_directory) unless Dir.exist?(author_directory)

    (year || 2015).upto(year || max_year) do |current_year|
      year_directory = File.join(author_directory, current_year.to_s)

      existing_solutions =
        if Dir.exist?(year_directory)
          Dir.entries(year_directory)
            .filter_map {
              it.delete_suffix(".yml").split("_").map(&:to_i) if it.end_with?(".yml")
            }.sort
        else
          []
        end

      solutions = github_api.get_solutions(
        author:,
        year: current_year,
        input_day: day,
        max_day:,
        force:,
        existing_solutions:
      )

      skipped_list = solutions_str(solutions[:skipped])
      if solutions[:skipped].any?
        puts "#{PASTEL.yellow.bold("Skipping")} from #{author} #{current_year}, already existing: #{PASTEL.yellow(skipped_list)}"
      end

      not_found_list = solutions_str(solutions[:not_found])
      if solutions[:not_found].any?
        puts "#{PASTEL.red.bold("Not found")} from #{author} #{current_year}: #{PASTEL.red(not_found_list)}"
        if solutions[:not_found].size < 49
          # Save empty files for not found solutions, so that they won't be
          # attempted to be downloaded again.
          Dir.mkdir(year_directory) unless Dir.exist?(year_directory)
          solutions[:not_found].each do |(day, part)|
            path = File.join(year_directory, "#{day.to_s.rjust(2, "0")}_#{part}.yml")
            File.write(path, [].to_yaml)
          end
        end
      end

      if solutions[:new].any?
        Dir.mkdir(year_directory) unless Dir.exist?(year_directory)
        solutions[:new].each do |(day, part), content|
          path = File.join(year_directory, "#{day.to_s.rjust(2, "0")}_#{part}.yml")
          File.write(path, content.to_yaml(line_width: -1))
        end

        new_list = solutions_str(solutions[:new].keys)
        puts "#{PASTEL.blue.bold("Saved")} from #{author} #{current_year}: #{PASTEL.blue(new_list)}"
        puts "Saved to #{year_directory}"
      end
    end

    puts
  end
rescue InputError => e
  puts PASTEL.red(e.message)
end

.reddit(year: nil, day: nil, languages: ["ruby"], force: false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/download_solutions/cli/reddit.rb', line 3

def self.reddit(year: nil, day: nil, languages: ["ruby"], force: false)
  validate_year_and_day(year:, day:)

  language_names = PASTEL.blue(languages.join(", "))
  detail = "for #{language_names}"
  output_initial_message(source: "Reddit", year:, day:, force:, detail:)

  language_directory = File.join("data", "solutions", "reddit", languages.join("-"))
  Dir.mkdir(language_directory) unless Dir.exist?(language_directory)

  max_year, max_day = max_year_and_day(year:, day:)

  (year || 2015).upto(year || max_year) do |current_year|
    year_directory = File.join("data", "solutions", "reddit", languages.join("-"), current_year.to_s)
    Dir.mkdir(year_directory) unless Dir.exist?(year_directory)

    (day || 1).upto(day || max_day) do |current_day|
      path = File.join("data", "solutions", "reddit", languages.join("-"), year.to_s, "#{current_day.to_s.rjust(2, "0")}.yml")

      if File.exist?(path) && !force
        puts PASTEL.yellow("Skipping #{PASTEL.yellow.bold("#{current_year}##{current_day.to_s.rjust(2, "0")}")} as it already exists.")
        puts
        next
      end

      comments = reddit_api.get_comments(
        year: current_year,
        day: current_day,
        languages:
      )

      File.write(path, comments.to_yaml(line_width: -1))

      puts "Saved #{PASTEL.blue("#{current_year}##{current_day.to_s.rjust(2, "0")}")} to #{path}"
      puts
    end
  end
rescue InputError => e
  puts PASTEL.red(e.message)
end