Skip to content

Commit 4a668c3

Browse files
authored
Merge pull request #6 from HikaruHokkyokusei/master
New source for Images and few misc. updates
2 parents f1bd680 + 89857d8 commit 4a668c3

File tree

5 files changed

+183
-113
lines changed

5 files changed

+183
-113
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ venv.bak/
102102

103103
# mypy
104104
.mypy_cache/
105+
106+
/.idea/

anicon.ico

26.4 KB
Binary file not shown.

anicon.py

+173-113
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,191 @@
1+
import os
2+
import re
3+
import traceback
14
from warnings import filterwarnings
5+
26
from PIL import Image, ImageOps
37
from jikanpy import Jikan
8+
# noinspection PyPackageRequirements
9+
from mal import AnimeSearch
410
from requests import get
5-
from time import sleep
6-
import re
7-
import os
811

9-
print('''Run this in your anime folder
10-
For help, info and memes, check out
11-
https://github.com/notdedsec/anicon
12-
''')
13-
14-
sleep(1)
15-
jikan = Jikan()
1612
filterwarnings("ignore")
17-
folderlist = next(os.walk('.'))[1]
18-
if folderlist is None or len(folderlist) == 0:
19-
# In case the file is placed inside an inner most directory which contains only files and no other folders, this list will be empty.
20-
# Thus adding the current directory path as an element of the list.
21-
folderlist = [str(os.getcwd())]
22-
automode = True if input('Use AutoMode? Y/N : ').upper() == 'Y' else False
23-
24-
def getname(name: str) -> str:
25-
26-
lastwords = ['bd', 's0', '480p', '720p', '1080p']
27-
wordstoremove = ['bluray', 'x265', 'x264', 'hevc', 'hi10p', 'avc', '10bit', 'dual', 'audio', 'eng', 'english', 'subbed', 'sub', 'dubbed', 'dub']
28-
29-
name = name.lower().replace('_', ' ').replace('.', ' ')
30-
31-
for word in wordstoremove:
32-
name = name.replace(word, '')
33-
34-
name = re.sub(r"(?<=\[)(.*?)(?=\])", '', name)
35-
name = re.sub(r"(?<=\()(.*?)(?=\))", '', name)
36-
name = name.replace('()', '').replace('[]', '')
37-
38-
for word in lastwords:
39-
rexstr = "(?<=" + word + ")(?s)(.*$)"
40-
name = re.sub(rexstr, '', name).replace(word, '')
41-
42-
return(name.strip())
43-
44-
def getartwork(name: str) -> tuple:
45-
46-
results = jikan.search('anime', name, parameters={'type': 'tv'})
47-
48-
print('\n' + name.title(), end = '')
49-
counter = 1
50-
for result in results['results']:
51-
if automode:
52-
print(' - ' + result['title'])
53-
ch = 1
54-
break
55-
else:
56-
print('\n' + str(counter) + ' - ' + result['title'], end = '')
57-
58-
if counter == 5:
59-
break
60-
counter += 1
61-
62-
if not automode:
63-
ch = input('\n>')
64-
if ch == '':
65-
ch = 1
66-
67-
return (results['results'][int(ch)-1]['image_url'], results['results'][int(ch)-1]['type'])
68-
69-
def createicon(folder: str, link: str):
13+
jikan = Jikan()
7014

71-
art = get(link)
72-
open(jpgfile, 'wb').write(art.content)
7315

