-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
327 lines (260 loc) · 10.8 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
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
import json
import sys
import time
import requests
import os
import base64
"""To get the json response of the requested url."""
def jikanjson(query):
#print("Querying for ", query)
url = f'https://api.jikan.moe/v4/anime?q={query}&sfw=true'
try:
response = requests.get(url)
response.raise_for_status()
output = response.json()
#print(output['data'][0]['title'])
#print(output['data'][0]['images']['webp']['large_image_url'])
return output
except requests.exceptions.HTTPError:
#assume it's a too many requests error and sleep - I don't want to try to figrue out how to handle all of them, but that would obviously be a good thing to do
time.sleep(0.5)
return jikanjson(query) # try again
def load_json_file(file_path):
try:
with open(file_path, 'r') as json_file:
data = json.load(json_file)
return data
except FileNotFoundError:
print("File not found.")
return None
except json.JSONDecodeError:
print("Error decoding JSON.")
return None
def get_user_filters():
including = ["watched", "watching", "want to watch", "stalled", "dropped"]
print("Enter the numbers of the statuses you want to keep (comma-separated, e.g., 1,2) ")
print("[1: watched, 2: watching, 3: want to watch, 4: stalled, 5: dropped]")
print("Or press enter for default: watched only")
keep_indices = input()
if keep_indices:
try:
keep_indices = [int(index.strip())-1 for index in keep_indices.split(",")]
# Remove the specified indices from the list
including = [item for index, item in enumerate(including) if index in keep_indices]
except ValueError:
print("Invalid input. Please enter comma-separated indices.")
return get_user_filters()
else:
#print("Default action")
keep_indices = "0"
keep_indices = [int(index.strip()) for index in keep_indices.split(",")]
# Remove the specified indices from the list
including = [item for index, item in enumerate(including) if index in keep_indices]
print("-- Keeping only:", including)
return including
def filter_anime(json_data):
''' Filter out anime by status.'''
including = get_user_filters()
filtered = []
for entry in json_data['entries']:
if entry['status'] in including:
title, status, rating = entry['name'], entry['status'], entry['rating']
filtered.append((title, status, rating))
return filtered
def format_name(name):
sanitized_string = ""
for char in name:
# Check if the character is within the desired ASCII range
if ord(char) >= 32 and ord(char) <= 126:
sanitized_string += char
else:
# Replace characters outside the desired range with an empty string
sanitized_string += ""
return sanitized_string.replace(" ", "%20")
def get_all_images_urls(data):
new_anime_data = []
for anime in data:
my_response = jikanjson(format_name(anime[0]))
image = my_response['data'][0]['images']['webp']['large_image_url']
new_anime_entry = anime + (image,)
new_anime_data.append(new_anime_entry)
return new_anime_data
def download_images(image_list, output_dir):
# Create the output directory if it doesn't exist
if not os.path.exists(output_dir):
os.makedirs(output_dir)
list_with_filename = []
for name, status, rating, url in image_list:
# Get the filename from the URL
sanitized_name = name.replace('/', '_')
filename = os.path.join(output_dir, sanitized_name + ".webp")
# Download the image
response = requests.get(url)
if response.status_code == 200:
# Save the image to a file
with open(filename, 'wb') as f:
f.write(response.content)
list_with_filename.append((name, status, rating, url, filename))
else:
list_with_filename.append((name, status, rating, url, "unknown"))
return list_with_filename
def image_to_data_url(image_path):
with open(image_path, "rb") as img_file:
img_data = img_file.read()
base64_data = base64.b64encode(img_data).decode("utf-8")
mime_type = "image/" + image_path.split(".")[-1] # Extracting the file extension for MIME type
return "data:{};base64,{}".format(mime_type, base64_data)
def get_Data_URLs(data):
final_list = []
for name, status, rating, url, location in data:
final_list.append((name, status, rating, image_to_data_url(location)))
return final_list
def get_user_export_choice():
print("Enter 1 to set up the tierlist or 2 to auto-complete it")
user_choice = input()
if user_choice:
try:
if(int(user_choice) == 1):
print("-- Will export as prepared tierlist.")
return int(user_choice)
elif(int(user_choice) == 2):
print("-- Will export as auto-completed tierlist.")
return int(user_choice)
else:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_export_choice()
except ValueError:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_export_choice()
else:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_export_choice()
def export_as_json(input_data):
my_data = {'title': 'My TierList',
'rows': [{'name': 'S', 'imgs': []},
{'name': 'A', 'imgs': []},
{'name': 'B', 'imgs': []},
{'name': 'C', 'imgs': []},
{'name': 'D', 'imgs': []},
{'name': 'E', 'imgs': []},
{'name': 'F', 'imgs': []}],
'untiered': []}
all_data_urls = []
for name, status, rating, data_URL in input_data:
all_data_urls.append(data_URL)
my_data['untiered'].extend(all_data_urls)
filename = "AP_to_tierlist_export.json"
with open(filename, "w") as json_file:
json.dump(my_data, json_file, indent=4)
return my_data
def export_and_auto_complete(input_data):
modify_scheme = get_user_rating_scheme_choice()
if(modify_scheme == 1):
S, A, B, C, D, F = 10,8,6,4,2,1
else:
S, A, B, C, D, F = get_user_rating_scheme()
my_data = {'title': 'My TierList',
'rows': [{'name': 'S', 'imgs': []},
{'name': 'A', 'imgs': []},
{'name': 'B', 'imgs': []},
{'name': 'C', 'imgs': []},
{'name': 'D', 'imgs': []},
{'name': 'F', 'imgs': []}],
'untiered': []}
for name, status, rating, data_URL in input_data:
if(rating >= S/2.0):
my_data['rows'][0]['imgs'].append(data_URL)
elif(rating >= A/2.0):
my_data['rows'][1]['imgs'].append(data_URL)
elif(rating >= B/2.0):
my_data['rows'][2]['imgs'].append(data_URL)
elif(rating >= C/2.0):
my_data['rows'][3]['imgs'].append(data_URL)
elif(rating >= D/2.0):
my_data['rows'][4]['imgs'].append(data_URL)
elif(rating >= F/2.0):
my_data['rows'][5]['imgs'].append(data_URL)
else:
my_data['untiered'].append(data_URL)
filename = "AUTO_AP_to_tierlist_export.json"
with open(filename, "w") as json_file:
json.dump(my_data, json_file, indent=4)
return my_data
def get_user_rating_scheme_choice():
print("The predefined scheme is: [S:10, A:8-9, B:6-7, C:4-5, D:2-3, F:1]")
print("Enter 1 to use the predefined rating scheme or 2 to modify it")
user_choice = input()
if user_choice:
try:
if(int(user_choice) == 1):
return int(user_choice)
elif(int(user_choice) == 2):
return int(user_choice)
else:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_export_choice()
except ValueError:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_export_choice()
else:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_export_choice()
def get_user_rating_scheme():
rating_scheme = tuple()
for letter in ['S', 'A', 'B', 'C', 'D', 'F']:
print("Enter a minimum value for", letter)
rating_scheme = rating_scheme + (get_user_rating_scheme_helper(),) #could add a check here for successive entries being strictly smaller. For now, hope user is logical
return rating_scheme
def get_user_rating_scheme_helper():
user_choice = input()
if user_choice:
try:
selected_rating = int(user_choice)
if(selected_rating >= 0 and selected_rating <= 10):
return selected_rating
else:
#retry recursively
print("Invalid input. Please enter either 1 or 2")
return get_user_rating_scheme_helper()
except ValueError:
#retry recursively
print("Invalid input. Please enter a number between 0 and 10 (inclusive)")
return get_user_rating_scheme_helper()
else:
#retry recursively
print("Invalid input. Please enter a number between 0 and 10 (inclusive)")
return get_user_rating_scheme_helper()
def main():
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <filename>")
return 1
filename = sys.argv[1]
# Example usage
json_data = load_json_file(filename)
if json_data:
print("Anime Planet export loaded")
anime_data_pipe = filter_anime(json_data)
print("Successfully filtered anime")
export_mode = get_user_export_choice()
anime_data_pipe = get_all_images_urls(anime_data_pipe)
print("Obtained image links via Jikan API")
anime_data_pipe = download_images(anime_data_pipe, output_dir="images")
print("Downloaded images to local directory")
anime_data_pipe = get_Data_URLs(anime_data_pipe)
print("Converted images to Data URL")
if(export_mode == 1):
anime_data_pipe = export_as_json(anime_data_pipe)
else:
anime_data_pipe = export_and_auto_complete(anime_data_pipe)
print("Successfully exported as .json file to load into Tiers Master")
#print(json.dumps(json_data, indent=4))
else:
print("Failed to load JSON data.")
if __name__ == "__main__":
main()