agh123 commited on
Commit
097ec8a
·
1 Parent(s): 7b33522

feat: use android device marketing name

Browse files
src/services/firebase.py CHANGED
@@ -27,13 +27,19 @@ db = initialize_firebase()
27
  def normalize_device_id(device_info: dict) -> str:
28
  """Normalize device identifier for aggregation"""
29
  emulator = "/Emulator" if device_info.get("isEmulator", False) else ""
 
 
30
  if device_info.get("systemName", "").lower() == "ios":
31
  device_id = device_info.get("deviceId", "Unknown")
32
- device_name = get_device_name(device_id, device_info.get("model", "Unknown"))
33
  return f"iOS/{device_name}{emulator}"
34
 
 
35
  memory_tier = f"{device_info.get('totalMemory', 0) // (1024**3)}GB"
36
- return f"{device_info.get('brand', 'Unknown')}/{device_info.get('model', 'Unknown')}/{memory_tier}{emulator}"
 
 
 
37
 
38
 
39
  def format_params_in_b(params: int) -> float:
@@ -70,14 +76,17 @@ def format_leaderboard_data(submissions: List[dict]) -> pd.DataFrame:
70
 
71
  # Get device ID for iOS devices
72
  device_id = device_info.get("deviceId", "Unknown")
73
-
74
- # Use the normalized device name from lookup for iOS devices
75
- if (
76
- device_info.get("systemName", "").lower() == "ios"
77
- and device_id != "Unknown"
78
- ):
79
- device_name = get_device_name(device_id)
 
 
80
  else:
 
81
  device_name = device_info.get("model", "Unknown")
82
 