74-
img = Image.open(jpgfile)
16+
def get_name(folder_name: str) -> str:
17+
last_words = ['bd', 's0', '480p', '720p', '1080p']
18+
words_to_remove = ['bluray', 'x265', 'x264', 'hevc', 'hi10p', 'avc', '10bit', 'dual', 'audio', 'eng', 'english',
19+
'subbed', 'sub', 'dubbed', 'dub']
20+
21+
folder_name = folder_name.lower().replace('_', ' ').replace('.', ' ')
22+
23+
for word in words_to_remove:
24+
folder_name = folder_name.replace(word, '')
25+
26+
folder_name = re.sub(r"(?<=\[)(.*?)(?=])", '', folder_name)
27+
folder_name = re.sub(r"(?<=\()(.*?)(?=\))", '', folder_name)
28+
folder_name = folder_name.replace('()', '').replace('[]', '')
29+
30+
for word in last_words:
31+
regex_str = "(?<=" + word + ")(?s)(.*$)"
32+
folder_name = re.sub(regex_str, '', folder_name).replace(word, '')
33+
34+
return folder_name.strip()
35+
36+
37+
def get_artwork(anime_name: str, max_results: int = 5, mode: str = "mal-api") -> tuple:
38+
print('\n' + anime_name.title())
39+
40+
counter, choice = 1, 0
41+
if mode == "mal-api":
42+
results = AnimeSearch(anime_name).results
43+
for result in results:
44+
if auto_mode:
45+
print(' - ' + result.title)
46+
choice = 1
47+
break
48+
else:
49+
print(str(counter) + ' - ' + result.title)
50+
51+
if counter == max_results:
52+
break
53+
counter += 1
54+
elif mode == "jikanpy":
55+
results = jikan.search('anime', anime_name, parameters={'type': 'tv'})
56+
for result in results['results']:
57+
if auto_mode:
58+
print(' - ' + result['title'])
59+
choice = 1
60+
break
61+
else:
62+
print(str(counter) + ' - ' + result['title'])
63+
64+
if counter == max_results:
65+
break
66+
counter += 1
67+
else:
68+
raise Exception("Invalid mode specified")
69+
print("X - Skip this folder")
70+
71+
if not auto_mode:
72+
choice = input('> ')
73+
if choice == '':
74+
choice = 1
75+
elif choice.upper() == "X":
76+
return None, None
77+
choice = int(choice) - 1
78+
79+
image_url = results['results'][choice]['image_url'] if mode == "jikanpy" else results[choice].image_url
80+
image_type = results['results'][choice]['type'] if mode == "jikanpy" else results[choice].type
81+
82+
return image_url, image_type
83+
84+
85+
def create_icon(img_link: str):
86+
art = get(img_link)
87+
open(jpg_file, 'wb').write(art.content)
88+
89+
img = Image.open(jpg_file)
7590
img = ImageOps.expand(img, (69, 0, 69, 0), fill=0)
76-
img = ImageOps.fit(img, (300,300)).convert("RGBA")
77-
91+
img = ImageOps.fit(img, (300, 300)).convert("RGBA")
92+
7893
datas = img.getdata()
79-
newData = []
94+
new_data = []
8095
for item in datas:
8196
if item[0] == 0 and item[1] == 0 and item[2] == 0:
82-
newData.append((0, 0, 0, 0))
97+
new_data.append((0, 0, 0, 0))
8398
else:
84-
newData.append(item)
99+
new_data.append(item)
85100

86-
img.putdata(newData)
87-
os.remove(jpgfile)
88-
img.save(icofile)
101+
img.putdata(new_data)
102+
os.remove(jpg_file)
103+
img.save(ico_file)
89104
img.close()
90-
return(icofile)
105+
return ico_file
91106

92-
for folder in folderlist:
93-
name = getname(folder)
94107

