This repository has been archived by the owner on Oct 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcb.py
758 lines (624 loc) Β· 31.9 KB
/
cb.py
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
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
#!/usr/bin/env python3.9 -m nuitka
# -*- coding: utf-8 -*-
import browser_cookie3
import requests
import configparser
import json
import os
import sys
import time
from datetime import datetime
import telepot
import unicodedata
import urllib3
import re
import keyboard
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
from pygame import mixer
urllib3.disable_warnings()
# DEPRECATED (~21.08.19)
# jar = browser_cookie3.chrome(domain_name=".kakao.com")
jar = {}
vaccine_candidates = [
{"name": "μ무거λ", "code": "ANY"},
{"name": "νμ΄μ", "code": "VEN00013"},
{"name": "λͺ¨λλ", "code": "VEN00014"},
{"name": "μμ€νΈλΌμ λ€μΉ΄", "code": "VEN00015"},
{"name": "μμΌ", "code": "VEN00016"},
{"name": "(μμ½λΆκ°)λ
Έλ°λ°±μ€", "code": "VEN00017"},
{"name": "(μμ½λΆκ°)μλ
Έν", "code": "VEN00018"},
{"name": "(μμ½λΆκ°)μλ
Έλ°±", "code": "VEN00019"},
{"name": "(μμ½λΆκ°)μ€νΈνΈλν¬V", "code": "VEN00020"},
]
# κΈ°μ‘΄ μ
λ ₯ κ° λ‘λ©
def load_config():
config_parser = configparser.ConfigParser()
if os.path.exists('config.ini'):
try:
config_parser.read('config.ini')
try:
# μ€μ νμΌμ΄ μμΌλ©΄ μ΅κ·Ό λ‘κ·ΈμΈ μ 보 λ‘λ©
configuration = config_parser['config']
previous_used_type = configuration["VAC"]
previous_top_x = configuration["topX"]
previous_top_y = configuration["topY"]
previous_bottom_x = configuration["botX"]
previous_bottom_y = configuration["botY"]
previous_only_left = configuration["onlyLeft"] == "True"
except KeyError:
print('ERROR: config.iniκ° μμλμμ΅λλ€. νμΌμ μμ νκ±°λ μμ ν λ€μ μ€μ ν΄μ£ΌμΈμ.')
close()
print("\n[νμ¬ μ€μ ]")
print(f"λ°±μ μ’
λ₯: {previous_used_type} ({next(x['name'] for x in vaccine_candidates if x['code'] == previous_used_type)})")
print("top_x:", previous_top_x)
print("top_y:", previous_top_y)
print("bottom_x:", previous_bottom_x)
print("bottom_y:", previous_bottom_y)
print(f"only_left: {previous_only_left} ({'μμ¬λ°±μ μ΄ μλ λ³μλ§ μ‘°ν' if previous_only_left else 'λͺ¨λ λ³μ μ‘°ν'})")
while True:
skip_input = str.lower(input("κΈ°μ‘΄μ μ
λ ₯ν μ λ³΄λ‘ μ¬κ²μνμκ² μ΅λκΉ? Y/N : "))
if skip_input == "y":
skip_input = True
break
elif skip_input == "n":
skip_input = False
break
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
if skip_input:
return previous_used_type, previous_top_x, previous_top_y, previous_bottom_x, previous_bottom_y, previous_only_left
except ValueError:
return None, None, None, None, None, None
return None, None, None, None, None, None
def check_user_info_loaded():
user_info_api = 'https://vaccine.kakao.com/api/v1/user'
user_info_response = requests.get(
user_info_api, headers=Headers.headers_vacc, cookies=jar, verify=False)
user_info_json = json.loads(user_info_response.text)
if user_info_json.get('error'):
print("μ¬μ©μ μ 보λ₯Ό λΆλ¬μ€λλ° μ€ν¨νμμ΅λλ€.")
print("Chrome λΈλΌμ°μ μμ μΉ΄μΉ΄μ€μ μ λλ‘ λ‘κ·ΈμΈλμ΄μλμ§ νμΈν΄μ£ΌμΈμ.")
print("λ‘κ·ΈμΈμ΄ λμ΄ μλλ°λ μλλ€λ©΄, μΉ΄μΉ΄μ€ν‘μ λ€μ΄κ°μ μμ¬λ°±μ μλ¦Ό μ μ²μ νλ² ν΄λ³΄μΈμ. μ 보μ 곡 λμκ° λμ¨λ€λ©΄ λμ ν λ€μ μλν΄μ£ΌμΈμ.")
close()
else:
user_info = user_info_json.get("user")
if user_info['status'] == "NORMAL":
print(f"[{user_info['name']}]λμ μ¬μ©μ μ 보λ₯Ό λΆλ¬μ€λλ° μ±κ³΅νμ΅λλ€.")
elif user_info['status'] == "UNKNOWN":
print(f"[{user_info['name']}]λμ νμ¬ μνλ₯Ό μ μ μλ μ¬μ©μμ
λλ€. 1339 λλ 보건μμ λ¬Έμν΄μ£ΌμΈμ.")
close()
elif user_info['status'] == "REFUSED":
print(f"[{user_info['name']}]λμ λ°±μ μ μμ½νκ³ λ°©λ¬Ένμ§ μμ μ¬μ©μμ
λλ€. μμ¬λ°±μ μμ½μ΄ λΆκ°ν©λλ€.")
close()
elif user_info['status'] == "ALREADY_RESERVED" or user_info['status'] == "ALREADY_VACCINATED":
print(f"[{user_info['name']}]λμ μ΄λ―Έ μ μ’
μ΄ μλ£λμκ±°λ μμ½μ΄ μλ£λ μ¬μ©μμ
λλ€.")
close()
else:
print(f"μλ €μ§μ§ μμ μν μ½λμ
λλ€. μ¬μ©μλͺ
:{user_info['name']} μνμ½λ:{user_info['status']}")
print("μν μ½λ μ 보μ ν¨κ» Issues μμ± λΆνλ립λλ€.")
close()
def set_kakao_user_cookie():
global jar
user_kavacto = input("μΉ΄μΉ΄μ€ν‘ μΈμ± λΈλΌμ°μ μμ νμΈν μΏ ν€ κ°μ μ
λ ₯ν΄μ£ΌμΈμ.\nμ) VGhpcyBpcy...lNjQgc3RyaW5nLg== : ")
jar = {'_kavacto': user_kavacto}
dump_cookie(user_kavacto)
def dump_cookie(user_kavacto):
config_parser = configparser.ConfigParser()
config_parser['cookie'] = {}
conf = config_parser['cookie']
conf['_kavacto'] = user_kavacto
with open("cookie.ini", "w") as cookie:
config_parser.write(cookie)
def load_kakao_user_cookie():
global jar
cookie_loaded = False
config_parser = configparser.ConfigParser()
if os.path.exists('cookie.ini'):
try:
config_parser.read('cookie.ini')
configuration = config_parser['cookie']
user_kavacto = configuration["_kavacto"]
jar = {'_kavacto': user_kavacto}
except KeyError:
print('ERROR: cookie.iniκ° μμλμμ΅λλ€. νμΌμ μμ νκ±°λ μμ ν λ€μ μ€μ ν΄μ£ΌμΈμ.')
close()
confirm_input = None
while confirm_input is None:
confirm_input = str.lower(input("κΈ°μ‘΄μ μ¬μ©μ μ λ³΄λ‘ μ§ννμκ² μ΅λκΉ? Y/N : "))
if confirm_input == "y":
cookie_loaded = True
elif confirm_input == "n":
os.remove("cookie.ini")
print("κΈ°μ‘΄μ μ€μ λ μ¬μ©μ μ λ³΄κ° μμ λμμ΅λλ€.")
cookie_loaded = False
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
confirm_input = None
return cookie_loaded
def set_chrome_user_profile():
global jar
confirm_input = None
while confirm_input is None:
confirm_input = str.lower(input("Default νλ‘νμΌλ‘ μ§ννμκ² μ΅λκΉ? Y/N : "))
if confirm_input == "y":
return
elif confirm_input == "n":
profile_path = input("μ€μ νμλ €λ ν¬λ‘¬ νλ‘νμΌ κ²½λ‘λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ. : ")
cookie_path = profile_path + "/Cookies"
jar = browser_cookie3.chrome(domain_name=".kakao.com", cookie_file=cookie_path)
dump_profile(profile_path)
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
confirm_input = None
def load_chrome_user_profile():
global jar
profile_loaded = False
config_parser = configparser.ConfigParser()
if os.path.exists('profile.ini'):
try:
config_parser.read('profile.ini')
configuration = config_parser['config']
profile_path = configuration["profilePath"]
except KeyError:
print('ERROR: profile.iniκ° μμλμμ΅λλ€. νμΌμ μμ νκ±°λ μμ ν λ€μ μ€μ ν΄μ£ΌμΈμ.')
close()
print(f"κΈ°μ‘΄μ μ€μ λ ν¬λ‘¬ νλ‘νμΌ κ²½λ‘λ\n[{profile_path}] μ
λλ€.")
confirm_input = None
while confirm_input is None:
confirm_input = str.lower(input("ν΄λΉ νλ‘νμΌλ‘ μ§ννμκ² μ΅λκΉ? Y/N : "))
if confirm_input == "y":
cookie_path = profile_path + "/Cookies"
jar = browser_cookie3.chrome(domain_name=".kakao.com", cookie_file=cookie_path)
profile_loaded = True
elif confirm_input == "n":
os.remove("profile.ini")
print("κΈ°μ‘΄μ μ€μ λ νλ‘νμΌμ΄ μμ λμμ΅λλ€.")
profile_loaded = False
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
confirm_input = None
return profile_loaded
def dump_profile(profile_path):
config_parser = configparser.ConfigParser()
config_parser['config'] = {}
conf = config_parser['config']
conf['profilePath'] = profile_path
with open("profile.ini", "w") as profile:
config_parser.write(profile)
def check_find_vaccine_filter():
confirm_input = None
print("\nνν°λ§ λͺ¨λλ μμ¬ λ°±μ λ¬Όλμ΄ μμ΄λ μ ννμ λ°±μ μ΄ μλ λ³μμ μΌμμ μΌλ‘ μλ μ€ν΅νλ κΈ°λ₯μ
λλ€.")
while confirm_input is None:
confirm_input = str.lower(input("νν°λ§ λͺ¨λλ₯Ό μ¬μ©νμκ² μ΅λκΉ? (νμ μμ μ N κΆμ₯) Y/N : "))
if confirm_input == "y":
return True
elif confirm_input == "n":
return False
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
confirm_input = None
def fill_str_with_space(input_s, max_size=40, fill_char=" "):
"""
- κΈΈμ΄κ° κΈ΄ λ¬Έμλ 2μΉΈμΌλ‘ 체ν¬νκ³ , 짧μΌλ©΄ 1μΉΈμΌλ‘ 체ν¬ν¨.
- μ΅λ κΈΈμ΄(max_size)λ 40μ΄λ©°, input_sμ μ€μ κΈΈμ΄κ° μ΄λ³΄λ€ 짧μΌλ©΄
λ¨μ λ¬Έμλ₯Ό fill_charλ‘ μ±μ΄λ€.
"""
length = 0
for c in input_s:
if unicodedata.east_asian_width(c) in ["F", "W"]:
length += 2
else:
length += 1
return input_s + fill_char * (max_size - length)
def input_config():
vaccine_type = None
while True:
print("\n=== λ°±μ λͺ©λ‘ ===")
for vaccine in vaccine_candidates:
if vaccine["name"] == "(λ―Έμ¬μ©)":
continue
print(
f"{fill_str_with_space(vaccine['name'], 18)} : {vaccine['code']}")
vaccine_type = str.upper(input("μμ½μλν λ°±μ μ½λλ₯Ό μλ €μ£ΌμΈμ: ").strip())
if any(x["code"] == vaccine_type for x in vaccine_candidates) or vaccine_type.startswith("FORCE:"):
if vaccine_type.startswith("FORCE:"):
vaccine_type = vaccine_type[6:]
print("κ²½κ³ : κ°μ μ½λ μ
λ ₯λͺ¨λλ₯Ό μ¬μ©νμ
¨μ΅λλ€.\n" +
"μ΄ λͺ¨λλ μλ‘μ΄ λ°±μ μ΄ μμ½λ μ½λλ‘ **λ±λ‘λμ§ μμ κ²½μ°μλ§** μ¬μ©ν΄μΌ ν©λλ€.\n" +
"μ
λ ₯νμ μ½λκ° μ μμ μΌλ‘ μλνλ λ°±μ μ½λμΈμ§ νν νμΈν΄μ£ΌμΈμ.\n" +
f"νμ¬ μ½λ: '{vaccine_type}'\n")
if (len(vaccine_type) != 8 or not vaccine_type.startswith("VEN") or not vaccine_type[3:].isdigit()):
print("μ
λ ₯νμ μ½λκ° νμ¬ μλ €μ§ λ°±μ μ½λ νμμ΄λ λ§μ§ μμ΅λλ€.")
proceed = str.lower(input("μ§ννμκ² μ΅λκΉ? Y/N : "))
if proceed == "y":
pass
elif proceed == "n":
continue
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
continue
if next((x for x in vaccine_candidates if x["code"] == vaccine_type), {"name": ""})["name"] == "(λ―Έμ¬μ©)":
print("νμ¬ νλ‘κ·Έλ¨ λ²μ μμ λ°±μ μ΄λ¦μ΄ λ±λ‘λμ§ μμ, μΆνλ₯Ό μν΄ λ―Έλ¦¬ λ£μ΄λ λ°±μ μ½λμ
λλ€.\n" +
"μ
λ ₯νμ μ½λκ° μ μμ μΌλ‘ μλνλ λ°±μ μ½λμΈμ§ νν νμΈν΄μ£ΌμΈμ.\n" +
f"νμ¬ μ½λ: '{vaccine_type}'\n")
break
else:
print("λ°±μ μ½λλ₯Ό νμΈν΄μ£ΌμΈμ.")
print("\nμ¬κ°ν λͺ¨μμΌλ‘ λ°±μ λ²μλ₯Ό μ§μ ν λ€, ν΄λΉ λ²μ μμ μλ λ°±μ μ μ‘°νν΄μ λ¨μ λ°±μ μ΄ μμΌλ©΄ μμ½μ μλν©λλ€.")
top_x = None
while top_x is None:
top_x = input("μ¬κ°νμ μμͺ½ μ’μΈ‘ xκ°μ λ£μ΄μ£ΌμΈμ. 127.xxxxxx: ").strip()
top_y = None
while top_y is None:
top_y = input("μ¬κ°νμ μμͺ½ μ’μΈ‘ yκ°μ λ£μ΄μ£ΌμΈμ 37.xxxxxx: ").strip()
bottom_x = None
while bottom_x is None:
bottom_x = input("μ¬κ°νμ μλμͺ½ μ°μΈ‘ xκ°μ λ£μ΄μ£ΌμΈμ 127.xxxxxx: ").strip()
bottom_y = None
while bottom_y is None:
bottom_y = input("μ¬κ°νμ μλμͺ½ μ°μΈ‘ yκ°μ λ£μ΄μ£ΌμΈμ 37.xxxxxx: ").strip()
only_left = None
print("\nλ¨μ μμ¬λ°±μ μ΄ μλ λ³μλ§ μ‘°νν κ²½μ° μλκ° ν₯μλλ, νμ¬ λκΈ°μ€μΈ λ³μ λͺ©λ‘μ νμΈν μ μμΌλ©° 리νμ€νΈ λλ μ΄κ° μ€μ΄λ€μ΄ κ³μ μ μ§μ μνμ΄ λμμ§λλ€.")
while only_left is None:
only_left = str.lower(input("λ¨μ μμ¬λ°±μ μ΄ μλ λ³μλ§ μ‘°ννμκ² μ΅λκΉ? Y/N : "))
if only_left == "y":
only_left = True
elif only_left == "n":
only_left = False
else:
print("Y λλ Nμ μ
λ ₯ν΄ μ£ΌμΈμ.")
only_left = None
dump_config(vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left)
return vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left
def dump_config(vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left):
config_parser = configparser.ConfigParser()
config_parser['config'] = {}
conf = config_parser['config']
conf['VAC'] = vaccine_type
conf["topX"] = top_x
conf["topY"] = top_y
conf["botX"] = bottom_x
conf["botY"] = bottom_y
conf["onlyLeft"] = "True" if only_left else "False"
with open("config.ini", "w") as config_file:
config_parser.write(config_file)
def check_sound_file_loaded():
not_loaded = False
if not os.path.exists('tada.mp3'):
print('ERROR: tada.mp3κ° exe κ²½λ‘μ μμ΅λλ€. mp3μ exeκ° κ°μ κ²½λ‘μ μλμ§ νμΈν΄μ£ΌμΈμ.')
not_loaded = True
if not os.path.exists('xylophon.mp3'):
print('ERROR: xylophon.mp3κ° exe κ²½λ‘μ μμ΅λλ€. mp3μ exeκ° κ°μ κ²½λ‘μ μλμ§ νμΈν΄μ£ΌμΈμ.')
not_loaded = True
if not_loaded:
input("Press Enter to close...")
sys.exit()
def play_tada():
try:
mixer.init()
mixer.music.load('tada.mp3')
mixer.music.play()
except:
print("\nERROR: tada.mp3λ₯Ό μ¬μνμ§ λͺ»νμ΅λλ€. mp3μ exeκ° κ°μ κ²½λ‘μ μλμ§ νμΈν΄μ£ΌμΈμ.")
def play_xylophon():
try:
mixer.init()
mixer.music.load('xylophon.mp3')
mixer.music.play()
except:
print("\nERROR: xylophon.mp3λ₯Ό μ¬μνμ§ λͺ»νμ΅λλ€. mp3μ exeκ° κ°μ κ²½λ‘μ μλμ§ νμΈν΄μ£ΌμΈμ.")
def close(success=False):
if success:
send_msg("μμ¬λ°±μ μμ½ μ±κ³΅!! \n μΉ΄μΉ΄μ€ν‘μ§κ°μ νμΈνμΈμ.")
play_tada()
else:
send_msg("μ€λ₯μ ν¨κ» μμ¬λ°±μ μμ½ νλ‘κ·Έλ¨μ΄ μ’
λ£λμμ΅λλ€.")
play_xylophon()
input("Press Enter to close...")
sys.exit()
class Headers:
headers_map = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
"Origin": "https://vaccine-map.kakao.com",
"Accept-Language": "en-us",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 KAKAOTALK 9.4.2",
"Referer": "https://vaccine-map.kakao.com/",
"Accept-Encoding": "gzip, deflate",
"Connection": "Keep-Alive",
"Keep-Alive": "timeout=5, max=1000"
}
headers_vacc = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
"Origin": "https://vaccine.kakao.com",
"Accept-Language": "en-us",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 KAKAOTALK 9.4.2",
"Referer": "https://vaccine.kakao.com/",
"Accept-Encoding": "gzip, deflate",
"Connection": "Keep-Alive",
"Keep-Alive": "timeout=5, max=1000"
}
def try_reservation(organization_code, vaccine_type, found):
data = {"from": "List", "vaccineCode": vaccine_type, "orgCode": organization_code, "distance": None}
response = requests.post('https://vaccine.kakao.com/api/v2/reservation', data=json.dumps(data), headers=Headers.headers_vacc, cookies=jar, verify=False)
print(f"{found.get('orgName')} μμ λ°±μ μ {found.get('leftCounts')}κ° λ°κ²¬νμ΅λλ€.\n{vaccine_type} μΌλ‘ μμ½μ μλν©λλ€.")
response_json = json.loads(response.text)
if response_json.get('error'):
print("μ¬μ©μ μ 보λ₯Ό λΆλ¬μ€λλ° μ€ν¨νμμ΅λλ€.")
print("Chrome λΈλΌμ°μ μμ μΉ΄μΉ΄μ€μ μ λλ‘ λ‘κ·ΈμΈλμ΄μλμ§ νμΈν΄μ£ΌμΈμ.")
close()
else:
reservation_status = response_json['code']
if reservation_status == "NO_VACANCY":
retry_reservation(organization_code, vaccine_type)
elif reservation_status == "TIMEOUT":
print("TIMEOUT, μμ½μ μ¬μλν©λλ€.")
retry_reservation(organization_code, vaccine_type)
elif reservation_status == "SUCCESS":
print("λ°±μ μ μ’
μ μ² μ±κ³΅!!!")
organization_code_success = response_json.get("organization")
print(
f"λ³μμ΄λ¦: {organization_code_success.get('orgName')}\t" +
f"μ νλ²νΈ: {organization_code_success.get('phoneNumber')}\t" +
f"μ£Όμ: {organization_code_success.get('address')}")
close(success=True)
else:
print("ERROR. μλ λ©μμ§λ₯Ό λ³΄κ³ , μμ½μ΄ μ μ²λ λ³μ λλ 1339μ μμ½μ΄ λμλμ§ νμΈν΄λ³΄μΈμ.")
print(response.text)
close()
def retry_reservation(organization_code, vaccine_type):
reservation_url = 'https://vaccine.kakao.com/api/v2/reservation/retry'
data = {"from": "List", "vaccineCode": vaccine_type,
"orgCode": organization_code, "distance": None}
response = requests.post(reservation_url, data=json.dumps(
data), headers=Headers.headers_vacc, cookies=jar, verify=False)
response_json = json.loads(response.text)
if response_json.get('error'):
print("μ¬μ©μ μ 보λ₯Ό λΆλ¬μ€λλ° μ€ν¨νμμ΅λλ€.")
print("Chrome λΈλΌμ°μ μμ μΉ΄μΉ΄μ€μ μ λλ‘ λ‘κ·ΈμΈλμ΄μλμ§ νμΈν΄μ£ΌμΈμ.")
close()
else:
reservation_status = response_json['code']
if reservation_status == "NO_VACANCY":
print("μ°ΎμΌμλ λ°±μ μ΄ μκ±°λ μ μ°©μ λ§κ°λμμ΅λλ€.")
elif reservation_status == "SUCCESS":
print("λ°±μ μ μ’
μ μ² μ±κ³΅!!!")
organization_code_success = response_json.get("organization")
print(
f"λ³μμ΄λ¦: {organization_code_success.get('orgName')}\t" +
f"μ νλ²νΈ: {organization_code_success.get('phoneNumber')}\t" +
f"μ£Όμ: {organization_code_success.get('address')}")
close(success=True)
else:
print("ERROR. μλ λ©μμ§λ₯Ό λ³΄κ³ , μμ½μ΄ μ μ²λ λ³μ λλ 1339μ μμ½μ΄ λμλμ§ νμΈν΄λ³΄μΈμ.")
print(response.text)
close()
# ===================================== def ===================================== #
# Get Cookie
# driver = selenium.webdriver.Firefox()
# driver.get("https://cs.kakao.com")
# pickle.dump( driver.get_cookies() , open("cookies.pkl","wb"))
# cookies = pickle.load(open("cookies.pkl", "rb"))
# for cookie in cookies:
# driver.add_cookie(cookie)
# print(cookie)
# pylint: disable=too-many-locals,too-many-statements,too-many-branches
def find_vaccine(vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left):
data = {"bottomRight": {"x": bottom_x, "y": bottom_y}, "onlyLeft": only_left, "order": "count",
"topLeft": {"x": top_x, "y": top_y}}
while True:
try:
response = requests.post('https://vaccine-map.kakao.com/api/v3/vaccine/left_count_by_coords', data=json.dumps(data), headers=Headers.headers_map, verify=False, timeout=5)
json_data = json.loads(response.text)
for x in json_data.get("organizations"):
if x.get('status') == "AVAILABLE" or x.get('leftCounts') != 0:
try_reservation(x.get('orgCode'), vaccine_type, x)
else:
break
# show waiting list only when p key is pressed
if keyboard.is_pressed("p"):
for org in json_data["organizations"]:
if org.get('status') == "INPUT_YET":
print(f"μμ¬κ°―μ: {org.get('leftCounts')}\tμν: {org.get('status')}\tκΈ°κ΄λͺ
: {org.get('orgName')}\tμ£Όμ: {org.get('address')}")
print(f"κ²μ μλ£: {datetime.now()}")
except json.decoder.JSONDecodeError as decodeerror:
print("JSONDecodeError : ", decodeerror)
print("JSON string : ", response.text)
close()
except requests.exceptions.Timeout as timeouterror:
print("Timeout Error : ", timeouterror)
except requests.exceptions.SSLError as sslerror:
print("SSL Error : ", sslerror)
close()
except requests.exceptions.ConnectionError as connectionerror:
print("Connection Error : ", connectionerror)
# See psf/requests#5430 to know why this is necessary.
if not re.search('Read timed out', str(connectionerror), re.IGNORECASE):
close()
except requests.exceptions.HTTPError as httperror:
print("Http Error : ", httperror)
close()
except requests.exceptions.RequestException as error:
print("AnyException : ", error)
close()
def find_any_vaccine(top_x, top_y, bottom_x, bottom_y, only_left):
data = {"bottomRight": {"x": bottom_x, "y": bottom_y}, "onlyLeft": only_left, "order": "count",
"topLeft": {"x": top_x, "y": top_y}}
while True:
try:
response = requests.post('https://vaccine-map.kakao.com/api/v3/vaccine/left_count_by_coords', data=json.dumps(data), headers=Headers.headers_map, verify=False, timeout=5)
json_data = json.loads(response.text)
for x in json_data.get("organizations"):
if x.get('status') == "AVAILABLE" or x.get('leftCounts') != 0:
organization_code = x.get('orgCode')
check_organization_url = f'https://vaccine.kakao.com/api/v3/org/org_code/{organization_code}'
check_organization_response = requests.get(check_organization_url, headers=Headers.headers_vacc, cookies=jar, verify=False)
check_organization_data = json.loads(check_organization_response.text).get("lefts")
for v in check_organization_data:
if v.get('leftCount') != 0:
try_reservation(organization_code, v.get('vaccineCode'), x)
else:
break
# show waiting list only when p key is pressed
if keyboard.is_pressed("p"):
for org in json_data["organizations"]:
if org.get('status') == "INPUT_YET":
print(f"μμ¬κ°―μ: {org.get('leftCounts')}\tμν: {org.get('status')}\tκΈ°κ΄λͺ
: {org.get('orgName')}\tμ£Όμ: {org.get('address')}")
print(f"κ²μ μλ£: {datetime.now()}")
except json.decoder.JSONDecodeError as decodeerror:
print("JSONDecodeError : ", decodeerror)
print("JSON string : ", response.text)
close()
except requests.exceptions.Timeout as timeouterror:
print("Timeout Error : ", timeouterror)
except requests.exceptions.SSLError as sslerror:
print("SSL Error : ", sslerror)
close()
except requests.exceptions.ConnectionError as connectionerror:
print("Connection Error : ", connectionerror)
# See psf/requests#5430 to know why this is necessary.
if not re.search('Read timed out', str(connectionerror), re.IGNORECASE):
close()
except requests.exceptions.HTTPError as httperror:
print("Http Error : ", httperror)
close()
except requests.exceptions.RequestException as error:
print("AnyException : ", error)
close()
def filter_init(vaccine_type, top_x, top_y, bottom_x, bottom_y):
print("\nνν°λ§μ μμν©λλ€. μ μλ§ κΈ°λ€λ €μ£ΌμΈμ.")
filter = {}
data = {"bottomRight": {"x": bottom_x, "y": bottom_y}, "onlyLeft": True, "order": "count",
"topLeft": {"x": top_x, "y": top_y}}
while True:
try:
response = requests.post('https://vaccine-map.kakao.com/api/v3/vaccine/left_count_by_coords', data=json.dumps(data), headers=Headers.headers_map, verify=False, timeout=5)
json_data = json.loads(response.text)
for x in json_data.get("organizations"):
left_counts = x.get('leftCounts')
organization_code = x.get('orgCode')
check_organization_url = f'https://vaccine.kakao.com/api/v3/org/org_code/{organization_code}'
check_organization_response = requests.get(check_organization_url, headers=Headers.headers_vacc, cookies=jar, verify=False)
check_organization_data = json.loads(check_organization_response.text).get("lefts")
for v in check_organization_data:
if v.get('vaccineCode') == vaccine_type and v.get('leftCount') != 0:
try_reservation(organization_code, v.get('vaccineCode'), x)
left_counts -= v.get('leftCount')
break
filter[organization_code] = left_counts
break
except json.decoder.JSONDecodeError as decodeerror:
print("JSONDecodeError : ", decodeerror)
print("JSON string : ", response.text)
close()
except requests.exceptions.Timeout as timeouterror:
print("Timeout Error : ", timeouterror)
except requests.exceptions.SSLError as sslerror:
print("SSL Error : ", sslerror)
close()
except requests.exceptions.ConnectionError as connectionerror:
print("Connection Error : ", connectionerror)
# See psf/requests#5430 to know why this is necessary.
if not re.search('Read timed out', str(connectionerror), re.IGNORECASE):
close()
except requests.exceptions.HTTPError as httperror:
print("Http Error : ", httperror)
close()
except requests.exceptions.RequestException as error:
print("AnyException : ", error)
close()
return filter
def smart_find_vaccine(vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left, filter):
org_filter = filter
data = {"bottomRight": {"x": bottom_x, "y": bottom_y}, "onlyLeft": only_left, "order": "count",
"topLeft": {"x": top_x, "y": top_y}}
while True:
try:
response = requests.post('https://vaccine-map.kakao.com/api/v3/vaccine/left_count_by_coords', data=json.dumps(data), headers=Headers.headers_map, verify=False, timeout=5)
json_data = json.loads(response.text)
new_org_filter = {}
for x in json_data.get("organizations"):
org_code = x.get('orgCode')
left_counts = x.get('leftCounts')
if left_counts != 0:
if org_filter.get(org_code, 0) != left_counts:
try_reservation(org_code, vaccine_type, x)
new_org_filter[org_code] = left_counts
else:
break
org_filter = new_org_filter
# show waiting list only when p key is pressed
if keyboard.is_pressed("p"):
for org in json_data["organizations"]:
if org.get('status') == "INPUT_YET":
print(f"μμ¬κ°―μ: {org.get('leftCounts')}\tμν: {org.get('status')}\tκΈ°κ΄λͺ
: {org.get('orgName')}\tμ£Όμ: {org.get('address')}")
print(f"κ²μ μλ£: {datetime.now()}")
except json.decoder.JSONDecodeError as decodeerror:
print("JSONDecodeError : ", decodeerror)
print("JSON string : ", response.text)
close()
except requests.exceptions.Timeout as timeouterror:
print("Timeout Error : ", timeouterror)
except requests.exceptions.SSLError as sslerror:
print("SSL Error : ", sslerror)
close()
except requests.exceptions.ConnectionError as connectionerror:
print("Connection Error : ", connectionerror)
# See psf/requests#5430 to know why this is necessary.
if not re.search('Read timed out', str(connectionerror), re.IGNORECASE):
close()
except requests.exceptions.HTTPError as httperror:
print("Http Error : ", httperror)
close()
except requests.exceptions.RequestException as error:
print("AnyException : ", error)
close()
def main_function():
print('* * * * * * * * * * * * * * * * * * *')
print('* *')
print('* KC19VR CUSTOM BUILD *')
print('* v1.8 by Queue_ri *')
print('* *')
print('* * * * * * * * * * * * * * * * * * *\n')
check_sound_file_loaded()
# DEPRECATED (~21.08.19)
# profile_loaded = load_chrome_user_profile()
# if profile_loaded is False:
# set_chrome_user_profile()
cookie_loaded = load_kakao_user_cookie()
if cookie_loaded is False:
set_kakao_user_cookie()
check_user_info_loaded()
previous_used_type, previous_top_x, previous_top_y, previous_bottom_x, previous_bottom_y, previous_only_left = load_config()
if previous_used_type is None:
vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left = input_config()
else:
vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left = previous_used_type, previous_top_x, previous_top_y, previous_bottom_x, previous_bottom_y, previous_only_left
if vaccine_type == "ANY":
find_any_vaccine(top_x, top_y, bottom_x, bottom_y, only_left)
else:
apply_filter = check_find_vaccine_filter()
if apply_filter:
filter = filter_init(vaccine_type, top_x, top_y, bottom_x, bottom_y)
smart_find_vaccine(vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left, filter)
else:
find_vaccine(vaccine_type, top_x, top_y, bottom_x, bottom_y, only_left)
close()
def send_msg(msg):
config_parser = configparser.ConfigParser()
if os.path.exists('telegram.txt'):
try:
config_parser.read('telegram.txt')
print("TelegramμΌλ‘ κ²°κ³Όλ₯Ό μ μ‘ν©λλ€.")
tgtoken = config_parser["telegram"]["token"]
tgid = config_parser["telegram"]["chatid"]
bot = telepot.Bot(tgtoken)
bot.sendMessage(tgid, msg)
return
except Exception as e:
print("Telegram Error : ", e)
return
# ===================================== run ===================================== #
if __name__ == '__main__':
main_function()