83
  formatted_data.append(
 
27
  def normalize_device_id(device_info: dict) -> str:
28
  """Normalize device identifier for aggregation"""
29
  emulator = "/Emulator" if device_info.get("isEmulator", False) else ""
30
+
31
+ # iOS
32
  if device_info.get("systemName", "").lower() == "ios":
33
  device_id = device_info.get("deviceId", "Unknown")
34
+ device_name = get_device_name("Apple", device_id, device_id)
35
  return f"iOS/{device_name}{emulator}"
36
 
37
+ # Android
38
  memory_tier = f"{device_info.get('totalMemory', 0) // (1024**3)}GB"
39
+ model = device_info.get("model", "Unknown")
40
+ manufacturer = device_info.get("brand", "Unknown")
41
+ name = get_device_name(manufacturer, model, model)
42
+ return f"{manufacturer}/{name}/{memory_tier}{emulator}"
43
 
44
 
45
  def format_params_in_b(params: int) -> float:
 
76
 
77
  # Get device ID for iOS devices
78
  device_id = device_info.get("deviceId", "Unknown")
79
+ platform = device_info.get("systemName", "Unknown").lower()
80
+ if platform == "ios":
81
+ # For iOS, use the device lookup
82
+ device_name = get_device_name("Apple", device_id, device_id)
83
+ elif platform == "android":
84
+ # For Android, use the GitHub repo lookup
85
+ manufacturer = device_info.get("brand", "Unknown")
86
+ model = device_info.get("model", "Unknown")
87
+ device_name = get_device_name(manufacturer, model, model)
88
  else:
89
+ # For other platforms, use the model as is
90
  device_name = device_info.get("model", "Unknown")
91
 
92
  formatted_data.append(
src/utils/android_device_cache.json ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "google:pixel 7 pro": "Pixel 7 Pro",
3
+ "oppo:cph2651": "Find X8",
4
+ "samsung:sm-s928u": "Galaxy S24 Ultra",
5
+ "samsung:sm-s918u": "Galaxy S23 Ultra",
6
+ "samsung:sm-s9180": "Galaxy S23 Ultra",
7
+ "samsung:sm-a546b": "Galaxy A54 5G",
8
+ "samsung:sm-s918b": "Galaxy S23 Ultra",
9
+ "samsung:sm-a155f": "Galaxy A15",
10
+ "google:pixel 6": "Pixel 6",
11
+ "google:pixel 6a": "Pixel 6a",
12
+ "google:pixel 8 pro": "Pixel 8 Pro",
13
+ "samsung:sm-n950u": "Galaxy Note8",
14
+ "google:pixel 9": "Pixel 9",
15
+ "vivo:v2324a": "X100 Pro",
16
+ "oneplus:cph2581": "OnePlus 12",
17
+ "google:pixel 9 pro": "Pixel 9 Pro",
18
+ "samsung:sm-g986u": "Galaxy S20+ 5G",
19
+ "samsung:sm-a556b": "Galaxy A55 5G",
20
+ "oneplus:cph2583": "OnePlus 12",
21
+ "motorola:motorola edge 40 neo": "motorola edge 40 neo",
22
+ "poco:23076pc4bi": "POCO M6 Pro 5G",
23
+ "samsung:sm-g985f": "Digicom_DTOK",
24
+ "samsung:sm-g780g": "Galaxy S20 FE",
25
+ "samsung:sm-x210": "Galaxy Tab A9+",
26
+ "samsung:sm-a5260": "Galaxy A52 5G",
27
+ "redmi:23124ra7eo": "Redmi Note 13",
28
+ "samsung:sm-s911b": "Galaxy S23",
29
+ "google:pixel 5a": "Pixel 5a 5G",
30
+ "xiaomi:2210132c": "Xiaomi 13 pro",
31
+ "google:pixel 7": "Pixel 7",
32
+ "samsung:sm-g781b": "ZenFone 7 / 7 Pro (ZS670KS/ZS671KS)",
33
+ "infinix:infinix x676c": "Infinix NOTE 12 2023",
34
+ "honor:rod2-w09": "\u8363\u8000\u5e73\u677fMagicPad2",
35
+ "vivo:vivo 1906": "vivo 1906",
36
+ "oneplus:pkg110": "OnePlus Ace 5",
37
+ "samsung:sm-s936b": "Galaxy S25+",
38
+ "oneplus:cph2573": "12",
39
+ "oppo:cph2629": "Reno12 Pro 5G",
40
+ "samsung:sm-x710": "Galaxy Tab S9",
41
+ "vivo:v2352a": "iQOO Z9 Turbo",
42
+ "samsung:sm-s908u1": "Galaxy S22 Ultra",
43
+ "realme:rmx3031": "realme X7 Max",
44
+ "redmi:m2101k7bi": "Redmi Note 10S",
45
+ "samsung:sm-s931u1": "Galaxy S25",
46
+ "samsung:sm-s938u1": "Galaxy S25 Ultra",
47
+ "samsung:sm-n975u1": "Galaxy Note10+",
48
+ "realme:rmx2202": "realme GT 5G",
49
+ "redmi:2407frk8ec": "Redmi K70 Ultra",
50
+ "poco:m2102j20sg": "POCO X3 Pro",
51
+ "xiaomi:m2102k1g": "Mi 11 Ultra",
52
+ "samsung:sm-g781w": "Galaxy S20 FE 5G",
53
+ "itel:itel p10003l": "itel VistaTab 30",
54
+ "samsung:sc-51e": "Galaxy S24",
55
+ "google:pixel 8": "Pixel 8",
56
+ "infinix:infinix x6731": "ZERO 30 5G",
57
+ "xiaomi:23127pn0cc": "Xiaomi 14",
58
+ "google:pixel 8a": "Pixel 8a",
59
+ "oneplus:cph2649": "OnePlus 13",
60
+ "sony:xq-bq52": "Xperia 5 III",
61
+ "samsung:sm-f956b": "Galaxy Z Fold6",
62
+ "honor:rmo-nx1": "HONOR Magic5 Lite 5G",
63
+ "xiaomi:23127pn0cg": "Xiaomi 14",
64
+ "lenovo:lenovo tb-j606f": "Lenovo Tab K11",
65
+ "poco:2201117pi": "POCO M4 Pro",
66
+ "samsung:sm-x700": "Galaxy Tab S8",
67
+ "samsung:sm-n770f": "Galaxy Note10 Lite",
68
+ "asus:asus_ai2401_d": "ROG Phone 8 series",
69
+ "motorola:moto g72": "moto g72",
70
+ "samsung:sm-s938b": "Galaxy S25 Ultra",
71
+ "redmi:22041211ac": "Redmi K50",
72
+ "tcl:t612b": "TCL 40 NXTPAPER",
73
+ "oneplus:cph2655": "OnePlus 13",
74
+ "oneplus:cph2551": "Open",
75
+ "motorola:motorola edge 50 fusion": "motorola edge 50 fusion",
76
+ "oppo:cph1879": "R17",
77
+ "samsung:sm-e146b": "Galaxy F14 5G",
78
+ "samsung:sm-s918u1": "Galaxy S23 Ultra",
79
+ "realme:rmx2170": "realme 7 Pro",
80
+ "xiaomi:2308cpxd0c": "Xiaomi MIX Fold 3",
81
+ "motorola:moto g54 5g": "moto g54 5G",
82
+ "poco:23049pcd8g": "POCO F5",
83
+ "infinix:infinix x6812b": "Infinix HOT 11S NFC",
84
+ "doogee:t30pro": "T30Pro",
85
+ "motorola:motorola edge 30": "motorola edge 30",
86
+ "samsung:sm-s928b": "Galaxy S24 Ultra",
87
+ "google:pixel 9 pro xl": "Pixel 9 Pro XL",
88
+ "samsung:sm-s928u1": "Galaxy S24 Ultra",
89
+ "xiaomi:pocophone f1": "POCO F1",
90
+ "samsung:sm-a055f": "Galaxy A05",
91
+ "vivo:v2309a": "X100",
92
+ "redmi:22081283g": "Redmi Pad",
93
+ "redmi:22101316g": "Redmi Note 12 Pro 5G",
94
+ "oneplus:le2120": "OnePlus 9 Pro 5G",
95
+ "samsung:sm-a245f": "Galaxy A24",
96
+ "poco:2311drk48g": "POCO X6 Pro 5G",
97
+ "oppo:pkb110": "Find X8",
98
+ "samsung:sm-s908b": "Galaxy S22 Ultra",
99
+ "samsung:sm-f936u1": "Galaxy Z Fold4",
100
+ "vivo:v2408a": "iQOO 13",
101
+ "infinix:infinix x6815c": "ZERO 5G 2023",
102
+ "oneplus:cph2493": "OnePlus Nord 3 5G",
103
+ "oneplus:ac2001": "OnePlus Nord",
104
+ "samsung:sc-51a": "Galaxy S20 5G",
105
+ "motorola:thinkphone by motorola": "ThinkPhone by Motorola",
106
+ "samsung:sm-s908e": "Galaxy S22 Ultra",
107
+ "samsung:sm-g986n": "Galaxy S20+ 5G",
108
+ "samsung:sm-f946u1": "Galaxy Z Fold5",
109
+ "redmi:23073rpbfg": "Redmi Pad SE",
110
+ "samsung:sm-f956u": "Galaxy Z Fold6",
111
+ "samsung:sm-s931w": "Galaxy S25",
112
+ "xiaomi:24091rpadg": "Xiaomi Pad 7 Pro",
113
+ "samsung:sm-f721n": "Galaxy Z Flip4",
114
+ "redmi:23053rn02a": "Redmi 12",
115
+ "oneplus:oneplus a6003": "OnePlus 6",
116
+ "oppo:phy110": "Find X7 Ultra",
117
+ "samsung:sm-s921b": "Galaxy S24",
118
+ "google:pixel 7a": "Pixel 7a",
119
+ "samsung:sm-s926n": "Galaxy S24+",
120
+ "google:pixel 6 pro": "Pixel 6 Pro",
121
+ "samsung:sm-x820": "Galaxy Tab S10+",
122
+ "samsung:sm-g998b": "Prism II",
123
+ "samsung:sm-f741u": "Galaxy Z Flip6",
124
+ "lenovo:tb320fc": "Legion Tab Y700",
125
+ "ulefone:armor 21": "Armor 21",
126
+ "samsung:sm-e236b": "Galaxy F23 5G",
127
+ "poco:23122pcd1g": "POCO X6 5G",
128
+ "samsung:sm-a256b": "Galaxy A25 5G",
129
+ "google:pixel 4a": "Pixel 4a",
130
+ "oneplus:pjf110": "OnePlus Ace 3V",
131
+ "samsung:sm-x510": "Galaxy Tab S9 FE",
132
+ "poco:24069pc21g": "POCO F6",
133
+ "xiaomi:23116pn5bc": "Xiaomi 14 Pro",
134
+ "xreal:x4000": "Beam Pro",
135
+ "samsung:sm-s931u": "Galaxy S25",
136
+ "samsung:sm-s936u": "Galaxy S25+",
137
+ "motorola:motorola edge 40": "motorola edge 40",
138
+ "gigaset:e940-2849-00": "Gigaset GX6",
139
+ "samsung:sm-s911u": "Galaxy S23",
140
+ "xiaomi:23043rp34g": "Xiaomi Pad 6",
141
+ "oneplus:ac2003": "OnePlus Nord",
142
+ "samsung:sm-a515f": "Galaxy A51",
143
+ "samsung:sm-a525f": "Galaxy A52",
144
+ "samsung:sm-a356e": "Galaxy A35 5G",
145
+ "oneplus:in2025": "OnePlus 8 Pro",
146
+ "sony:xq-dq44": "Xperia 1 V",
147
+ "realme:rmx3085": "realme 8",
148
+ "poco:m2010j19ci": "POCO M3",
149
+ "oneplus:ne2213": "OnePlus 10 Pro 5G",
150
+ "poco:24069pc21i": "POCO F6",
151
+ "nothing:a142": "Nothing Phone (2a)",
152
+ "lenovo:tb350fu": "Lenovo Tab P11 (2nd Gen)",
153
+ "samsung:sm-s908w": "Galaxy S22 Ultra",
154
+ "poco:2311drk48i": "POCO X6 Pro 5G",
155
+ "redmi:23027rad4i": "Redmi Note 12",
156
+ "samsung:sm-s906u": "Galaxy S22+",
157
+ "samsung:sm-f956u1": "Galaxy Z Fold6",
158
+ "lenovo:tb321fu": "Lenovo Legion Tab\uff088.8'',3\uff09",
159
+ "redmi:22126rn91y": "Redmi 12C",
160
+ "poco:2412dpc0ag": "POCO X7 Pro",
161
+ "samsung:sm-s926b": "Galaxy S24+",
162
+ "oneplus:pjx110": "Oneplus Ace 3 Pro",
163
+ "zte:a304zt": "Libero Flip",
164
+ "samsung:sm-t975": "Galaxy Tab S7+",
165
+ "realme:rmx3312": "realme GT 2",
166
+ "realme:rmx3888": "realme GT5 Pro",
167
+ "lenovo:lenovo tb-8506x": "Lenovo Tab M8 (3rd Gen)",
168
+ "samsung:sm-s901b": "Galaxy S22",
169
+ "vivo:v2419": "vivo Y19s",
170
+ "oppo:phs110": "OPPO A1 5G",
171
+ "samsung:sm-g990e": "Hot 1",
172
+ "huawei:vog-l29": "P30 Pro",
173
+ "oppo:cph2483": "A78 5G",
174
+ "motorola:moto g75 5g": "moto g75 5G",
175
+ "motorola:moto g41": "moto g41",
176
+ "samsung:sm-n950f": "Galaxy Note8",
177
+ "samsung:sm-g998u": "Galaxy S21 Ultra 5G",
178
+ "xiaomi:24031pn0dc": "Xiaomi 14 Ultra",
179
+ "infinix:infinix x6833b": "Infinix NOTE 30",
180
+ "vivo:v2426": "T3 Ultra",
181
+ "samsung:sm-f936b": "Galaxy Z Fold4",
182
+ "xiaomi:2107113sg": "Xiaomi 11T Pro",
183
+ "realme:rmx3853": "realme GT 6T",
184
+ "oneplus:dn2103": "OnePlus Nord2 5G",
185
+ "redmi:redmi note 8 pro": "Redmi Note 8 Pro",
186
+ "xiaomi:2406apnfag": "Xiaomi 14T",
187
+ "samsung:sm-s721b": "Galaxy S24 FE",
188
+ "honor:bvl-an00": "HONOR Magic6",
189
+ "nothing:a063": "Nothing Phone (1)",
190
+ "xiaomi:m2105k81ac": "Xiaomi Pad 5 Pro",
191
+ "asus:asus_i005da": "ROG Phone 5",
192
+ "poco:23113rkc6g": "POCO F6 Pro",
193
+ "samsung:sm-a536b": "Galaxy A53 5G",
194
+ "samsung:sm-s916u1": "Galaxy S23+",
195
+ "realme:rmx3844": "realme P1 Pro 5G",
196
+ "samsung:sm-g973u1": "Galaxy S10",
197
+ "poco:22101320g": "POCO X5 Pro 5G",
198
+ "oneplus:cph2449": "OnePlus 11 5G",
199
+ "oneplus:cph2653": "OnePlus 13",
200
+ "vivo:v2426a": "V2426A",
201
+ "ulefone:armor 17 pro": "Armor 17 Pro",
202
+ "google:pixel 9 pro fold": "Pixel 9 Pro Fold",
203
+ "redmi:2405crpfdg": "Redmi Pad Pro",
204
+ "oppo:pgx110": "OPPO Reno9 Pro 5G",
205
+ "redmi:23129raa4g": "Redmi Note 13",
206
+ "oppo:cph2531": "Reno10 5G",
207
+ "samsung:sm-m156b": "Galaxy M15 5G",
208
+ "samsung:sm-g970u1": "Galaxy S10e",
209
+ "xiaomi:2407fpn8eg": "Xiaomi 14T Pro",
210
+ "asus:asusai2501c": "ROG Phone 9 Pro",
211
+ "xiaomi:2410dpn6cc": "Xiaomi 15 Pro",
212
+ "fairphone:fp5": "Fairphone 5 5G",
213
+ "oneplus:pjd110": "OnePlus 12",
214
+ "samsung:sm-s9210": "Galaxy S24",
215
+ "samsung:sm-s901e": "Galaxy S22",
216
+ "redmi:23124rn87i": "Redmi 13C 5G",
217
+ "samsung:sm-a346b": "Galaxy A34 5G",
218
+ "oneplus:cph2491": "OnePlus Nord 3 5G",
219
+ "oppo:cph2659": "Find X8 Pro",
220
+ "samsung:sm-g988b": "Stella X",
221
+ "samsung:sm-a217f": "Galaxy A21s",
222
+ "honor:elp-nx9": "HONOR 200 Pro",
223
+ "redmi:2311drk48c": "Redmi K70E",
224
+ "tcl:t702d": "TCL 50 NXTPAPER 5G",
225
+ "honor:pgt-n19": "HONOR Magic5 Pro",
226
+ "samsung:sm-x610": "Galaxy Tab S9 FE+",
227
+ "motorola:moto g42": "moto g42",
228
+ "samsung:sm-m446k": "Galaxy Jump3",
229
+ "xiaomi:2210132g": "Xiaomi 13 Pro",
230
+ "motorola:moto g power 5g - 2024": "moto g power 5G - 2024",
231
+ "redmi:2201117tl": "Redmi Note 11",
232
+ "samsung:sm-a556e": "Galaxy A55 5G",
233
+ "redmi:22041219ny": "Redmi 10 5G",
234
+ "samsung:sm-s928n": "Galaxy S24 Ultra",
235
+ "oneplus:cph2447": "OnePlus 11 5G",
236
+ "samsung:sm-g781u": "Galaxy S20 FE 5G",
237
+ "xiaomi:24030pn60g": "Xiaomi 14 Ultra",
238
+ "huawei:lya-al00p": "Mate 20 RS",
239
+ "samsung:sm-n986u": "Galaxy Note20 Ultra 5G",
240
+ "oneplus:cph2467": "OnePlus Nord CE 3 Lite 5G",
241
+ "sharp:sh-m28": "AQUOS R9",
242
+ "poco:m2007j20cg": "POCO X3 NFC",
243
+ "redmi:2201117ti": "Redmi Note 11",
244
+ "samsung:sm-a346m": "Galaxy A34 5G",
245
+ "xiaomi:24091rpadc": "Xiaomi Pad 7 Pro",
246
+ "oneplus:pjz110": "OnePlus 13",
247
+ "xiaomi:21081111rg": "Xiaomi 11T",
248
+ "cubot:max 5": "MAX 5",
249
+ "xiaomi:2306epn60g": "Xiaomi 13T",
250
+ "xiaomi:25019pnf3c": "Xiaomi 15 Ultra",
251
+ "samsung:sm-f946b": "Galaxy Z Fold5",
252
+ "sony:xq-dq54": "Xperia 1 V",
253
+ "vivo:v2040": "V2040",
254
+ "samsung:sm-g988w": "Galaxy S20 Ultra 5G",
255
+ "oppo:cph2637": "F27 5G",
256
+ "oukitel:rt2": "RT2_EEA",
257
+ "samsung:sm-g991u1": "Galaxy S21 5G",
258
+ "realme:rmx3360": "realme GT Master Edition",
259
+ "redmi:23049rad8c": "Redmi Note 12 Turbo",
260
+ "honor:ali-nx1": "HONOR Magic6 Lite 5G",
261
+ "oppo:cph2145": "CPH2145",
262
+ "realme:rmx3430": "realme narzo 50A",
263
+ "samsung:sm-a546e": "Galaxy A54 5G",
264
+ "samsung:sm-s926u1": "Galaxy S24+",
265
+ "lge:lm-v600": "LG V60 ThinQ",
266
+ "samsung:sm-s931b": "Galaxy S25",
267
+ "huawei:vog-al00": "P30 Pro",
268
+ "cubot:note 50": "NOTE 50",
269
+ "redmi:22041216c": "Redmi Note 11T Pro",
270
+ "realme:rmx3121": "realme V11 5G",
271
+ "samsung:sm-s926w": "Galaxy S24+",
272
+ "alldocube:iplay60 mini turbo": "iPlay60_mini_Turbo",
273
+ "vivo:v1924a": "V1924A",
274
+ "xiaomi:24129pn74c": "Xiaomi 15",
275
+ "poco:21121210g": "POCO F4 GT",
276
+ "sony:xq-dq72": "Xperia 1 V",
277
+ "motorola:motorola edge 30 pro": "ThinkPhone by Motorola",
278
+ "xiaomi:21051182g": "Xiaomi Pad 5",
279
+ "oneplus:pje110": "OnePlus Ace 3",
280
+ "oneplus:php110": "PHP110",
281
+ "xiaomi:xig04": "Xiaomi 13T",
282
+ "vivo:vivo 1917": "vivo 1917",
283
+ "oneplus:in2023": "OnePlus 8 Pro",
284
+ "oneplus:cph2661": "OnePlus Nord 4",
285
+ "redmi:m2101k6g": "Redmi Note 10 Pro",
286
+ "redmi:2201117ty": "Redmi Note 11",
287
+ "vivo:v2339fa": "iQOO Neo9S Pro",
288
+ "samsung:sm-f731u1": "Galaxy Z Flip5",
289
+ "xiaomi:22071212ag": "Xiaomi 12T",
290
+ "samsung:sm-a528b": "Galaxy A52s 5G",
291
+ "oppo:cph2251": "CPH2251",
292
+ "samsung:sm-s928w": "Galaxy S24 Ultra",
293
+ "oneplus:oneplus a5010": "OnePlus5T",
294
+ "samsung:sm-s146vl": "Galaxy A14 5G",
295
+ "xiaomi:mi 10 pro": "Mi 10 Pro",
296
+ "samsung:sm-s906e": "Galaxy S22+",
297
+ "samsung:sm-s938w": "Galaxy S25 Ultra",
298
+ "redmi:23106rn0da": "Redmi 13C",
299
+ "redmi:23113rkc6c": "Redmi K70",
300
+ "redmi:2312draabi": "Redmi Note 13 5G",
301
+ "samsung:scg27": "Galaxy A55 5G",
302
+ "samsung:sm-x910": "Galaxy Tab S9 Ultra",
303
+ "samsung:sm-n981u1": "Galaxy Note20 5G",
304
+ "samsung:sm-s906w": "Galaxy S22+",
305
+ "redmi:m2101k6p": "Redmi Note 10 Pro",
306
+ "oppo:cph2009": "Find X2 Neo/Reno3 Pro",
307
+ "redmi:22041216i": "Redmi K50i",
308
+ "samsung:sm-x920": "Galaxy Tab S10 Ultra",
309
+ "oneplus:cph2613": "OnePlus Nord CE4",
310
+ "samsung:sm-f936u": "Galaxy Z Fold4",
311
+ "oppo:cph2521": "Reno10 Pro+ 5G",
312
+ "hotwav:hyper 7 pro": "Hyper 7 Pro",
313
+ "oneplus:le2127": "OnePlus 9 Pro 5G",
314
+ "honor:ver-n49": "HONOR Magic V2",
315
+ "xiaomi:23043rp34i": "Xiaomi Pad 6",
316
+ "tecno:tecno kj7": "TECNO SPARK 20 Pro+",
317
+ "samsung:sm-m556b": "Galaxy M55 5G",
318
+ "oneplus:le2123": "OnePlus 9 Pro 5G",
319
+ "oneplus:cph2451": "OnePlus 11 5G",
320
+ "redmi:23021raa2y": "Redmi Note 12",
321
+ "xiaomi:m2007j1sc": "Mi 10 Ultra",
322
+ "asus:asus_ai2401_c": "ROG Phone 8 series",
323
+ "samsung:sm-g780f": "Galaxy S20 FE",
324
+ "samsung:sm-n960u": "Galaxy Note9",
325
+ "nothing:a065": "Nothing Phone (2)",
326
+ "oneplus:eb2103": "OnePlus Nord CE 5G",
327
+ "samsung:sm-a226b": "Galaxy A22 5G",
328
+ "xiaomi:m2002j9g": "Mi 10 lite 5G",
329
+ "samsung:sm-f721u1": "Galaxy Z Flip4",
330
+ "honor:eli-nx9": "HONOR 200",
331
+ "vivo:v2309": "X100 Pro",
332
+ "oppo:cph2197": "CPH2197",
333
+ "poco:m2012k11ag": "POCO F3",
334
+ "oneplus:phb110": "OnePlus 11 5G \u4e2d\u56fd\u7248",
335
+ "samsung:sm-s9260": "Galaxy S24+",
336
+ "motorola:motorola edge 2023": "motorola edge 2023",
337
+ "realme:rmx3840": "realme 12 Pro+ 5G",
338
+ "samsung:sm-n975u": "Galaxy Note10+",
339
+ "infinix:infinix x6711": "Infinix NOTE 30 5G",
340
+ "motorola:motorola edge 50 neo": "motorola edge 50 neo",
341
+ "sony:xq-dq62": "Xperia 1 V",
342
+ "vivo:v2346": "Y28s 5G",
343
+ "nothing:ain065": "Nothing Phone (2)",
344
+ "honor:bvl-n49": "HONOR Magic6 Pro",
345
+ "xiaomi:23078pnd5g": "Xiaomi 13T Pro",
346
+ "oneplus:mt2110": "OnePlus 9RT 5G",
347
+ "vivo:v2307a": "iQOO 12",
348
+ "poco:23049pcd8i": "POCO F5",
349
+ "vivo:v2143": "T1x",
350
+ "oppo:pgem10": "Find X6 Pro",
351
+ "samsung:sm-a325f": "Galaxy A32",
352
+ "infinix:infinix x669c": "Infinix HOT 30i",
353
+ "oneplus:cph2415": "OnePlus 10T 5G",
354
+ "realme:rmx3709": "realme GT3 240W",
355
+ "samsung:sm-g965u": "Galaxy S9+",
356
+ "realme:rmx3301": "realme GT 2 Pro",
357
+ "infinix:infinix x6871": "GT 20 Pro",
358
+ "xiaomi:m2007j3sy": "Mi 10T",
359
+ "tecno:tecno li9": "TECNO POVA 6 Pro 5G",
360
+ "samsung:sm-f741b": "Galaxy Z Flip6",
361
+ "motorola:moto g64 5g": "moto g64 5G",
362
+ "motorola:moto e(6) plus": "moto e\u2076 plus",
363
+ "oppo:cph1823": "F9",
364
+ "realme:rmx3851": "realme GT 6",
365
+ "samsung:sm-n975w": "Galaxy Note10+",
366
+ "vivo:v2336": "Y200e 5G",
367
+ "huawei:evr-l29": "Huawei Mate 20 X",
368
+ "honor:ntn-lx1": "HONOR 50 Lite",
369
+ "samsung:sm-n9750": "Galaxy Note10+",
370
+ "lge:lm-v500n": "LG V50 ThinQ",
371
+ "xiaomi:mi 9t pro": "Mi 9T Pro",
372
+ "oneplus:pgkm10": "OnePlus Ace",
373
+ "xiaomi:m2011j18c": "Xiaomi MIX Fold",
374
+ "samsung:sm-s901u": "Galaxy S22",
375
+ "vivo:v2162a": "V2162A",
376
+ "oneplus:le2115": "OnePlus 9 5G",
377
+ "samsung:sm-a225f": "Galaxy A22",
378
+ "nokia:n1374dl": "Nokia G300",
379
+ "unihertz:titan slim": "Titan Slim",
380
+ "oppo:cph2305": "Find X5 Pro",
381
+ "samsung:sm-a235f": "Galaxy A23",
382
+ "oneplus:ne2215": "OnePlus 10 Pro 5G",
383
+ "samsung:sm-n975f": "Galaxy Note10+",
384
+ "samsung:sm-s9280": "Galaxy S24 Ultra",
385
+ "redmi:2312dra50g": "Redmi Note 13 Pro 5G",
386
+ "xiaomi:2107113sr": "Xiaomi 11T Pro",
387
+ "samsung:sm-m236b": "Galaxy M23 5G",
388
+ "poco:22021211rg": "POCO F4",
389
+ "vivo:v2339a": "iQOO Neo9 Pro",
390
+ "doogee:s cyber": "S cyber",
391
+ "oneplus:kb2003": "OnePlus 8T",
392
+ "tecno:tecno bg6": "SPARK Go 2024",
393
+ "motorola:moto g play - 2024": "moto g play - 2024",
394
+ "oneplus:opd2403": "Oneplus Pad2",
395
+ "xiaomi:2410crp4ci": "Xiaomi Pad 7",
396
+ "realme:rmx3870": "realme P1 5G",
397
+ "oukitel:rt9": "RT9_EEA",
398
+ "realme:rmx3823": "realme GT5 240W",
399
+ "redmi:22127rk46c": "Redmi K60 Pro",
400
+ "oppo:pkc110": "Find X8 Pro",
401
+ "samsung:sm-f926n": "Galaxy Z Fold3 5G",
402
+ "oneplus:pja110": "Oneplus Ace 2 Pro",
403
+ "realme:rmx3686": "realme 10 Pro+ 5G",
404
+ "motorola:moto g stylus 5g - 2023": "moto g stylus 5G - 2023",
405
+ "samsung:sm-f9460": "Galaxy Z Fold5",
406
+ "samsung:sm-n976u": "Galaxy Note10+ 5G",
407
+ "vivo:v2337a": "X Fold3 Pro",
408
+ "vivo:v2205": "Y35",
409
+ "samsung:scg13": "Galaxy S22",
410
+ "samsung:sm-s908n": "Galaxy S22 Ultra",
411
+ "xiaomi:2106118c": "MIX 4",
412
+ "samsung:sm-m526b": "Galaxy M52 5G",
413
+ "redmi:2409brn2ca": "Redmi 14C",
414
+ "8849:tank 3": "TANK3",
415
+ "samsung:sm-t865": "Galaxy Tab S6",
416
+ "huawei:jkm-lx1": "HUAWEI Y8s",
417
+ "infinix:infinix x669": "Infinix HOT 30i",
418
+ "oppo:phn110": "Find N3",
419
+ "asus:asus_ai2205_c": "ROG Phone 7 (AI2205)",
420
+ "samsung:sm-a536e": "Galaxy A53 5G",
421
+ "samsung:sm-s908u": "Galaxy S22 Ultra",
422
+ "samsung:sm-g991b": "Galaxy S21 5G",
423
+ "sony:xq-ct72": "Xperia 1 IV",
424
+ "huawei:eml-al00": "P20",
425
+ "samsung:sm-x906b": "Galaxy Tab S8 Ultra 5G",
426
+ "samsung:sm-a035f": "Galaxy A03",
427
+ "samsung:sm-a705fn": "Galaxy A70",
428
+ "sony:h8296": "Xperia XZ2",
429
+ "realme:rmx3241": "realme 8 5G",
430
+ "zte:a202zt": "A202ZT",
431
+ "t-mobile:tmrv075g": "REVVL 7"
432
+ }
src/utils/device_lookup.py CHANGED
@@ -1,6 +1,262 @@
1
- # https://gist.github.com/adamawolf/3048717
 
 
 
 
 
2
 
3
- def get_device_name(device_id, default_device_name="Unknown"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  """
5
  Get the normalized device name from a device ID like iPad16,1
6
 
@@ -10,221 +266,67 @@ def get_device_name(device_id, default_device_name="Unknown"):
10
  Returns:
11
  str: The normalized device name without connectivity info
12
  """
13
- device_mapping = {
14
- "Watch1,1": "Apple Watch 38mm case",
15
- "Watch1,2": "Apple Watch 42mm case",
16
- "Watch2,3": "Apple Watch Series 2 38mm case",
17
- "Watch2,4": "Apple Watch Series 2 42mm case",
18
- "Watch2,6": "Apple Watch Series 1 38mm case",
19
- "Watch2,7": "Apple Watch Series 1 42mm case",
20
- "Watch3,1": "Apple Watch Series 3 38mm case",
21
- "Watch3,2": "Apple Watch Series 3 42mm case",
22
- "Watch3,3": "Apple Watch Series 3 38mm case",
23
- "Watch3,4": "Apple Watch Series 3 42mm case",
24
- "Watch4,1": "Apple Watch Series 4 40mm case",
25
- "Watch4,2": "Apple Watch Series 4 44mm case",
26
- "Watch4,3": "Apple Watch Series 4 40mm case",
27
- "Watch4,4": "Apple Watch Series 4 44mm case",
28
- "Watch5,1": "Apple Watch Series 5 40mm case",
29
- "Watch5,10": "Apple Watch SE 44mm case",
30
- "Watch5,11": "Apple Watch SE 40mm case",
31
- "Watch5,12": "Apple Watch SE 44mm case",
32
- "Watch5,2": "Apple Watch Series 5 44mm case",
33
- "Watch5,3": "Apple Watch Series 5 40mm case",
34
- "Watch5,4": "Apple Watch Series 5 44mm case",
35
- "Watch5,9": "Apple Watch SE 40mm case",
36
- "Watch6,1": "Apple Watch Series 6 40mm case",
37
- "Watch6,10": "Apple Watch SE 40mm case",
38
- "Watch6,11": "Apple Watch SE 44mm case",
39
- "Watch6,12": "Apple Watch SE 40mm case",
40
- "Watch6,13": "Apple Watch SE 44mm case",
41
- "Watch6,14": "Apple Watch Series 8 41mm case",
42
- "Watch6,15": "Apple Watch Series 8 45mm case",
43
- "Watch6,16": "Apple Watch Series 8 41mm case",
44
- "Watch6,17": "Apple Watch Series 8 45mm case",
45
- "Watch6,18": "Apple Watch Ultra",
46
- "Watch6,2": "Apple Watch Series 6 44mm case",
47
- "Watch6,3": "Apple Watch Series 6 40mm case",
48
- "Watch6,4": "Apple Watch Series 6 44mm case",
49
- "Watch6,6": "Apple Watch Series 7 41mm case",
50
- "Watch6,7": "Apple Watch Series 7 45mm case",
51
- "Watch6,8": "Apple Watch Series 7 41mm case",
52
- "Watch6,9": "Apple Watch Series 7 45mm case",
53
- "Watch7,1": "Apple Watch Series 9 41mm case",
54
- "Watch7,10": "Apple Watch Series 10 42mm case",
55
- "Watch7,11": "Apple Watch Series 10 46mm",
56
- "Watch7,2": "Apple Watch Series 9 45mm case",
57
- "Watch7,3": "Apple Watch Series 9 41mm case",
58
- "Watch7,4": "Apple Watch Series 9 45mm case",
59
- "Watch7,5": "Apple Watch Ultra 2",
60
- "Watch7,8": "Apple Watch Series 10 42mm case",
61
- "Watch7,9": "Apple Watch Series 10 46mm case (GPS",
62
- "arm64": "iPhone Simulator",
63
- "i386": "iPhone Simulator",
64
- "iPad1,1": "iPad",
65
- "iPad1,2": "iPad 3G",
66
- "iPad11,1": "iPad mini 5th Gen",
67
- "iPad11,2": "iPad mini 5th Gen",
68
- "iPad11,3": "iPad Air 3rd Gen",
69
- "iPad11,4": "iPad Air 3rd Gen",
70
- "iPad11,6": "iPad 8th Gen",
71
- "iPad11,7": "iPad 8th Gen",
72
- "iPad12,1": "iPad 9th Gen",
73
- "iPad12,2": "iPad 9th Gen",
74
- "iPad13,1": "iPad Air 4th Gen",
75
- "iPad13,10": "iPad Pro 12.9 inch 5th Gen",
76
- "iPad13,11": "iPad Pro 12.9 inch 5th Gen",
77
- "iPad13,16": "iPad Air 5th Gen",
78
- "iPad13,17": "iPad Air 5th Gen",
79
- "iPad13,18": "iPad 10th Gen",
80
- "iPad13,19": "iPad 10th Gen",
81
- "iPad13,2": "iPad Air 4th Gen",
82
- "iPad13,4": "iPad Pro 11 inch 5th Gen",
83
- "iPad13,5": "iPad Pro 11 inch 5th Gen",
84
- "iPad13,6": "iPad Pro 11 inch 5th Gen",
85
- "iPad13,7": "iPad Pro 11 inch 5th Gen",
86
- "iPad13,8": "iPad Pro 12.9 inch 5th Gen",
87
- "iPad13,9": "iPad Pro 12.9 inch 5th Gen",
88
- "iPad14,1": "iPad mini 6th Gen",
89
- "iPad14,10": "iPad Air 13 inch 6th Gen",
90
- "iPad14,11": "iPad Air 13 inch 6th Gen",
91
- "iPad14,2": "iPad mini 6th Gen",
92
- "iPad14,3": "iPad Pro 11 inch 4th Gen",
93
- "iPad14,4": "iPad Pro 11 inch 4th Gen",
94
- "iPad14,5": "iPad Pro 12.9 inch 6th Gen",
95
- "iPad14,6": "iPad Pro 12.9 inch 6th Gen",
96
- "iPad14,8": "iPad Air 11 inch 6th Gen",
97
- "iPad14,9": "iPad Air 11 inch 6th Gen",
98
- "iPad15,3": "iPad Air 11-inch 7th Gen",
99
- "iPad15,4": "iPad Air 11-inch 7th Gen",
100
- "iPad15,5": "iPad Air 13-inch 7th Gen",
101
- "iPad15,6": "iPad Air 13-inch 7th Gen",
102
- "iPad15,7": "iPad 11th Gen",
103
- "iPad15,8": "iPad 11th Gen",
104
- "iPad16,1": "iPad mini 7th Gen",
105
- "iPad16,2": "iPad mini 7th Gen",
106
- "iPad16,3": "iPad Pro 11 inch 5th Gen",
107
- "iPad16,4": "iPad Pro 11 inch 5th Gen",
108
- "iPad16,5": "iPad Pro 12.9 inch 7th Gen",
109
- "iPad16,6": "iPad Pro 12.9 inch 7th Gen",
110
- "iPad2,1": "2nd Gen iPad",
111
- "iPad2,2": "2nd Gen iPad",
112
- "iPad2,3": "2nd Gen iPad",
113
- "iPad2,4": "2nd Gen iPad New Revision",
114
- "iPad2,5": "iPad mini",
115
- "iPad2,6": "iPad mini",
116
- "iPad2,7": "iPad mini",
117
- "iPad3,1": "3rd Gen iPad",
118
- "iPad3,2": "3rd Gen iPad",
119
- "iPad3,3": "3rd Gen iPad",
120
- "iPad3,4": "4th Gen iPad",
121
- "iPad3,5": "4th Gen iPad",
122
- "iPad3,6": "4th Gen iPad",
123
- "iPad4,1": "iPad Air",
124
- "iPad4,2": "iPad Air",
125
- "iPad4,3": "1st Gen iPad Air",
126
- "iPad4,4": "iPad mini Retina",
127
- "iPad4,5": "iPad mini Retina",
128
- "iPad4,6": "iPad mini Retina",
129
- "iPad4,7": "iPad mini 3",
130
- "iPad4,8": "iPad mini 3",
131
- "iPad4,9": "iPad Mini 3",
132
- "iPad5,1": "iPad mini 4",
133
- "iPad5,2": "4th Gen iPad mini",
134
- "iPad5,3": "iPad Air 2",
135
- "iPad5,4": "iPad Air 2",
136
- "iPad6,11": "iPad (2017)",
137
- "iPad6,12": "iPad (2017)",
138
- "iPad6,3": "iPad Pro (9.7 inch)",
139
- "iPad6,4": "iPad Pro (9.7 inch)",
140
- "iPad6,7": "iPad Pro (12.9 inch)",
141
- "iPad6,8": "iPad Pro (12.9 inch)",
142
- "iPad7,1": "iPad Pro 2nd Gen",
143
- "iPad7,11": "iPad 7th Gen 10.2-inch",
144
- "iPad7,12": "iPad 7th Gen 10.2-inch",
145
- "iPad7,2": "iPad Pro 2nd Gen",
146
- "iPad7,3": "iPad Pro 10.5-inch 2nd Gen",
147
- "iPad7,4": "iPad Pro 10.5-inch 2nd Gen",
148
- "iPad7,5": "iPad 6th Gen",
149
- "iPad7,6": "iPad 6th Gen",
150
- "iPad8,1": "iPad Pro 11 inch 3rd Gen",
151
- "iPad8,10": "iPad Pro 11 inch 4th Gen",
152
- "iPad8,11": "iPad Pro 12.9 inch 4th Gen",
153
- "iPad8,12": "iPad Pro 12.9 inch 4th Gen",
154
- "iPad8,2": "iPad Pro 11 inch 3rd Gen",
155
- "iPad8,3": "iPad Pro 11 inch 3rd Gen",
156
- "iPad8,4": "iPad Pro 11 inch 3rd Gen",
157
- "iPad8,5": "iPad Pro 12.9 inch 3rd Gen",
158
- "iPad8,6": "iPad Pro 12.9 inch 3rd Gen",
159
- "iPad8,7": "iPad Pro 12.9 inch 3rd Gen",
160
- "iPad8,8": "iPad Pro 12.9 inch 3rd Gen",
161
- "iPad8,9": "iPad Pro 11 inch 4th Gen",
162
- "iPhone1,1": "iPhone",
163
- "iPhone1,2": "iPhone 3G",
164
- "iPhone10,1": "iPhone 8",
165
- "iPhone10,2": "iPhone 8 Plus",
166
- "iPhone10,3": "iPhone X",
167
- "iPhone10,4": "iPhone 8",
168
- "iPhone10,5": "iPhone 8 Plus",
169
- "iPhone10,6": "iPhone X",
170
- "iPhone11,2": "iPhone XS",
171
- "iPhone11,4": "iPhone XS Max",
172
- "iPhone11,6": "iPhone XS Max",
173
- "iPhone11,8": "iPhone XR",
174
- "iPhone12,1": "iPhone 11",
175
- "iPhone12,3": "iPhone 11 Pro",
176
- "iPhone12,5": "iPhone 11 Pro Max",
177
- "iPhone12,8": "iPhone SE 2nd Gen",
178
- "iPhone13,1": "iPhone 12 Mini",
179
- "iPhone13,2": "iPhone 12",
180
- "iPhone13,3": "iPhone 12 Pro",
181
- "iPhone13,4": "iPhone 12 Pro Max",
182
- "iPhone14,2": "iPhone 13 Pro",
183
- "iPhone14,3": "iPhone 13 Pro Max",
184
- "iPhone14,4": "iPhone 13 Mini",
185
- "iPhone14,5": "iPhone 13",
186
- "iPhone14,6": "iPhone SE 3rd Gen",
187
- "iPhone14,7": "iPhone 14",
188
- "iPhone14,8": "iPhone 14 Plus",
189
- "iPhone15,2": "iPhone 14 Pro",
190
- "iPhone15,3": "iPhone 14 Pro Max",
191
- "iPhone15,4": "iPhone 15",
192
- "iPhone15,5": "iPhone 15 Plus",
193
- "iPhone16,1": "iPhone 15 Pro",
194
- "iPhone16,2": "iPhone 15 Pro Max",
195
- "iPhone17,1": "iPhone 16 Pro",
196
- "iPhone17,2": "iPhone 16 Pro Max",
197
- "iPhone17,3": "iPhone 16",
198
- "iPhone17,4": "iPhone 16 Plus",
199
- "iPhone17,5": "iPhone 16e",
200
- "iPhone2,1": "iPhone 3GS",
201
- "iPhone3,1": "iPhone 4",
202
- "iPhone3,2": "iPhone 4",
203
- "iPhone3,3": "iPhone 4",
204
- "iPhone4,1": "iPhone 4S",
205
- "iPhone5,1": "iPhone 5",
206
- "iPhone5,2": "iPhone 5",
207
- "iPhone5,3": "iPhone 5C",
208
- "iPhone5,4": "iPhone 5C",
209
- "iPhone6,1": "iPhone 5S",
210
- "iPhone6,2": "iPhone 5S",
211
- "iPhone7,1": "iPhone 6 Plus",
212
- "iPhone7,2": "iPhone 6",
213
- "iPhone8,1": "iPhone 6s",
214
- "iPhone8,2": "iPhone 6s Plus",
215
- "iPhone8,4": "iPhone SE",
216
- "iPhone9,1": "iPhone 7",
217
- "iPhone9,2": "iPhone 7 Plus",
218
- "iPhone9,3": "iPhone 7",
219
- "iPhone9,4": "iPhone 7 Plus",
220
- "iPod1,1": "1st Gen iPod",
221
- "iPod2,1": "2nd Gen iPod",
222
- "iPod3,1": "3rd Gen iPod",
223
- "iPod4,1": "4th Gen iPod",
224
- "iPod5,1": "5th Gen iPod",
225
- "iPod7,1": "6th Gen iPod",
226
- "iPod9,1": "7th Gen iPod",
227
- "x86_64": "iPhone Simulator",
228
- }
229
-
230
- return device_mapping.get(device_id, default_device_name)
 
1
+ import requests
2
+ from urllib.parse import quote
3
+ from functools import lru_cache
4
+ import os
5
+ import json
6
+ from functools import lru_cache
7
 
8
+ apple_device_mapping = {
9
+ "Watch1,1": "Apple Watch 38mm case",
10
+ "Watch1,2": "Apple Watch 42mm case",
11
+ "Watch2,3": "Apple Watch Series 2 38mm case",
12
+ "Watch2,4": "Apple Watch Series 2 42mm case",
13
+ "Watch2,6": "Apple Watch Series 1 38mm case",
14
+ "Watch2,7": "Apple Watch Series 1 42mm case",
15
+ "Watch3,1": "Apple Watch Series 3 38mm case",
16
+ "Watch3,2": "Apple Watch Series 3 42mm case",
17
+ "Watch3,3": "Apple Watch Series 3 38mm case",
18
+ "Watch3,4": "Apple Watch Series 3 42mm case",
19
+ "Watch4,1": "Apple Watch Series 4 40mm case",
20
+ "Watch4,2": "Apple Watch Series 4 44mm case",
21
+ "Watch4,3": "Apple Watch Series 4 40mm case",
22
+ "Watch4,4": "Apple Watch Series 4 44mm case",
23
+ "Watch5,1": "Apple Watch Series 5 40mm case",
24
+ "Watch5,10": "Apple Watch SE 44mm case",
25
+ "Watch5,11": "Apple Watch SE 40mm case",
26
+ "Watch5,12": "Apple Watch SE 44mm case",
27
+ "Watch5,2": "Apple Watch Series 5 44mm case",
28
+ "Watch5,3": "Apple Watch Series 5 40mm case",
29
+ "Watch5,4": "Apple Watch Series 5 44mm case",
30
+ "Watch5,9": "Apple Watch SE 40mm case",
31
+ "Watch6,1": "Apple Watch Series 6 40mm case",
32
+ "Watch6,10": "Apple Watch SE 40mm case",
33
+ "Watch6,11": "Apple Watch SE 44mm case",
34
+ "Watch6,12": "Apple Watch SE 40mm case",
35
+ "Watch6,13": "Apple Watch SE 44mm case",
36
+ "Watch6,14": "Apple Watch Series 8 41mm case",
37
+ "Watch6,15": "Apple Watch Series 8 45mm case",
38
+ "Watch6,16": "Apple Watch Series 8 41mm case",
39
+ "Watch6,17": "Apple Watch Series 8 45mm case",
40
+ "Watch6,18": "Apple Watch Ultra",
41
+ "Watch6,2": "Apple Watch Series 6 44mm case",
42
+ "Watch6,3": "Apple Watch Series 6 40mm case",
43
+ "Watch6,4": "Apple Watch Series 6 44mm case",
44
+ "Watch6,6": "Apple Watch Series 7 41mm case",
45
+ "Watch6,7": "Apple Watch Series 7 45mm case",
46
+ "Watch6,8": "Apple Watch Series 7 41mm case",
47
+ "Watch6,9": "Apple Watch Series 7 45mm case",
48
+ "Watch7,1": "Apple Watch Series 9 41mm case",
49
+ "Watch7,10": "Apple Watch Series 10 42mm case",
50
+ "Watch7,11": "Apple Watch Series 10 46mm",
51
+ "Watch7,2": "Apple Watch Series 9 45mm case",
52
+ "Watch7,3": "Apple Watch Series 9 41mm case",
53
+ "Watch7,4": "Apple Watch Series 9 45mm case",
54
+ "Watch7,5": "Apple Watch Ultra 2",
55
+ "Watch7,8": "Apple Watch Series 10 42mm case",
56
+ "Watch7,9": "Apple Watch Series 10 46mm case (GPS",
57
+ "arm64": "iPhone Simulator",
58
+ "i386": "iPhone Simulator",
59
+ "iPad1,1": "iPad",
60
+ "iPad1,2": "iPad 3G",
61
+ "iPad11,1": "iPad mini 5th Gen",
62
+ "iPad11,2": "iPad mini 5th Gen",
63
+ "iPad11,3": "iPad Air 3rd Gen",
64
+ "iPad11,4": "iPad Air 3rd Gen",
65
+ "iPad11,6": "iPad 8th Gen",
66
+ "iPad11,7": "iPad 8th Gen",
67
+ "iPad12,1": "iPad 9th Gen",
68
+ "iPad12,2": "iPad 9th Gen",
69
+ "iPad13,1": "iPad Air 4th Gen",
70
+ "iPad13,10": "iPad Pro 12.9 inch 5th Gen",
71
+ "iPad13,11": "iPad Pro 12.9 inch 5th Gen",
72
+ "iPad13,16": "iPad Air 5th Gen",
73
+ "iPad13,17": "iPad Air 5th Gen",
74
+ "iPad13,18": "iPad 10th Gen",
75
+ "iPad13,19": "iPad 10th Gen",
76
+ "iPad13,2": "iPad Air 4th Gen",
77
+ "iPad13,4": "iPad Pro 11 inch 5th Gen",
78
+ "iPad13,5": "iPad Pro 11 inch 5th Gen",
79
+ "iPad13,6": "iPad Pro 11 inch 5th Gen",
80
+ "iPad13,7": "iPad Pro 11 inch 5th Gen",
81
+ "iPad13,8": "iPad Pro 12.9 inch 5th Gen",
82
+ "iPad13,9": "iPad Pro 12.9 inch 5th Gen",
83
+ "iPad14,1": "iPad mini 6th Gen",
84
+ "iPad14,10": "iPad Air 13 inch 6th Gen",
85
+ "iPad14,11": "iPad Air 13 inch 6th Gen",
86
+ "iPad14,2": "iPad mini 6th Gen",
87
+ "iPad14,3": "iPad Pro 11 inch 4th Gen",
88
+ "iPad14,4": "iPad Pro 11 inch 4th Gen",
89
+ "iPad14,5": "iPad Pro 12.9 inch 6th Gen",
90
+ "iPad14,6": "iPad Pro 12.9 inch 6th Gen",
91
+ "iPad14,8": "iPad Air 11 inch 6th Gen",
92
+ "iPad14,9": "iPad Air 11 inch 6th Gen",
93
+ "iPad15,3": "iPad Air 11-inch 7th Gen",
94
+ "iPad15,4": "iPad Air 11-inch 7th Gen",
95
+ "iPad15,5": "iPad Air 13-inch 7th Gen",
96
+ "iPad15,6": "iPad Air 13-inch 7th Gen",
97
+ "iPad15,7": "iPad 11th Gen",
98
+ "iPad15,8": "iPad 11th Gen",
99
+ "iPad16,1": "iPad mini 7th Gen",
100
+ "iPad16,2": "iPad mini 7th Gen",
101
+ "iPad16,3": "iPad Pro 11 inch 5th Gen",
102
+ "iPad16,4": "iPad Pro 11 inch 5th Gen",
103
+ "iPad16,5": "iPad Pro 12.9 inch 7th Gen",
104
+ "iPad16,6": "iPad Pro 12.9 inch 7th Gen",
105
+ "iPad2,1": "2nd Gen iPad",
106
+ "iPad2,2": "2nd Gen iPad",
107
+ "iPad2,3": "2nd Gen iPad",
108
+ "iPad2,4": "2nd Gen iPad New Revision",
109
+ "iPad2,5": "iPad mini",
110
+ "iPad2,6": "iPad mini",
111
+ "iPad2,7": "iPad mini",
112
+ "iPad3,1": "3rd Gen iPad",
113
+ "iPad3,2": "3rd Gen iPad",
114
+ "iPad3,3": "3rd Gen iPad",
115
+ "iPad3,4": "4th Gen iPad",
116
+ "iPad3,5": "4th Gen iPad",
117
+ "iPad3,6": "4th Gen iPad",
118
+ "iPad4,1": "iPad Air",
119
+ "iPad4,2": "iPad Air",
120
+ "iPad4,3": "1st Gen iPad Air",
121
+ "iPad4,4": "iPad mini Retina",
122
+ "iPad4,5": "iPad mini Retina",
123
+ "iPad4,6": "iPad mini Retina",
124
+ "iPad4,7": "iPad mini 3",
125
+ "iPad4,8": "iPad mini 3",
126
+ "iPad4,9": "iPad Mini 3",
127
+ "iPad5,1": "iPad mini 4",
128
+ "iPad5,2": "4th Gen iPad mini",
129
+ "iPad5,3": "iPad Air 2",
130
+ "iPad5,4": "iPad Air 2",
131
+ "iPad6,11": "iPad (2017)",
132
+ "iPad6,12": "iPad (2017)",
133
+ "iPad6,3": "iPad Pro (9.7 inch)",
134
+ "iPad6,4": "iPad Pro (9.7 inch)",
135
+ "iPad6,7": "iPad Pro (12.9 inch)",
136
+ "iPad6,8": "iPad Pro (12.9 inch)",
137
+ "iPad7,1": "iPad Pro 2nd Gen",
138
+ "iPad7,11": "iPad 7th Gen 10.2-inch",
139
+ "iPad7,12": "iPad 7th Gen 10.2-inch",
140
+ "iPad7,2": "iPad Pro 2nd Gen",
141
+ "iPad7,3": "iPad Pro 10.5-inch 2nd Gen",
142
+ "iPad7,4": "iPad Pro 10.5-inch 2nd Gen",
143
+ "iPad7,5": "iPad 6th Gen",
144
+ "iPad7,6": "iPad 6th Gen",
145
+ "iPad8,1": "iPad Pro 11 inch 3rd Gen",
146
+ "iPad8,10": "iPad Pro 11 inch 4th Gen",
147
+ "iPad8,11": "iPad Pro 12.9 inch 4th Gen",
148
+ "iPad8,12": "iPad Pro 12.9 inch 4th Gen",
149
+ "iPad8,2": "iPad Pro 11 inch 3rd Gen",
150
+ "iPad8,3": "iPad Pro 11 inch 3rd Gen",
151
+ "iPad8,4": "iPad Pro 11 inch 3rd Gen",
152
+ "iPad8,5": "iPad Pro 12.9 inch 3rd Gen",
153
+ "iPad8,6": "iPad Pro 12.9 inch 3rd Gen",
154
+ "iPad8,7": "iPad Pro 12.9 inch 3rd Gen",
155
+ "iPad8,8": "iPad Pro 12.9 inch 3rd Gen",
156
+ "iPad8,9": "iPad Pro 11 inch 4th Gen",
157
+ "iPhone1,1": "iPhone",
158
+ "iPhone1,2": "iPhone 3G",
159
+ "iPhone10,1": "iPhone 8",
160
+ "iPhone10,2": "iPhone 8 Plus",
161
+ "iPhone10,3": "iPhone X",
162
+ "iPhone10,4": "iPhone 8",
163
+ "iPhone10,5": "iPhone 8 Plus",
164
+ "iPhone10,6": "iPhone X",
165
+ "iPhone11,2": "iPhone XS",
166
+ "iPhone11,4": "iPhone XS Max",
167
+ "iPhone11,6": "iPhone XS Max",
168
+ "iPhone11,8": "iPhone XR",
169
+ "iPhone12,1": "iPhone 11",
170
+ "iPhone12,3": "iPhone 11 Pro",
171
+ "iPhone12,5": "iPhone 11 Pro Max",
172
+ "iPhone12,8": "iPhone SE 2nd Gen",
173
+ "iPhone13,1": "iPhone 12 Mini",
174
+ "iPhone13,2": "iPhone 12",
175
+ "iPhone13,3": "iPhone 12 Pro",
176
+ "iPhone13,4": "iPhone 12 Pro Max",
177
+ "iPhone14,2": "iPhone 13 Pro",
178
+ "iPhone14,3": "iPhone 13 Pro Max",
179
+ "iPhone14,4": "iPhone 13 Mini",
180
+ "iPhone14,5": "iPhone 13",
181
+ "iPhone14,6": "iPhone SE 3rd Gen",
182
+ "iPhone14,7": "iPhone 14",
183
+ "iPhone14,8": "iPhone 14 Plus",
184
+ "iPhone15,2": "iPhone 14 Pro",
185
+ "iPhone15,3": "iPhone 14 Pro Max",
186
+ "iPhone15,4": "iPhone 15",
187
+ "iPhone15,5": "iPhone 15 Plus",
188
+ "iPhone16,1": "iPhone 15 Pro",
189
+ "iPhone16,2": "iPhone 15 Pro Max",
190
+ "iPhone17,1": "iPhone 16 Pro",
191
+ "iPhone17,2": "iPhone 16 Pro Max",
192
+ "iPhone17,3": "iPhone 16",
193
+ "iPhone17,4": "iPhone 16 Plus",
194
+ "iPhone17,5": "iPhone 16e",
195
+ "iPhone2,1": "iPhone 3GS",
196
+ "iPhone3,1": "iPhone 4",
197
+ "iPhone3,2": "iPhone 4",
198
+ "iPhone3,3": "iPhone 4",
199
+ "iPhone4,1": "iPhone 4S",
200
+ "iPhone5,1": "iPhone 5",
201
+ "iPhone5,2": "iPhone 5",
202
+ "iPhone5,3": "iPhone 5C",
203
+ "iPhone5,4": "iPhone 5C",
204
+ "iPhone6,1": "iPhone 5S",
205
+ "iPhone6,2": "iPhone 5S",
206
+ "iPhone7,1": "iPhone 6 Plus",
207
+ "iPhone7,2": "iPhone 6",
208
+ "iPhone8,1": "iPhone 6s",
209
+ "iPhone8,2": "iPhone 6s Plus",
210
+ "iPhone8,4": "iPhone SE",
211
+ "iPhone9,1": "iPhone 7",
212
+ "iPhone9,2": "iPhone 7 Plus",
213
+ "iPhone9,3": "iPhone 7",
214
+ "iPhone9,4": "iPhone 7 Plus",
215
+ "iPod1,1": "1st Gen iPod",
216
+ "iPod2,1": "2nd Gen iPod",
217
+ "iPod3,1": "3rd Gen iPod",
218
+ "iPod4,1": "4th Gen iPod",
219
+ "iPod5,1": "5th Gen iPod",
220
+ "iPod7,1": "6th Gen iPod",
221
+ "iPod9,1": "7th Gen iPod",
222
+ "x86_64": "iPhone Simulator",
223
+ }
224
+
225
+ # Cache for Android device names
226
+ CACHE_FILE = os.path.join(
227
+ os.path.dirname(os.path.abspath(__file__)), "android_device_cache.json"
228
+ )
229
+ android_device_cache = {}
230
+
231
+
232
+ # Load cache from file if it exists
233
+ def load_cache():
234
+ global android_device_cache
235
+ try:
236
+ if os.path.exists(CACHE_FILE):
237
+ with open(CACHE_FILE, "r") as f:
238
+ android_device_cache = json.load(f)
239
+ print(f"Loaded {len(android_device_cache)} Android device names from cache")
240
+ except Exception as e:
241
+ print(f"Error loading Android device cache: {str(e)}")
242
+ android_device_cache = {}
243
+
244
+
245
+ # Save cache to file
246
+ def save_cache():
247
+ try:
248
+ with open(CACHE_FILE, "w") as f:
249
+ json.dump(android_device_cache, f, indent=2)
250
+ except Exception as e:
251
+ print(f"Error saving Android device cache: {str(e)}")
252
+
253
+
254
+ # Load cache on module import
255
+ load_cache()
256
+
257
+
258
+ @lru_cache(maxsize=1024)
259
+ def get_device_name(manufacturer, device_id, default_device_name):
260
  """
261
  Get the normalized device name from a device ID like iPad16,1
262
 
 
266
  Returns:
267
  str: The normalized device name without connectivity info
268
  """
269
+
270
+ if manufacturer == "Apple":
271
+ return apple_device_mapping.get(device_id, default_device_name)
272
+ else:
273
+ return get_android_model_name(manufacturer, device_id)
274
+
275
+
276
+ def get_android_model_name(manufacturer, model):
277
+ """
278
+ Get a user-friendly Android device name from cache or GitHub repository
279
+
280
+ Args:
281
+ manufacturer (str): Device manufacturer
282
+ model (str): Device model
283
+
284
+ Returns:
285
+ str: User-friendly device name, or original model if not found
286
+ """
287
+ # https://github.com/openhoangnc/android_model_name
288
+
289
+ # Create a cache key by combining manufacturer and model
290
+ cache_key = f"{manufacturer.lower()}:{model.lower()}"
291
+
292
+ # Check if we already have this device in our cache
293
+ if cache_key in android_device_cache:
294
+ # Return the cached result
295
+ return android_device_cache[cache_key]
296
+
297
+ # If not in cache, fetch from GitHub
298
+ repo_url = "https://raw.githubusercontent.com/openhoangnc/android_model_name/main"
299
+
300
+ # Prepare the URL path components
301
+ if not manufacturer:
302
+ # Return the model if manufacturer is empty
303
+ return model
304
+
305
+ first_letter = manufacturer[0].lower()
306
+ safe_manufacturer = quote(manufacturer.lower())
307
+ safe_model = quote(model.replace("/", "-").lower()) if model else ""
308
+
309
+ # Build the query URL
310
+ query_url = f"{repo_url}/{first_letter}/{safe_manufacturer}/{safe_model}"
311
+
312
+ try:
313
+ # Fetch the device name from the repository
314
+ response = requests.get(query_url, timeout=3)
315
+ if response.status_code == 200:
316
+ device_name = response.text.strip()
317
+ # Cache the result
318
+ android_device_cache[cache_key] = device_name
319
+ # Save cache periodically (every 10 new entries)
320
+ if len(android_device_cache) % 10 == 0:
321
+ save_cache()
322
+ return device_name
323
+ return model
324
+ except Exception as e:
325
+ print(f"Error fetching Android model name: {str(e)}")
326
+ return model
327
+
328
+
329
+ # Make sure to save the cache when the program exits
330
+ import atexit
331
+
332
+ atexit.register(save_cache)