kittypedia 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +4 -0
- data/lib/kittypedia.rb +5 -2
- data/lib/kittypedia/pages/timeline_fancies.rb +379 -0
- data/lib/kittypedia/pages/timeline_purrstiges.rb +223 -0
- data/lib/kittypedia/pages/timeline_traits.rb +107 -0
- data/lib/kittypedia/pages/traits.rb +109 -0
- data/lib/kittypedia/version.rb +2 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63e560f65ff5047e2809e14e7bb7411f3dc7c972b84f477ef530e7d61c52e211
|
4
|
+
data.tar.gz: d59dcc318722d8afbbb1e151c56eb4a873b49e69fd90e15f23eebb4638624d91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81df9f5020272bb32d7324e94277cb59d7b17e5eb2e1720595ad02f0cdb4796f4c1794993575a3430de906a1f12c9d61317c65021b9268bda0ba99a8610321eb
|
7
|
+
data.tar.gz: a80648c585519f52a57d58ff9e9292603eda818b09136ad2e3bb749f391b39fd02777305ee75dfec4144f7c67ff1e9fdf5d80d7c3dfddf48ad64cfd9109341ab
|
data/Manifest.txt
CHANGED
@@ -6,4 +6,8 @@ lib/kittypedia.rb
|
|
6
6
|
lib/kittypedia/genome_tables.rb
|
7
7
|
lib/kittypedia/links.rb
|
8
8
|
lib/kittypedia/pages/genes.rb
|
9
|
+
lib/kittypedia/pages/timeline_fancies.rb
|
10
|
+
lib/kittypedia/pages/timeline_purrstiges.rb
|
11
|
+
lib/kittypedia/pages/timeline_traits.rb
|
12
|
+
lib/kittypedia/pages/traits.rb
|
9
13
|
lib/kittypedia/version.rb
|
data/lib/kittypedia.rb
CHANGED
@@ -7,10 +7,13 @@ require 'kittyverse'
|
|
7
7
|
require 'kittypedia/version' # note: let version always go first
|
8
8
|
|
9
9
|
require 'kittypedia/links'
|
10
|
-
require '
|
10
|
+
require 'kittypedia/genome_tables'
|
11
11
|
require 'kittypedia/pages/genes'
|
12
|
+
require 'kittypedia/pages/traits'
|
12
13
|
|
13
|
-
|
14
|
+
require 'kittypedia/pages/timeline_fancies'
|
15
|
+
require 'kittypedia/pages/timeline_purrstiges'
|
16
|
+
require 'kittypedia/pages/timeline_traits'
|
14
17
|
|
15
18
|
|
16
19
|
|
@@ -0,0 +1,379 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class TimelineFanciesPage
|
4
|
+
|
5
|
+
HEADER =<<TXT
|
6
|
+
[2021](#2021) •
|
7
|
+
[2020](#2020) •
|
8
|
+
[2019](#2019) •
|
9
|
+
[2018](#2018) •
|
10
|
+
[2017](#2017)
|
11
|
+
|
12
|
+
# Updates - Fancy / Exclusive / Special Edition Cats - Timeline
|
13
|
+
|
14
|
+
see <https://updates.cryptokitties.co>
|
15
|
+
|
16
|
+
|
17
|
+
TXT
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
###
|
22
|
+
# sort fancies by date - latest first / reverse chronological order
|
23
|
+
FANCY_BY_DATE = begin
|
24
|
+
fancies = []
|
25
|
+
Fancy.each { |fancy| fancies << fancy }
|
26
|
+
## note: sort by recipe date if present?
|
27
|
+
fancies.sort do |l,r|
|
28
|
+
r.date <=> l.date
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def build
|
34
|
+
buf = ""
|
35
|
+
buf << HEADER
|
36
|
+
|
37
|
+
special_editions = Fancy.special_editions
|
38
|
+
exclusives = Fancy.exclusives
|
39
|
+
fancies = Fancy.fancies
|
40
|
+
|
41
|
+
buf << "## Special Edition Cats (#{special_editions.size})"
|
42
|
+
buf << "\n\n"
|
43
|
+
buf << build_fancies( special_editions )
|
44
|
+
buf << "\n\n"
|
45
|
+
buf << build_fancies_media( special_editions )
|
46
|
+
buf << "\n\n"
|
47
|
+
|
48
|
+
buf << "## Exclusive Cats (#{exclusives.size})"
|
49
|
+
buf << "\n\n"
|
50
|
+
buf << build_fancies( exclusives )
|
51
|
+
buf << "\n\n"
|
52
|
+
buf << build_fancies_media( exclusives )
|
53
|
+
buf << "\n\n"
|
54
|
+
|
55
|
+
buf << "## Fancy Cats (#{fancies.size})"
|
56
|
+
buf << "\n\n"
|
57
|
+
buf << build_fancies( fancies )
|
58
|
+
buf << "\n\n"
|
59
|
+
buf << build_fancies_media( fancies )
|
60
|
+
buf << "\n\n"
|
61
|
+
|
62
|
+
##################
|
63
|
+
## step 2 - add fancy cat details / chronic
|
64
|
+
|
65
|
+
month = nil
|
66
|
+
year = nil
|
67
|
+
last_date = nil
|
68
|
+
|
69
|
+
## start of kitties blockchain / genesis
|
70
|
+
genesisdate = Date.new( 2017, 11, 23) ## 2017-11-23
|
71
|
+
|
72
|
+
|
73
|
+
FANCY_BY_DATE.each do |fancy|
|
74
|
+
|
75
|
+
key = fancy.key
|
76
|
+
date = fancy.date
|
77
|
+
|
78
|
+
if year != date.year
|
79
|
+
buf << "\n"
|
80
|
+
buf << "\n"
|
81
|
+
buf << "## #{date.year}"
|
82
|
+
buf << "\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
if month != date.month
|
86
|
+
buf << "\n"
|
87
|
+
buf << "### #{date.strftime( '%B')}"
|
88
|
+
buf << "\n"
|
89
|
+
end
|
90
|
+
|
91
|
+
year = date.year
|
92
|
+
month = date.month
|
93
|
+
|
94
|
+
|
95
|
+
if last_date != date
|
96
|
+
buf << "\n"
|
97
|
+
buf << date.strftime( '%b %-d, %Y')
|
98
|
+
|
99
|
+
day_count = (date.jd - genesisdate.jd)+1
|
100
|
+
buf << " (#{day_count}d)"
|
101
|
+
buf << "\n"
|
102
|
+
end
|
103
|
+
last_date = date
|
104
|
+
|
105
|
+
|
106
|
+
## add anchor name
|
107
|
+
buf << %Q{\n<a name="#{fancy.key}">}
|
108
|
+
buf << "\n\n"
|
109
|
+
|
110
|
+
|
111
|
+
line = ""
|
112
|
+
name = ""
|
113
|
+
|
114
|
+
line << "- "
|
115
|
+
if fancy.special_edition?
|
116
|
+
line << "Special Edition "
|
117
|
+
elsif fancy.exclusive?
|
118
|
+
line << "Exclusive "
|
119
|
+
else
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
name << fancy.name
|
124
|
+
name << " (#{fancy.name_cn})" if fancy.name_cn # add chinese name if present
|
125
|
+
|
126
|
+
line << "[**#{name}**]"
|
127
|
+
line << "(#{kitties_fancy_search_url( fancy )})"
|
128
|
+
|
129
|
+
|
130
|
+
line << " ("
|
131
|
+
line << build_fancy_counter(fancy)
|
132
|
+
|
133
|
+
if fancy.ids
|
134
|
+
id_links = fancy.ids.map { |id| "[##{id}](#{kitties_kitty_url(id)})" }
|
135
|
+
line << " - #{id_links.join(', ')}"
|
136
|
+
end
|
137
|
+
line << ")"
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
if fancy.special_edition?
|
142
|
+
line << " Fancy Cat released"
|
143
|
+
line << " -- #{fancy.desc}" if fancy.desc
|
144
|
+
line << "."
|
145
|
+
line << " #Fancy Cat #Special Edition"
|
146
|
+
elsif fancy.exclusive?
|
147
|
+
line << " Fancy Cat released"
|
148
|
+
line << " -- #{fancy.desc}" if fancy.desc
|
149
|
+
line << "."
|
150
|
+
line << " #Fancy Cat #Exclusive"
|
151
|
+
else
|
152
|
+
line << " Fancy Cat discovered"
|
153
|
+
line << " -- #{fancy.desc}" if fancy.desc
|
154
|
+
line << "."
|
155
|
+
line << " #Fancy Cat"
|
156
|
+
end
|
157
|
+
|
158
|
+
buf << line
|
159
|
+
buf << "\n"
|
160
|
+
|
161
|
+
|
162
|
+
## special case for time-windows special editions
|
163
|
+
if fancy.specialedition? && fancy.time?
|
164
|
+
time_window = build_time_window( fancy )
|
165
|
+
buf << " - #{time_window}"
|
166
|
+
buf << "\n"
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
if fancy.recipe?
|
171
|
+
buf << " - **#{fancy.recipe.traits.size}** traits"
|
172
|
+
buf << " + **#{fancy.recipe.variants.size}** variants" if fancy.recipe.variants
|
173
|
+
|
174
|
+
if fancy.recipe.time? ## time windowed recipe
|
175
|
+
time_window = build_time_window( fancy.recipe )
|
176
|
+
buf << " - #{time_window}"
|
177
|
+
end
|
178
|
+
buf << ":"
|
179
|
+
buf << "\n"
|
180
|
+
|
181
|
+
## traits:
|
182
|
+
fancy.recipe.traits.each do |trait_keys|
|
183
|
+
buf << " - "
|
184
|
+
buf << build_traits( trait_keys )
|
185
|
+
buf << "\n"
|
186
|
+
end
|
187
|
+
|
188
|
+
if fancy.recipe.variants
|
189
|
+
fancy.recipe.variants.each do |variant_key,variant_h|
|
190
|
+
buf << " - **#{variant_h[:name]}** (#{variant_h[:count]}), **#{variant_h[:traits].size}** trait:\n"
|
191
|
+
variant_h[:traits].each do |trait_keys|
|
192
|
+
buf << " - "
|
193
|
+
buf << build_traits( trait_keys )
|
194
|
+
buf << "\n"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
buf << "\n"
|
201
|
+
buf << build_fancy_media( fancy )
|
202
|
+
buf << "\n"
|
203
|
+
end
|
204
|
+
buf
|
205
|
+
|
206
|
+
end # method build
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
def build_time_window( o )
|
211
|
+
buf = ""
|
212
|
+
if o.time_start.year == o.time_end.year
|
213
|
+
buf << o.time_start.strftime( '%b %-d')
|
214
|
+
else # include year
|
215
|
+
buf << o.time_start.strftime( '%b %-d %Y')
|
216
|
+
end
|
217
|
+
|
218
|
+
buf << " - "
|
219
|
+
buf << o.time_end.strftime( '%b %-d %Y')
|
220
|
+
buf << " (#{o.time_days}d)"
|
221
|
+
buf
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
def build_fancy_counter( fancy, show_time: false )
|
226
|
+
buf = ""
|
227
|
+
|
228
|
+
if fancy.recipe?
|
229
|
+
if fancy.recipe.time? ## time windowed recipe
|
230
|
+
if fancy.recipe.time_end >= Date.today
|
231
|
+
buf << "![](#{media_icon_url(:unlocked)})"
|
232
|
+
if fancy.count # add count if present/known
|
233
|
+
buf << "#{fancy.count}+"
|
234
|
+
else
|
235
|
+
buf << "?"
|
236
|
+
end
|
237
|
+
if show_time
|
238
|
+
buf << "/Till: #{fancy.recipe.time_end.strftime( '%b %-d %Y')}"
|
239
|
+
end
|
240
|
+
else
|
241
|
+
buf << "#{fancy.count ? fancy.count : '?'}" # add count if present/known
|
242
|
+
end
|
243
|
+
elsif fancy.recipe &&
|
244
|
+
fancy.recipe.time_start && ## time window BUT unknown end date
|
245
|
+
fancy.recipe.time_end.nil?
|
246
|
+
if fancy.count # add count if present/known
|
247
|
+
buf << "#{fancy.count}+"
|
248
|
+
else
|
249
|
+
buf << "?"
|
250
|
+
end
|
251
|
+
else ## assume limit
|
252
|
+
if fancy.count && fancy.count < fancy.limit
|
253
|
+
buf << "![](#{media_icon_url(:unlocked)})"
|
254
|
+
if fancy.count <= 0
|
255
|
+
buf << '?'
|
256
|
+
else
|
257
|
+
buf << "#{fancy.count}+"
|
258
|
+
end
|
259
|
+
buf << "/#{fancy.limit}" # add limit if present/known
|
260
|
+
else
|
261
|
+
buf << "#{fancy.limit ? fancy.limit : '?'}"
|
262
|
+
buf << "+#{fancy.overflow}" if fancy.overflow?
|
263
|
+
end
|
264
|
+
end
|
265
|
+
else
|
266
|
+
## note: fow now exclusive and specialeditions always have a limit
|
267
|
+
## and do NOT use counts (- use count for (time-windowed) specialeditions - why? why not?)
|
268
|
+
buf << "#{fancy.limit ? fancy.limit : '?'}" # add limit if present/known
|
269
|
+
end
|
270
|
+
buf
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
def build_fancy( fancy )
|
276
|
+
name = ""
|
277
|
+
name << fancy.name
|
278
|
+
name << " (#{fancy.name_cn})" if fancy.name_cn # add chinese name if present
|
279
|
+
|
280
|
+
line = "[**#{name}**]"
|
281
|
+
## line << "(#{kitties_fancy_search_url( fancy )})"
|
282
|
+
line << "(##{fancy.key})"
|
283
|
+
|
284
|
+
line << " ("
|
285
|
+
line << build_fancy_counter( fancy, show_time: true )
|
286
|
+
line << ")"
|
287
|
+
|
288
|
+
line
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
def build_fancies( fancies )
|
294
|
+
buf = ""
|
295
|
+
fancies.each do |fancy|
|
296
|
+
buf << build_fancy( fancy )
|
297
|
+
buf << "\n"
|
298
|
+
end
|
299
|
+
buf
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
def build_fancy_media( fancy )
|
304
|
+
buf = ""
|
305
|
+
if fancy.recipe && fancy.recipe.variants
|
306
|
+
fancy.recipe.variants.each do |variant_key,variant_h|
|
307
|
+
name = "#{fancy.name} #{variant_h[:name]}"
|
308
|
+
|
309
|
+
buf << %Q{![#{name}](#{media_fancy_pic_url( fancy.key, variant_key )} "#{name}")}
|
310
|
+
buf << "\n"
|
311
|
+
end
|
312
|
+
else
|
313
|
+
name = "#{fancy.name}"
|
314
|
+
name << " (#{fancy.name_cn})" if fancy.name_cn
|
315
|
+
|
316
|
+
buf << %Q{![#{name}](#{media_fancy_pic_url( fancy.key )} "#{name}")}
|
317
|
+
buf << "\n"
|
318
|
+
end
|
319
|
+
buf
|
320
|
+
end
|
321
|
+
|
322
|
+
def build_fancies_media( fancies )
|
323
|
+
buf = ""
|
324
|
+
fancies.each do |fancy|
|
325
|
+
buf << build_fancy_media( fancy )
|
326
|
+
end
|
327
|
+
buf
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
def build_trait( key )
|
333
|
+
puts "lookup trait >#{key}<"
|
334
|
+
trait = Trait[ key ]
|
335
|
+
## pp trait
|
336
|
+
if trait.nil?
|
337
|
+
puts "!! ERROR: cannot find trait with key: >#{key}<"
|
338
|
+
exit 1
|
339
|
+
end
|
340
|
+
|
341
|
+
if key =~ /[A-Z]{2}[0-9]{2}/ # if code e.g. WE20 - keep as is
|
342
|
+
line = "**#{key}** #{trait.tier_roman} "
|
343
|
+
|
344
|
+
[line, trait.type.name]
|
345
|
+
else
|
346
|
+
# rec[:name] = name
|
347
|
+
# rec[:kai] = kai
|
348
|
+
# rec[:code] = code
|
349
|
+
# rec[:type] = key ## todo - use trait instead of type (use string not symbol?) - why? why not?
|
350
|
+
|
351
|
+
line = ""
|
352
|
+
line << "**#{trait.name}** #{trait.tier_roman} "
|
353
|
+
line << "("
|
354
|
+
line << trait.code
|
355
|
+
line << ")"
|
356
|
+
|
357
|
+
[line, trait.type.name]
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def build_traits( key_or_keys )
|
362
|
+
pp key_or_keys
|
363
|
+
if key_or_keys.is_a? Array
|
364
|
+
keys = key_or_keys
|
365
|
+
tt = "" ## last trait type (assume all trait types are the same for now)
|
366
|
+
t = keys.map do |key|
|
367
|
+
t, tt = build_trait( key )
|
368
|
+
t
|
369
|
+
end.join(', ')
|
370
|
+
else
|
371
|
+
key = key_or_keys
|
372
|
+
t, tt = build_trait( key )
|
373
|
+
end
|
374
|
+
"#{t} - #{tt}" # trait (t) - trait type (tt)
|
375
|
+
end
|
376
|
+
|
377
|
+
end # class TimelineFanciesPage
|
378
|
+
|
379
|
+
|
@@ -0,0 +1,223 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class TimelinePurrstigesPage
|
4
|
+
|
5
|
+
PRESTIGES_BY_DATE = begin
|
6
|
+
prestiges = []
|
7
|
+
cattributes = TraitType.find_by_key( :prestige ).cattributes
|
8
|
+
cattributes.each { |c| prestiges << c }
|
9
|
+
## note: sort by recipe date if present?
|
10
|
+
prestiges.sort do |l,r|
|
11
|
+
r.recipe.time_start <=> l.recipe.time_start
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
HEADER =<<TXT
|
16
|
+
[2021](#2021) •
|
17
|
+
[2020](#2020) •
|
18
|
+
[2019](#2019) •
|
19
|
+
[2018](#2018)
|
20
|
+
|
21
|
+
# Updates - Purrstige Trait Recipes / Formulas - Timeline
|
22
|
+
|
23
|
+
see <https://updates.cryptokitties.co>
|
24
|
+
|
25
|
+
|
26
|
+
TXT
|
27
|
+
|
28
|
+
|
29
|
+
def build
|
30
|
+
buf = ""
|
31
|
+
buf << HEADER
|
32
|
+
|
33
|
+
buf << "## Purrstige Cattributes (#{PRESTIGES_BY_DATE.size})"
|
34
|
+
buf << "\n\n"
|
35
|
+
buf << "_Special traits for a limited time only bred through a recipe._"
|
36
|
+
buf << "\n\n"
|
37
|
+
buf << build_prestiges()
|
38
|
+
buf << "\n\n\n"
|
39
|
+
|
40
|
+
month = nil
|
41
|
+
year = nil
|
42
|
+
last_date = nil
|
43
|
+
|
44
|
+
## start of kitties blockchain / genesis
|
45
|
+
genesisdate = Date.new( 2017, 11, 23) ## 2017-11-23
|
46
|
+
|
47
|
+
|
48
|
+
## buf << "## Purrstige Cattributes"
|
49
|
+
buf << "\n\n"
|
50
|
+
|
51
|
+
|
52
|
+
PRESTIGES_BY_DATE.each do |c|
|
53
|
+
key = c.key
|
54
|
+
date = c.recipe.time_start
|
55
|
+
|
56
|
+
if year != date.year
|
57
|
+
buf << "\n"
|
58
|
+
buf << "\n"
|
59
|
+
buf << "## #{date.year}"
|
60
|
+
buf << "\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
if month != date.month
|
64
|
+
buf << "\n"
|
65
|
+
buf << "### #{date.strftime( '%B')}"
|
66
|
+
buf << "\n"
|
67
|
+
end
|
68
|
+
|
69
|
+
year = date.year
|
70
|
+
month = date.month
|
71
|
+
|
72
|
+
|
73
|
+
if last_date != date
|
74
|
+
buf << "\n"
|
75
|
+
buf << date.strftime( '%b %-d, %Y')
|
76
|
+
|
77
|
+
day_count = (date.jd - genesisdate.jd)+1
|
78
|
+
buf << " (#{day_count}d)"
|
79
|
+
buf << "\n\n"
|
80
|
+
end
|
81
|
+
last_date = date
|
82
|
+
|
83
|
+
|
84
|
+
## add anchor name
|
85
|
+
buf << %Q{\n<a name="#{c.key}">}
|
86
|
+
buf << "\n\n"
|
87
|
+
|
88
|
+
|
89
|
+
name = ""
|
90
|
+
name << c.name
|
91
|
+
|
92
|
+
buf << "[**#{name}**]"
|
93
|
+
buf << "(#{kitties_search_url( key )}) "
|
94
|
+
|
95
|
+
buf << " (#{build_prestige_counter(c)})" # add count(er)
|
96
|
+
buf << ", "
|
97
|
+
|
98
|
+
time_window = build_time_window( c.recipe )
|
99
|
+
buf << "#{time_window}"
|
100
|
+
buf << ", "
|
101
|
+
|
102
|
+
|
103
|
+
buf << " **#{c.recipe.traits.size}** traits:"
|
104
|
+
buf << "\n"
|
105
|
+
|
106
|
+
## traits:
|
107
|
+
c.recipe.traits.each do |trait_keys|
|
108
|
+
buf << "- "
|
109
|
+
buf << build_traits( trait_keys )
|
110
|
+
buf << "\n"
|
111
|
+
end
|
112
|
+
|
113
|
+
buf << "\n\n"
|
114
|
+
end
|
115
|
+
|
116
|
+
buf
|
117
|
+
end # method build
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
def build_time_window( o )
|
123
|
+
buf = ""
|
124
|
+
|
125
|
+
if o.time_start && o.time_end ## note: make sure start & end date present!!!
|
126
|
+
if o.time_start.year == o.time_end.year
|
127
|
+
buf << o.time_start.strftime( '%b %-d')
|
128
|
+
else # include year
|
129
|
+
buf << o.time_start.strftime( '%b %-d %Y')
|
130
|
+
end
|
131
|
+
|
132
|
+
buf << " - "
|
133
|
+
buf << o.time_end.strftime( '%b %-d %Y')
|
134
|
+
buf << " (#{o.time_days}d)"
|
135
|
+
end
|
136
|
+
|
137
|
+
buf
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def build_prestige_counter( prestige, show_time: false )
|
142
|
+
buf = ""
|
143
|
+
|
144
|
+
if prestige.recipe.time_end && prestige.recipe.time_end >= Date.today
|
145
|
+
buf << "![](#{media_icon_url(:unlocked)})"
|
146
|
+
if prestige.count # add count if present/known
|
147
|
+
buf << "#{prestige.count}+"
|
148
|
+
else
|
149
|
+
buf << "?"
|
150
|
+
end
|
151
|
+
if show_time
|
152
|
+
buf << "/Till: #{prestige.recipe.time_end.strftime( '%b %-d %Y')}"
|
153
|
+
end
|
154
|
+
else
|
155
|
+
buf << "#{prestige.count ? prestige.count : '?'}" # add count if present/known
|
156
|
+
end
|
157
|
+
buf
|
158
|
+
end
|
159
|
+
|
160
|
+
def build_prestige( c )
|
161
|
+
name = ""
|
162
|
+
name << c.name
|
163
|
+
|
164
|
+
line = "[**#{name}**](##{c.key})"
|
165
|
+
|
166
|
+
line << " (#{build_prestige_counter(c, show_time: true)})" # add count(er)
|
167
|
+
line
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
def build_prestiges
|
173
|
+
buf = ""
|
174
|
+
PRESTIGES_BY_DATE.each do |c|
|
175
|
+
buf << build_prestige( c )
|
176
|
+
buf << "\n"
|
177
|
+
end
|
178
|
+
buf
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
def build_trait( key )
|
183
|
+
puts "lookup trait >#{key}<"
|
184
|
+
trait = Trait[ key ]
|
185
|
+
## pp trait
|
186
|
+
|
187
|
+
if key =~ /[A-Z]{2}[0-9]{2}/ # if code e.g. WE20 - keep as is
|
188
|
+
line = "**#{key}** #{trait.tier_roman} "
|
189
|
+
|
190
|
+
[line, trait.type.name]
|
191
|
+
else
|
192
|
+
# rec[:name] = name
|
193
|
+
# rec[:kai] = kai
|
194
|
+
# rec[:code] = code
|
195
|
+
# rec[:type] = key ## todo - use trait instead of type (use string not symbol?) - why? why not?
|
196
|
+
|
197
|
+
line = ""
|
198
|
+
line << "**#{trait.name}** #{trait.tier_roman} "
|
199
|
+
line << "("
|
200
|
+
line << trait.code
|
201
|
+
line << ")"
|
202
|
+
|
203
|
+
[line, trait.type.name]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def build_traits( key_or_keys )
|
208
|
+
if key_or_keys.is_a? Array
|
209
|
+
keys = key_or_keys
|
210
|
+
tt = "" ## last trait type (assume all trait types are the same for now)
|
211
|
+
t = keys.map do |key|
|
212
|
+
t, tt = build_trait( key )
|
213
|
+
t
|
214
|
+
end.join(', ')
|
215
|
+
else
|
216
|
+
key = key_or_keys
|
217
|
+
t, tt = build_trait( key )
|
218
|
+
end
|
219
|
+
"#{t} - #{tt}" # trait (t) - trait type (tt)
|
220
|
+
end
|
221
|
+
|
222
|
+
end # class TimelinePurrstigesPage
|
223
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class TimelineTraitsPage
|
4
|
+
|
5
|
+
HEADER = <<TXT
|
6
|
+
# Updates - Traits / Cattributes / Mewtations - Timeline
|
7
|
+
|
8
|
+
see <https://updates.cryptokitties.co>
|
9
|
+
|
10
|
+
TXT
|
11
|
+
|
12
|
+
|
13
|
+
def build
|
14
|
+
## check traits if all known
|
15
|
+
TRAITS_TIMELINE.each do |key,h|
|
16
|
+
|
17
|
+
## double check traits if present / known / defined
|
18
|
+
trait = Trait.find_by_name( key.to_s )
|
19
|
+
if trait.nil?
|
20
|
+
puts "unknown / undefined trait #{key}:"
|
21
|
+
pp h
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
buf = ""
|
28
|
+
buf << HEADER
|
29
|
+
|
30
|
+
|
31
|
+
month = nil
|
32
|
+
year = nil
|
33
|
+
last_date = nil
|
34
|
+
|
35
|
+
## start of kitties blockchain / genesis
|
36
|
+
genesisdate = Date.new( 2017, 11, 23) ## 2017-11-23
|
37
|
+
|
38
|
+
|
39
|
+
TRAITS_TIMELINE.each do |key,h|
|
40
|
+
date = Date.strptime( h[:date], '%Y-%m-%d' )
|
41
|
+
|
42
|
+
if year != date.year
|
43
|
+
buf << "\n"
|
44
|
+
buf << "\n"
|
45
|
+
buf << "## #{date.year}"
|
46
|
+
buf << "\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
if month != date.month
|
50
|
+
buf << "\n"
|
51
|
+
buf << "### #{date.strftime( '%B')}"
|
52
|
+
buf << "\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
year = date.year
|
56
|
+
month = date.month
|
57
|
+
|
58
|
+
|
59
|
+
if last_date != date
|
60
|
+
buf << "\n"
|
61
|
+
buf << date.strftime( '%b %-d, %Y')
|
62
|
+
|
63
|
+
day_count = (date.to_date.jd - genesisdate.jd)+1
|
64
|
+
buf << " (#{day_count}d)"
|
65
|
+
buf << "\n"
|
66
|
+
end
|
67
|
+
last_date = date
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
trait = Trait.find_by_name( key.to_s )
|
72
|
+
trait_type = trait.type
|
73
|
+
|
74
|
+
kai = trait.kai
|
75
|
+
tier = trait.tier # 0,1,2,3,4,nil
|
76
|
+
tier_roman = trait.tier_roman
|
77
|
+
|
78
|
+
|
79
|
+
line = ""
|
80
|
+
name = "#{key}" ## todo/fix: upcase first letter - why? why not?
|
81
|
+
|
82
|
+
line << "- "
|
83
|
+
line << "[**#{name}**](#{kitties_search_url(name)}) #{tier_roman} "
|
84
|
+
|
85
|
+
line << " - #{trait_type.name.downcase} "
|
86
|
+
|
87
|
+
pair = MUTATION_PAIR[kai]
|
88
|
+
|
89
|
+
kai_pair = "#{kai}"
|
90
|
+
kai_pair << " = #{pair}" unless pair.empty?
|
91
|
+
|
92
|
+
line << "(#{trait.code} / #{kai_pair}) "
|
93
|
+
|
94
|
+
line << "trait discovered. #Cattribute"
|
95
|
+
line << " #Mewtation" if tier && tier > 0
|
96
|
+
|
97
|
+
|
98
|
+
buf << line
|
99
|
+
buf << "\n"
|
100
|
+
end
|
101
|
+
buf
|
102
|
+
end # method build
|
103
|
+
|
104
|
+
end # class TimelineTraitsPage
|
105
|
+
|
106
|
+
|
107
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
|
2
|
+
class TraitsPage
|
3
|
+
|
4
|
+
|
5
|
+
def build_part( offset, length )
|
6
|
+
buf = ""
|
7
|
+
buf << "| Tier | Kai |"
|
8
|
+
TraitType[offset, length].each do |tt|
|
9
|
+
buf << " #{tt.name} (#{tt.code}) |"
|
10
|
+
end
|
11
|
+
buf << "\n"
|
12
|
+
buf << "|----|----|"
|
13
|
+
buf << "----|" * length
|
14
|
+
buf << "\n"
|
15
|
+
|
16
|
+
buf << "| | |"
|
17
|
+
TraitType[offset, length].each do |tt|
|
18
|
+
buf << " #{tt.genes} |"
|
19
|
+
end
|
20
|
+
buf << "\n"
|
21
|
+
|
22
|
+
## note: skip unknown trait 31/x for now (e.g. use 0..30 and NOT 0..31)
|
23
|
+
(0..30).each do |i|
|
24
|
+
kai = Kai::ALPHABET[i]
|
25
|
+
tier = MUTATION_TIER_ROMAN[kai]
|
26
|
+
buf << "| #{tier} | #{kai} |"
|
27
|
+
TraitType[offset, length].each do |tt|
|
28
|
+
t = tt.traits[i]
|
29
|
+
if t.name
|
30
|
+
|
31
|
+
search_url = if TOTESBASIC.include?( t.name )
|
32
|
+
kitties_search_url( 'totesbasic' )
|
33
|
+
else
|
34
|
+
kitties_search_url( t.name.downcase )
|
35
|
+
end
|
36
|
+
buf << "[**#{t.name}**](#{search_url}) (#{t.code})"
|
37
|
+
else
|
38
|
+
buf << "#{t.code}"
|
39
|
+
end
|
40
|
+
buf << " |"
|
41
|
+
end
|
42
|
+
buf << "\n"
|
43
|
+
end
|
44
|
+
buf << "\n\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def build
|
49
|
+
buf = ""
|
50
|
+
buf << "# Traits\n\n"
|
51
|
+
|
52
|
+
## split in three parts
|
53
|
+
buf << build_part( 0, 3 )
|
54
|
+
buf << build_part( 3, 3 )
|
55
|
+
buf << build_part( 6, 3 )
|
56
|
+
buf << build_part( 9, 3 )
|
57
|
+
|
58
|
+
buf += <<TXT
|
59
|
+
## Mutations / Mewtations
|
60
|
+
|
61
|
+
16 Mutation Pairs (16 x 2 = 32)
|
62
|
+
|
63
|
+
```
|
64
|
+
Base Tier I Tier II Tier III Tier IIII
|
65
|
+
(1-g) (h-p) (q-t) (u,v) (w)
|
66
|
+
h = 1+2 q = h+i u = q+r w = u+v
|
67
|
+
i = 3+4 r = j+k v = s+t
|
68
|
+
j = 5+6 s = m+n
|
69
|
+
k = 7+8 t = o+p
|
70
|
+
m = 9+a
|
71
|
+
n = b+c
|
72
|
+
o = d+e
|
73
|
+
p = f+g
|
74
|
+
```
|
75
|
+
|
76
|
+
Note: It's impossible for a mutation to reach `x` e.g. `w+x = x`.
|
77
|
+
|
78
|
+
|
79
|
+
## Kai (Base32) Notation
|
80
|
+
|
81
|
+
|Kai |Binary |Num|Kai |Binary |Num|Kai |Binary |Num|Kai |Binary |Num|
|
82
|
+
|-------|-------|---|-------|-------|---|-------|-------|---|-------|-------|---|
|
83
|
+
| **1** | 00000 | 0 | **9** | 01000 | 8 | **h** | 10000 |16 | **q** | 11000 |24 |
|
84
|
+
| **2** | 00001 | 1 | **a** | 01001 | 9 | **i** | 10001 |17 | **r** | 11001 |25 |
|
85
|
+
| **3** | 00010 | 2 | **b** | 01010 | 10| **j** | 10010 |18 | **s** | 11010 |26 |
|
86
|
+
| **4** | 00011 | 3 | **c** | 01011 | 11| **k** | 10011 |19 | **t** | 11011 |27 |
|
87
|
+
| **5** | 00100 | 4 | **d** | 01100 | 12| **m** | 10100 |20 | **u** | 11100 |28 |
|
88
|
+
| **6** | 00101 | 5 | **e** | 01101 | 13| **n** | 10101 |21 | **v** | 11101 |29 |
|
89
|
+
| **7** | 00110 | 6 | **f** | 01110 | 14| **o** | 10110 |22 | **w** | 11110 |30 |
|
90
|
+
| **8** | 00111 | 7 | **g** | 01111 | 15| **p** | 10111 |23 | **x** | 11111 |31 |
|
91
|
+
|
92
|
+
Note: The digit-0 and the letter-l are NOT used in kai.
|
93
|
+
|
94
|
+
TXT
|
95
|
+
|
96
|
+
|
97
|
+
puts buf
|
98
|
+
|
99
|
+
buf
|
100
|
+
end ## method build
|
101
|
+
|
102
|
+
|
103
|
+
def save( path )
|
104
|
+
File.open( path, "w:utf-8" ) do |f|
|
105
|
+
f.write build
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end # class TraitsPage
|
data/lib/kittypedia/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kittypedia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kittyverse
|
@@ -76,6 +76,10 @@ files:
|
|
76
76
|
- lib/kittypedia/genome_tables.rb
|
77
77
|
- lib/kittypedia/links.rb
|
78
78
|
- lib/kittypedia/pages/genes.rb
|
79
|
+
- lib/kittypedia/pages/timeline_fancies.rb
|
80
|
+
- lib/kittypedia/pages/timeline_purrstiges.rb
|
81
|
+
- lib/kittypedia/pages/timeline_traits.rb
|
82
|
+
- lib/kittypedia/pages/traits.rb
|
79
83
|
- lib/kittypedia/version.rb
|
80
84
|
homepage: https://github.com/cryptocopycats/kittyverse
|
81
85
|
licenses:
|