-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmain.py
100 lines (89 loc) · 3.29 KB
/
main.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
import configparser
import hashlib
import hmac
import json
import random
import string
import sys
import time
from http import client
from pathlib import Path
config_file_name = "config.ini"
# noinspection SpellCheckingInspection
pica_api_host = "picaapi.picacomic.com"
pica_api_base_url = "https://%s/" % pica_api_host
sign_in_path = "auth/sign-in"
punch_in_path = "users/punch-in"
POST = "POST"
# noinspection SpellCheckingInspection
api_key = "C69BAF41DA5ABD1FFEDC6D2FEA56B"
api_secret = "~d}$Q7$eIni=V)9\\RK/P.RM4;9[7|@/CA}b~OW!3?EV`:<>M7pddUBL5n|0/*Cn"
# noinspection SpellCheckingInspection
static_headers = {
"api-key": api_key,
"accept": "application/vnd.picacomic.com.v1+json",
"app-channel": "2",
"app-version": "2.2.1.2.3.3",
"app-uuid": "defaultUuid",
"app-platform": "android",
"app-build-version": "44",
"User-Agent": "okhttp/3.8.1",
"image-quality": "original",
}
def send_request(path: string, method: string, body: string = None, token: string = None) -> dict:
current_time = str(int(time.time()))
nonce = "".join(random.choices(string.ascii_lowercase + string.digits, k=32))
raw = path + current_time + nonce + method + api_key
raw = raw.lower()
h = hmac.new(api_secret.encode(), digestmod=hashlib.sha256)
h.update(raw.encode())
signature = h.hexdigest()
headers = static_headers.copy()
headers["time"] = current_time
headers["nonce"] = nonce
headers["signature"] = signature
if body is not None:
headers["Content-Type"] = "application/json; charset=UTF-8"
if token is not None:
headers["authorization"] = token
connection = client.HTTPSConnection(pica_api_host)
connection.request(method, '/' + path, body, headers)
response = connection.getresponse().read().decode("utf-8")
json_object = json.loads(response)
if json_object["code"] != 200:
raise RuntimeError(json_object["message"])
return json_object
def sign_in(email: string, password: string) -> string:
body = {
"email": email,
"password": password
}
return send_request(sign_in_path, POST, json.dumps(body))["data"]["token"]
def punch_in(token: string):
return send_request(punch_in_path, POST, token=token)
if __name__ == '__main__':
input_email = None
input_password = None
if len(sys.argv) > 1:
if len(sys.argv) != 3:
sys.exit("Usage:\npython main.py {email} {password}")
input_email = sys.argv[1]
input_password = sys.argv[2]
else:
config_file = Path(__file__).resolve().parent / config_file_name
if not config_file.exists():
sys.exit("Please rename '_%(s)s' to '%(s)s'" % {"s": config_file_name})
config = configparser.ConfigParser()
config.read(config_file)
default_section = config["DEFAULT"]
input_email = default_section["email"]
input_password = default_section["password"]
if not input_email or not input_password:
sys.exit("Email and password can't be empty")
current_token = sign_in(input_email, input_password)
punch_in_response = punch_in(current_token)
result = punch_in_response["data"]["res"]
if result["status"] == "ok":
print("Punch-in succeed, last punch-in day: %s" % result["punchInLastDay"])
else:
print("Already punch-in")