-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscrape.applescript
More file actions
executable file
·511 lines (460 loc) · 17.2 KB
/
Copy pathscrape.applescript
File metadata and controls
executable file
·511 lines (460 loc) · 17.2 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
-- database
set databaseFile to "/Users/balupton/Projects/coda/stepn/scrape.json"
-- stuff
-- set debug=yes
set clickDelay to 0.8
set refreshDelay to 5
-- networks
set networks to {"solana", "binance"}
-- settings
set settingsXY to {128.9654375530969, 156.965437553097} -- open settings
set networkXY to {244.2091454272864, 348.3103699233757} -- select network
set networkSolanaXY to {244.2091454272864, 558.8694413626927} -- solana
set networkBinanceXY to {244.2091454272864, 609.4113199900294} -- binance
set confirmSettingsXY to {122.6889055472264, 162.6101949025488} -- close settings
-- shop
set shopXY to {340.8292728635682, 604.9889296684665}
set shopSneakersXY to {158.8373313343328, 194.2400645323241}
set shopGemsXY to {244.2091454272864, 194.2400645323241}
set shopOtherXY to {329.5809595202398, 194.2400645323241}
set filterXY to {333.0419790104947, 224.8810722888677}
set clearFilterXY to {350.3470764617691, 157.281323414335}
set confirmFilterXY to {273.0509745127436, 608.1478000166176}
set filterSneakersXY to {226.904047976012, 214.8139026132837}
set filterShoeboxesXY to {319.1979010494753, 214.8139026132837}
set filterScrollsXY to {219.2128935532234, 214.8139026132837}
-- shop gems
set efficiencyXY to {226.904047976012, 214.8139026132837}
set luckXY to {319.1979010494753, 214.8139026132837}
set comfortXY to {226.904047976012, 240.0848389930097}
set resilienceXY to {319.1979010494753, 240.0848389930097}
set gemAttributes to {"efficiency", "luck", "comfort", "resilience"}
set gemLevels to {1, 2, 3, 4, 5} -- , 6, 7, 8, 9}
-- shop sneakers
set walkerXY to {226.904047976012, 272.0306032858509}
set joggerXY to {319.1979010494753, 272.0306032858509}
set runnerXY to {226.904047976012, 297.3015425995193}
set trainerXY to {319.1979010494753, 297.3015425995193}
set shoeCategories to {"walker", "jogger", "runner", "trainer"}
set shoeCommonXY to {226.904047976012, 354.5182286023737}
set shoeUncommonXY to {319.1979010494753, 354.5182286023737}
set shoeRareXY to {226.904047976012, 379.7891679160421}
set shoeEpicXY to {319.1979010494753, 379.7891679160421}
set shoeLegendaryXY to {226.904047976012, 405.0601072297104}
set shoeQualities to {"common", "uncommon", "rare", "epic", "legendary"}
-- shop shoeboxes
set shoeboxCommonXY to {226.904047976012, 272.0306032858509}
set shoeboxUncommonXY to {319.1979010494753, 272.0306032858509}
set shoeboxRareXY to {226.904047976012, 297.3015425995193}
set shoeboxEpicXY to {319.1979010494753, 297.3015425995193}
set shoeboxLegendaryXY to {226.904047976012, 322.5724701774175}
set shoeboxQualities to {"common", "uncommon", "rare", "epic", "legendary"}
-- shop other / minting scrolls
set scrollCommonXY to {226.904047976012, 272.0306032858509}
set scrollUncommonXY to {319.1979010494753, 272.0306032858509}
set scrollRareXY to {226.904047976012, 297.3015425995193}
set scrollEpicXY to {319.1979010494753, 297.3015425995193}
set scrollLegendaryXY to {226.904047976012, 322.5724701774175}
set scrollQualities to {"common", "uncommon", "rare", "epic", "legendary"}
on getApp()
tell application "System Events"
tell process "STEPN"
activate
delay 3
set theWindow to window 1
perform action "AXRaise" of theWindow
delay 3
set position of theWindow to {100, 100}
delay 3
return theWindow
end tell
end tell
end getApp
on selectNetwork(theApp, theNetwork)
tell application "System Events"
click at my settingsXY
delay my clickDelay
click at my networkXY
delay my clickDelay
if (theNetwork as string) is equal to "solana" then
click at my networkSolanaXY
else if (theNetwork as string) is equal to "binance" then
click at my networkBinanceXY
else
tell me to error ("invalid network: " & theNetwork)
end if
delay my clickDelay
click at my confirmSettingsXY
delay my clickDelay
end tell
end selectNetwork
on shopGems(theApp, theGemAttribute, theGemLevel)
tell application "System Events"
if theGemAttribute is not null and theGemLevel is not null then
tell me to error ("invalid gem attribute and level: " & theGemAttribute & " and " & theGemLevel & " only one can be set at a time")
else if theGemAttribute is null and theGemLevel is null then
-- shop gems
click at my shopXY
delay my clickDelay
click at my shopGemsXY
delay my clickDelay
-- reset gem filter
click at my filterXY
delay my clickDelay
click at my clearFilterXY
delay my refreshDelay
else
-- select gem filter
click at my filterXY
delay my clickDelay
-- set the gem filter
if theGemAttribute is not null then
if (theGemAttribute as string) is equal to "efficiency" then
click at my efficiencyXY
else if (theGemAttribute as string) is equal to "luck" then
click at my luckXY
else if (theGemAttribute as string) is equal to "comfort" then
click at my comfortXY
else if (theGemAttribute as string) is equal to "resilience" then
click at my resilienceXY
else
tell me to error ("invalid gem attribute: " & theGemAttribute)
end if
else if theGemLevel is not null then
set theMaxSlider to my getMaxSlider(theApp)
set theMinSlider to my getMinSlider(theApp)
-- work around a bug
my incrementSlider(theMaxSlider)
my incrementSlider(theMaxSlider)
delay my clickDelay
my setSlider(theMinSlider, theGemLevel)
my setSlider(theMaxSlider, theGemLevel)
else
tell me to error ("invalid state")
end if
-- confirm the gem filter
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
end if
end tell
end shopGems
on shopSneakers(theApp, theShoeCategory, theShoeQuality)
tell application "System Events"
if theShoeCategory is not null and theShoeQuality is not null then
tell me to error ("invalid shoe category and quality: " & theShoeCategory & " and " & theShoeQuality & " only one can be set at a time")
else if theShoeCategory is null and theShoeQuality is null then
-- shop sneakers
click at my shopXY
delay my clickDelay
click at my shopSneakersXY
delay my clickDelay
-- reset shoe filter
click at my filterXY
delay my clickDelay
click at my clearFilterXY
delay my refreshDelay
click at my filterXY
delay my clickDelay
click at my filterSneakersXY
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
else
-- select shoe filter
click at my filterXY
delay my clickDelay
-- set the shoe filter
if theShoeCategory is not null then
-- click at (get theShoeCategory of my categoryXYs)
if (theShoeCategory as string) is equal to "walker" then
click at my walkerXY
else if (theShoeCategory as string) is equal to "jogger" then
click at my joggerXY
else if (theShoeCategory as string) is equal to "runner" then
click at my runnerXY
else if (theShoeCategory as string) is equal to "trainer" then
click at my trainerXY
else
tell me to error ("invalid shoe category: " & theShoeCategory)
end if
else if theShoeQuality is not null then
if (theShoeQuality as string) is equal to "common" then
click at my shoeCommonXY
else if (theShoeQuality as string) is equal to "uncommon" then
click at my shoeUncommonXY
else if (theShoeQuality as string) is equal to "rare" then
click at my shoeRareXY
else if (theShoeQuality as string) is equal to "epic" then
click at my shoeEpicXY
else if (theShoeQuality as string) is equal to "legendary" then
click at my shoeLegendaryXY
else
tell me to error ("invalid shoe quality: " & theShoeQuality)
end if
else
tell me to error ("invalid state")
end if
-- confirm the shoe filter
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
end if
end tell
end shopSneakers
on shopShoeboxes(theApp, theShoeboxQuality)
tell application "System Events"
if theShoeboxQuality is null then
-- shop sneakers
click at my shopXY
delay my clickDelay
click at my shopSneakersXY
delay my clickDelay
-- reset shoebox filter
click at my filterXY
delay my clickDelay
click at my clearFilterXY
delay my refreshDelay
click at my filterXY
delay my clickDelay
click at my filterShoeboxesXY
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
else
-- select shoe filter
click at my filterXY
delay my clickDelay
-- set the shoebox filter
if theShoeboxQuality is not null then
if (theShoeboxQuality as string) is equal to "common" then
click at my shoeboxCommonXY
else if (theShoeboxQuality as string) is equal to "uncommon" then
click at my shoeboxUncommonXY
else if (theShoeboxQuality as string) is equal to "rare" then
click at my shoeboxRareXY
else if (theShoeboxQuality as string) is equal to "epic" then
click at my shoeboxEpicXY
else if (theShoeboxQuality as string) is equal to "legendary" then
click at my shoeboxLegendaryXY
else
tell me to error ("invalid shoebox quality: " & theShoeboxQuality)
end if
else
tell me to error ("invalid state")
end if
-- confirm the shoe filter
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
end if
end tell
end shopShoeboxes
on shopScrolls(theApp, theScrollQuality)
tell application "System Events"
if theScrollQuality is null then
-- shop other
click at my shopXY
delay my clickDelay
click at my shopOtherXY
delay my clickDelay
-- reset shoebox filter
click at my filterXY
delay my clickDelay
click at my clearFilterXY
delay my refreshDelay
click at my filterXY
delay my clickDelay
click at my filterScrollsXY
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
else
-- select filter
click at my filterXY
delay my clickDelay
-- set the scroll filter
if theScrollQuality is not null then
if (theScrollQuality as string) is equal to "common" then
click at my scrollCommonXY
else if (theScrollQuality as string) is equal to "uncommon" then
click at my scrollUncommonXY
else if (theScrollQuality as string) is equal to "rare" then
click at my scrollRareXY
else if (theScrollQuality as string) is equal to "epic" then
click at my scrollEpicXY
else if (theScrollQuality as string) is equal to "legendary" then
click at my scrollLegendaryXY
else
tell me to error ("invalid scroll quality: " & theScrollQuality)
end if
else
tell me to error ("invalid state")
end if
-- confirm the shoe filter
delay my clickDelay
click at my confirmFilterXY
delay my refreshDelay
end if
end tell
end shopScrolls
on getElementsByClass(theApp, theClass)
set matchedElements to {}
tell application "System Events"
repeat with anElement in (entire contents of theApp) as list
if (class of anElement as string) is (theClass as string) then
set end of matchedElements to contents of anElement
end if
end repeat
end tell
return matchedElements
end getElementsByClass
on getElementsByContents(theApp, theContents)
set matchedElements to {}
tell application "System Events"
repeat with anElement in (entire contents of theApp) as list
if description of anElement contains (theContents as string) then
set end of matchedElements to contents of anElement
end if
end repeat
end tell
return matchedElements
end getElementsByContents
on getGemDetails(theApp)
tell application "System Events"
try
return get description of image 1 of group 1 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 3 of group 2 of group 2 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of theApp
end try
return null
end tell
end getGemDetails
on getShoeDetails(theApp)
tell application "System Events"
try
return get description of UI element 1 of group 1 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 3 of group 2 of group 2 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of theApp
end try
return null
end tell
end getShoeDetails
on getShoeboxDetails(theApp)
tell application "System Events"
try
return get description of UI element 1 of group 1 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 3 of group 2 of group 2 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of theApp
end try
return null
end tell
end getShoeboxDetails
on getScrollDetails(theApp)
tell application "System Events"
try
return get description of UI element 1 of group 1 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 2 of group 3 of group 2 of group 2 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of theApp
end try
return null
end tell
end getScrollDetails
on getMinSlider(theApp)
tell application "System Events"
-- return item 1 of my getElementsByClass(theApp, "slider")
return slider 1 of group 1 of group 2 of group 2 of group 2 of group 2 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of theApp
end tell
end getMinSlider
on getMaxSlider(theApp)
tell application "System Events"
-- return item 2 of my getElementsByClass(theApp, "slider")
return slider 2 of group 1 of group 2 of group 2 of group 2 of group 2 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of group 1 of theApp
end tell
end getMaxSlider
on readSlider(theSlider)
tell application "System Events"
return get description of theSlider
end tell
end readSlider
on decrementSlider(theSlider)
tell application "System Events"
perform action "AXDecrement" of theSlider
end tell
end decrementSlider
on incrementSlider(theSlider)
tell application "System Events"
perform action "AXIncrement" of theSlider
end tell
end incrementSlider
on setSlider(theSlider, theValue)
tell application "System Events"
set currentValue to my readSlider(theSlider)
set originalValue to currentValue
repeat while (currentValue as integer) is not equal to (theValue as integer)
if (currentValue as integer) < (theValue as integer) then
perform action "AXIncrement" of theSlider
else
perform action "AXDecrement" of theSlider
end if
set nextValue to my readSlider(theSlider)
if (nextValue as integer) is equal to (currentValue as integer) then
tell me to error ("failed to set slider to " & theValue & " from " & currentValue)
end if
set currentValue to nextValue
end repeat
if (currentValue as integer) is not equal to (originalValue as integer) then
delay my clickDelay
return "changed"
else
return "same"
end if
end tell
end setSlider
-- open
try
tell application "STEPN"
quit
end tell
end try
tell application "STEPN"
activate
end tell
tell application "System Events"
set theApp to my getApp()
-- return
-- log my getShoeDetails(theApp)
-- log my getElementsByContents(theApp, "SOL")
-- return
repeat with theNetwork in my networks
my selectNetwork(theApp, theNetwork)
my shopScrolls(theApp, null)
repeat with theScrollQuality in my scrollQualities
my shopScrolls(theApp, theScrollQuality)
set theDetails to my getScrollDetails(theApp)
do shell script "jq --arg network '" & theNetwork & "' --arg quality '" & theScrollQuality & "' --arg details '" & theDetails & "' '.scrolls += [{network: $network, quality: $quality, details: $details}]' " & (my databaseFile) & " | sponge " & (my databaseFile)
end repeat
my shopShoeboxes(theApp, null)
repeat with theShoeboxQuality in my shoeboxQualities
my shopShoeboxes(theApp, theShoeboxQuality)
set theDetails to my getShoeboxDetails(theApp)
do shell script "jq --arg network '" & theNetwork & "' --arg quality '" & theShoeboxQuality & "' --arg details '" & theDetails & "' '.shoeboxes += [{network: $network, quality: $quality, details: $details}]' " & (my databaseFile) & " | sponge " & (my databaseFile)
end repeat
my shopSneakers(theApp, null, null)
repeat with theShoeCategory in my shoeCategories
my shopSneakers(theApp, theShoeCategory, null)
repeat with theShoeQuality in my shoeQualities
my shopSneakers(theApp, null, theShoeQuality)
set theDetails to my getShoeDetails(theApp)
do shell script "jq --arg network '" & theNetwork & "' --arg category '" & theShoeCategory & "' --arg quality '" & theShoeQuality & "' --arg details '" & theDetails & "' '.shoes += [{network: $network, category: $category, quality: $quality, details: $details}]' " & (my databaseFile) & " | sponge " & (my databaseFile)
end repeat
end repeat
my shopGems(theApp, null, null)
repeat with theGemAttribute in my gemAttributes
my shopGems(theApp, theGemAttribute, null)
repeat with theGemLevel in my gemLevels
my shopGems(theApp, null, theGemLevel)
set theDetails to my getGemDetails(theApp)
do shell script "jq --arg network '" & theNetwork & "' --arg attribute '" & theGemAttribute & "' --arg level '" & theGemLevel & "' --arg details '" & theDetails & "' '.gems += [{network: $network, attribute: $attribute, level: $level, details: $details}]' " & (my databaseFile) & " | sponge " & (my databaseFile)
end repeat
end repeat
end repeat
-- minimise
-- perform action "AXPress" of button 3 of theApp
end tell
-- close
tell application "STEPN"
quit
end tell