rdp-studio commited on
Commit
f5e6625
1 Parent(s): c53e6a1

Create nft.py

Browse files
Files changed (1) hide show
  1. nft.py +140 -0
nft.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import requests
3
+ from hashlib import md5
4
+ from typing import Union
5
+ from urllib.parse import urlencode
6
+ from requests_toolbelt.multipart.encoder import MultipartEncoder
7
+ import imghdr
8
+
9
+
10
+ class Crypto:
11
+ APPKEY = '4409e2ce8ffd12b8'
12
+ APPSECRET = '59b43e04ad6965f34319062b478f83dd'
13
+
14
+ @staticmethod
15
+ def md5(data: Union[str, bytes]) -> str:
16
+ '''generates md5 hex dump of `str` or `bytes`'''
17
+ if type(data) == str:
18
+ return md5(data.encode()).hexdigest()
19
+ return md5(data).hexdigest()
20
+
21
+ @staticmethod
22
+ def sign(data: Union[str, dict]) -> str:
23
+ '''salted sign funtion for `dict`(converts to qs then parse) & `str`'''
24
+ if isinstance(data, dict):
25
+ _str = urlencode(data)
26
+ elif type(data) != str:
27
+ raise TypeError
28
+ return Crypto.md5(_str + Crypto.APPSECRET)
29
+
30
+
31
+ class SingableDict(dict):
32
+ @property
33
+ def sorted(self):
34
+ '''returns a alphabetically sorted version of `self`'''
35
+ return dict(sorted(self.items()))
36
+
37
+ @property
38
+ def signed(self):
39
+ '''returns our sorted self with calculated `sign` as a new key-value pair at the end'''
40
+ _sorted = self.sorted
41
+ return {**_sorted, 'sign': Crypto.sign(_sorted)}
42
+
43
+
44
+ def get_image_type(file_path):
45
+ with open(file_path, 'rb') as f:
46
+ data = f.read()
47
+ return imghdr.what(None, data)
48
+
49
+
50
+ def get_have_card_id_list(UID, ACCESS_KEY, sid):
51
+ url = "https://api.bilibili.com/x/vas/nftcard/cardlist"
52
+ params = SingableDict(
53
+ {
54
+ "access_key": ACCESS_KEY,
55
+ "act_id": sid, # 这里默认已经是三体数字藏品卡14,github下载的默认是4,也就是胶囊卡
56
+ "appkey": "4409e2ce8ffd12b8",
57
+ "disable_rcmd": "0",
58
+ "ruid": UID,
59
+ "statistics": "{\"appId\":1,\"platform\":3,\"version\":\"7.9.0\",\"abtest\":\"\"}",
60
+ "ts": int(time.time()),
61
+ }
62
+ ).signed
63
+ response = requests.request("GET", url, params=params)
64
+ data = response.json()
65
+ if data['code'] != 0:
66
+ print(f"获取卡片信息出错,下面是 api 返回:\n{data}")
67
+ return
68
+ # print(data) # 查询已添加无需再填
69
+ have_card_id_list = {}
70
+ try:
71
+ for round in data['data']['round_list']:
72
+ for card in round['card_list']:
73
+ if card['card_id_list']:
74
+ print(f"找到付费卡 card_id: {card['card_id_list'][0]['card_id']}\n这个id属于{card['card_name']}")
75
+ have_card_id_list.update({card['card_name']: card['card_id_list'][0]['card_id']})
76
+ if data["data"]["pre_list"]:
77
+ for i in data["data"]["pre_list"]:
78
+ if card_id_list := i.get("card_id_list"):
79
+ for j in card_id_list:
80
+ if card_id := j.get("card_id"):
81
+ print(f"找到预约卡card_id: {card_id}\n这个 id 属于{i.get('card_name')}")
82
+ have_card_id_list.update({i.get('card_name'): card_id})
83
+ except Exception as e:
84
+ print(f"处理卡牌列表出错{e.args[0]},下面是 api 返回:\n{data}")
85
+ return {}
86
+ if have_card_id_list:
87
+ print(f"已经找到卡片")
88
+ return have_card_id_list
89
+ else:
90
+ print("没有找到可用的卡片")
91
+ return {}
92
+
93
+
94
+ def set_face(card_id, ACCESS_KEY, img_data):
95
+ api = "https://api.bilibili.com/x/member/app/face/digitalKit/update"
96
+ params = SingableDict(
97
+ {
98
+ "access_key": ACCESS_KEY,
99
+ "appkey": "4409e2ce8ffd12b8",
100
+ "build": "7090300",
101
+ "c_locale": "zh_CN",
102
+ "channel": "xiaomi",
103
+ "disable_rcmd": "0",
104
+ "mobi_app": "android",
105
+ "platform": "android",
106
+ "s_locale": "zh_CN",
107
+ "statistics": "{\"appId\":1,\"platform\":3,\"version\":\"7.9.0\",\"abtest\":\"\"}",
108
+ "ts": int(time.time()),
109
+ }
110
+ ).signed
111
+ m = MultipartEncoder(
112
+ fields={
113
+ 'digital_kit_id': str(card_id),
114
+ 'face': ('face', img_data, 'application/octet-stream'),
115
+ }
116
+ )
117
+ headers = {
118
+ "Content-Type": m.content_type,
119
+ }
120
+ response = requests.request("POST", api, data=m, headers=headers, params=params)
121
+ if response.json()['code'] != 0:
122
+ return False, response.json()
123
+ return True, '设置头像成功, 请等待审核'
124
+
125
+
126
+ def having_card_id_list(uid, key, sid):
127
+ uid = int(uid)
128
+ access_key = str(key)
129
+ sid = str(sid)
130
+
131
+ had_card_id_list = get_have_card_id_list(uid, access_key, sid) # 根据你所取得的卡card_id进行更改
132
+ if had_card_id_list:
133
+ return True, had_card_id_list, "已找到拥有卡牌"
134
+ return False, {}, "没找到任何card_id ,请确认当前卡组已拥有卡片"
135
+
136
+
137
+ def card_id_set_ava(card_id, key, img_data):
138
+ access_key = str(key)
139
+ result, code = set_face(card_id, access_key, img_data)
140
+ return result, code