kittypedia 0.0.1 → 0.1.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/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 << "})"
|
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 << "})"
|
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}")}
|
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}")}
|
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 << "})"
|
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:
|