summaryrefslogtreecommitdiff
path: root/Rakefile
blob: 38adb95cefe238044834db57aefa98c739f86558 (plain)
1
2
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
%w[json erb]
  .each { require _1 }

def fputs(f, c)
  puts "fputs #{f}"
  File.write f, c
end
def erb(tmpl, ctx={}) =
  ERB.new(File.read(tmpl), trim_mode: "-")
    .result_with_hash(ctx)

module Component
  def Component.parse(str)
    script = []; style = []; html = []
    cur = html
    str.lines.each do |line|
      line = line.chomp
      if line == "<script>" and cur.object_id == html.object_id
        cur = script
      elsif line == "<style>" and cur.object_id == html.object_id
        cur = style
      elsif line =~ /^<\/(style|script)>$/ and cur.object_id != html.object_id
        cur = html
      else
        cur.push line
      end
    end
    {style: style * "\n",
     html: html * "\n",
     script: script * "\n"}
  end

  private
  def Component.amalg(list, key) =
    list.values.map { _1[key] }.filter { _1 != "" } * "\n"
  public
  def Component.parse_many(deps)
    start = deps.map { [_1.split(".")[0], parse(read(_1, []))] }.to_h
    start.merge(style: amalg(start, :style),
                html: amalg(start, :html),
                script: amalg(start, :script))
  end

  def Component.read(f, deps)
    if not f =~ /\.erb/
      File.read f
    else
      erb f, parse_many(deps)
    end
  end
end

DB = "protobowl-2019-10-15-ALL.json"
KEPT_KEYS = %w[category subcategory difficulty
               year source tournament round num
               question answer]

$data = nil
def get_data
  return $data if $data
  $data =
    File.read(DB)
      .split("\n")
      .map! { JSON.parse _1 }
      .filter! { _1["type"] == "qb" }
end

file DB do
  sh "wget -N https://github.com/neotenic/database-dumps/raw/refs/heads/master/2019-10-15-ALL.json.xz"
  sh "unxz 2019-10-15-ALL.json.xz"
  mv "2019-10-15-ALL.json", DB
end

file "summary.json": [DB] do
  data = get_data

  difficulties = data.map { _1["difficulty"] }.uniq
  categories = data.map { _1["category"] }.uniq

  fputs "summary.json",
        JSON.generate({difficulties:, categories:})
end.invoke # ensure it's generated now

$difficulties, $categories =
  JSON.parse(File.read "summary.json")
    .values_at("difficulties", "categories")

def dir_from(dif) = "qdb/#{dif.downcase}"
def name_from(dif, cat) = "#{dir_from dif}/#{cat.downcase.gsub(/\s/, "-")}.json"

$files = []
$difficulties.each do |dif|
  dir = dir_from(dif)
  directory dir
  $categories.each do |cat|
    f = name_from(dif, cat)
    $files.push f
    file f => [DB, dir] do
      d = get_data
            .filter { _1["difficulty"] == dif &&
		      _1["category"] == cat }
            .map { _1.slice(*KEPT_KEYS) }
      fputs f, JSON.generate(d)
    end
  end
end

file qdb: [DB, *$files]

file "deck.html": ["deck.erb.html", "summary.json"] do
  fputs "deck.html", erb("deck.erb.html")
end

file "_.html": ["_.erb.html",
                "utils.html", "storage.html",
                "card.html", "reviewer.html",
                "deck.html", "settings.html",
                "ie.html"] do |t|
  fputs "_.html", Component.read("_.erb.html", t.prereqs[1..-1])
end

task :clean do
  ["qdb", "summary.json", "_.html", "deck.html"].map { rm_r _1 }
end

task default: ["qdb", "_.html"]

task :publish do
  sh "rsync -rutv --delete qdb _.html manifest.json root@ba.ln.ea.cx:/var/www/onpoint/"
end