95-
# Extracting the name of the folder without the path and then performing search for the same. This will be the name of the anime
96-
# episode, thus instead of performing a search for the directory path, now performing a search for the directory name.
97-
name = name.rpartition('\\')[2].strip()
98-
99-
iconname = name.replace(' ', '_')
100-
jpgfile = folder + '\\' + iconname + '.jpg'
101-
icofile = folder + '\\' + iconname + '.ico'
102-
103-
if os.path.isfile(icofile):
104-
print('An icon is already present. Delete the older icon and `desktop.ini` file before applying a new icon')
105-
continue
106-
107-
link, Type = getartwork(name)
108-
108+
if __name__ == "__main__":
109+
print("""\
110+
Run this in your anime folder
111+
For help, info and memes, check out
112+
https://github.com/notdedsec/anicon
113+
""")
114+
auto_mode = True if input('Use AutoMode? Y/N : ').upper() == 'Y' else False
115+
max_res = input("Max Results (default 5): ")
109116
try:
110-
icon = createicon(folder, link)
111-
except:
112-
print('Ran into an error. Blame the dev :(')
113-
continue
114-
115-
f = open(folder + "\\desktop.ini","w+")
116-
117-
f.write("[.ShellClassInfo]\nConfirmFileOp=0\n")
118-
f.write("IconResource={},0".format(icofile.replace(folder, "").strip("\\")))
119-
f.write("\nIconFile={}\nIconIndex=0".format(icofile.replace(folder, "").strip("\\")))
120-
121-
if Type is not None and len(Type) > 0:
122-
# If the result has a type, then using this as the infotip for the desktop icon.
123-
f.write("\nInfoTip={}".format(Type))
124-
125-
# Closing the output stream. All the text will be written into `desktop.ini` file only when the output is being closed.
126-
f.close()
127-
128-
# Not marking the `desktop.ini` file as a system file. This will make sure that the file can be seen if display hidden items is enabled.
129-
os.system('attrib +r \"{}\\{}\"'.format(os.getcwd(), folder))
130-
os.system('attrib +h \"{}\\desktop.ini\"'.format(folder))
131-
os.system('attrib +h \"{}\"'.format(icon))
117+
max_res = int(max_res)
118+
except ValueError:
119+
max_res = 5
120+
121+
lib_mode = input("""\
122+
123+
Image Source Library:
124+
1. mal-api (default)
125+
2. Jikanpy
126+
> """)
127+
if lib_mode == "2":
128+
lib_mode = "jikanpy"
129+
else:
130+
lib_mode = "mal-api"
131+
132+
folder_list = next(os.walk('.'))[1]
133+
if folder_list is None or len(folder_list) == 0:
134+
# In case the file is placed inside an innermost directory which contains only files and no other folders,
135+
# this list will be empty. Thus adding the current directory path as an element of the list.
136+
folder_list = [str(os.getcwd())]
137+
138+
for folder in folder_list:
139+
name = get_name(folder)
140+
141+
# Extracting the name of the folder without the path and then performing search for the same.
142+
# This will be the name of the anime episode, thus instead of performing a search for the directory path,
143+
# now performing a search for the directory name.
144+
name = name.rpartition('\\')[2].strip()
145+
146+
icon_name = re.sub("[^A-Za-z0-9_,. ()-]", "_", name)
147+
jpg_file = folder + '\\' + icon_name + '.jpg'
148+
ico_file = folder + '\\' + icon_name + '.ico'
149+
150+
if os.path.isfile(folder + "\\" + "desktop.ini"):
151+
print('An icon is already present. Delete the older icon and `desktop.ini` file before applying a new icon')
152+
continue
153+
154+
link, artwork_type = get_artwork(name, max_results=max_res, mode=lib_mode)
155+
if not link or not artwork_type:
156+
print("Skipping this folder...")
157+
continue
158+
159+
try:
160+
icon = create_icon(link)
161+
except Exception as e:
162+
print('Ran into an error while creating the icon object. Blame the dev :(')
163+
for line in traceback.format_exception(None, e, e.__traceback__):
164+
print(line, end="")
165+
continue
166+
167+
try:
168+
f = open(folder + "\\desktop.ini", "w+")
169+
170+
f.write("[.ShellClassInfo]\nConfirmFileOp=0\n")
171+
f.write("IconResource={},0".format(ico_file.replace(folder, "").strip("\\")))
172+
f.write("\nIconFile={}\nIconIndex=0".format(ico_file.replace(folder, "").strip("\\")))
173+
174+
if artwork_type is not None and len(artwork_type) > 0:
175+
# If the result has a type, then using this as the info-tip for the desktop icon.
176+
f.write("\nInfoTip={}".format(artwork_type))
177+
178+
# Closing the output stream.
179+
# All the text will be written into `desktop.ini` file only when the output is being closed.
180+
f.close()
181+
182+
# Not marking the `desktop.ini` file as a system file.
183+
# This will make sure that the file can be seen if display hidden items is enabled.
184+
os.system('attrib +r \"{}\\{}\"'.format(os.getcwd(), folder))
185+
os.system('attrib +h \"{}\\desktop.ini\"'.format(folder))
186+
os.system('attrib +h \"{}\"'.format(icon))
187+
except Exception as e:
188+
print('Ran into an error while creating files. Blame the dev :(')
189+
for line in traceback.format_exception(None, e, e.__traceback__):
190+
print(line, end="")
191+
continue

build.bat

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@echo off
2+
CALL venv/scripts/activate
3+
pyinstaller -F -i ./anicon.ico ./anicon.py

requirements.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
jikanpy
2+
requests
3+
pillow
4+
mal-api
5+
pyinstaller

0 commit comments

Comments
 (0)