aw-cli 2.1.1__tar.gz → 2.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aw_cli-2.1.1 → aw_cli-2.1.2}/PKG-INFO +4 -2
- {aw_cli-2.1.1 → aw_cli-2.1.2}/aw_cli.egg-info/PKG-INFO +4 -2
- {aw_cli-2.1.1 → aw_cli-2.1.2}/aw_cli.egg-info/requires.txt +1 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/awcli/anilist.py +8 -15
- {aw_cli-2.1.1 → aw_cli-2.1.2}/awcli/run.py +102 -118
- {aw_cli-2.1.1 → aw_cli-2.1.2}/awcli/utilities.py +31 -39
- aw_cli-2.1.2/awcli/version.py +1 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/setup.py +3 -2
- aw_cli-2.1.1/awcli/version.py +0 -1
- {aw_cli-2.1.1 → aw_cli-2.1.2}/LICENSE +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/README.md +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/aw_cli.egg-info/SOURCES.txt +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/aw_cli.egg-info/dependency_links.txt +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/aw_cli.egg-info/entry_points.txt +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/aw_cli.egg-info/top_level.txt +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/awcli/__init__.py +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/awcli/anime.py +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/awcli/arg_parser.py +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/setup.cfg +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/tests/test_anime.py +0 -0
- {aw_cli-2.1.1 → aw_cli-2.1.2}/tests/test_utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: aw-cli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: guarda anime dal terminale e molto altro!
|
|
5
5
|
Home-page: https://github.com/fexh10/aw-cli
|
|
6
6
|
Author: fexh10
|
|
@@ -12,11 +12,13 @@ Requires-Dist: requests
|
|
|
12
12
|
Requires-Dist: pySmartDL
|
|
13
13
|
Requires-Dist: wheel
|
|
14
14
|
Requires-Dist: regex
|
|
15
|
+
Requires-Dist: toml
|
|
15
16
|
Dynamic: author
|
|
16
17
|
Dynamic: description
|
|
17
18
|
Dynamic: description-content-type
|
|
18
19
|
Dynamic: home-page
|
|
19
20
|
Dynamic: license
|
|
21
|
+
Dynamic: license-file
|
|
20
22
|
Dynamic: requires-dist
|
|
21
23
|
Dynamic: requires-python
|
|
22
24
|
Dynamic: summary
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: aw-cli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: guarda anime dal terminale e molto altro!
|
|
5
5
|
Home-page: https://github.com/fexh10/aw-cli
|
|
6
6
|
Author: fexh10
|
|
@@ -12,11 +12,13 @@ Requires-Dist: requests
|
|
|
12
12
|
Requires-Dist: pySmartDL
|
|
13
13
|
Requires-Dist: wheel
|
|
14
14
|
Requires-Dist: regex
|
|
15
|
+
Requires-Dist: toml
|
|
15
16
|
Dynamic: author
|
|
16
17
|
Dynamic: description
|
|
17
18
|
Dynamic: description-content-type
|
|
18
19
|
Dynamic: home-page
|
|
19
20
|
Dynamic: license
|
|
21
|
+
Dynamic: license-file
|
|
20
22
|
Dynamic: requires-dist
|
|
21
23
|
Dynamic: requires-python
|
|
22
24
|
Dynamic: summary
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
|
|
3
|
-
tokenAnilist = "tokenAnilist: False"
|
|
4
|
-
user_id = 0
|
|
5
|
-
ratingAnilist = False
|
|
6
|
-
preferitoAnilist = False
|
|
7
|
-
dropAnilist = False
|
|
8
|
-
|
|
9
3
|
class TokenError(Exception):
|
|
10
4
|
pass
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
def updateAnilist(id_anilist: int, ep: int, status_list: str, score: float, favourite: bool = False) -> None:
|
|
6
|
+
def updateAnilist(token, id_anilist: int, ep: int, status_list: str, score: float, favourite: bool = False) -> None:
|
|
14
7
|
"""
|
|
15
8
|
Collegamento alle API di AniList per aggiornare lo stato dell'anime
|
|
16
9
|
|
|
@@ -47,10 +40,10 @@ def updateAnilist(id_anilist: int, ep: int, status_list: str, score: float, favo
|
|
|
47
40
|
if score != 0:
|
|
48
41
|
var["score"] = score
|
|
49
42
|
|
|
50
|
-
requestModifyAnilist(query, var)
|
|
43
|
+
requestModifyAnilist(token, query, var)
|
|
51
44
|
|
|
52
45
|
|
|
53
|
-
def getAnilistUserId() -> int:
|
|
46
|
+
def getAnilistUserId(token) -> int:
|
|
54
47
|
"""
|
|
55
48
|
Collegamento alle API di AniList per trovare
|
|
56
49
|
l'id dell'utente in base al token AniList dell'utente.
|
|
@@ -67,7 +60,7 @@ def getAnilistUserId() -> int:
|
|
|
67
60
|
}
|
|
68
61
|
"""
|
|
69
62
|
|
|
70
|
-
header_anilist = {'Authorization': 'Bearer ' +
|
|
63
|
+
header_anilist = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json', 'Accept': 'application/json'}
|
|
71
64
|
risposta = requests.post('https://graphql.anilist.co',headers=header_anilist,json={'query' : query})
|
|
72
65
|
if risposta.status_code != 200:
|
|
73
66
|
raise TokenError("Errore: Token AniList sbagliato")
|
|
@@ -77,7 +70,7 @@ def getAnilistUserId() -> int:
|
|
|
77
70
|
return user_id
|
|
78
71
|
|
|
79
72
|
|
|
80
|
-
def getAnimePrivateRating(id_anime: int) -> (float | None):
|
|
73
|
+
def getAnimePrivateRating(token, user_id, id_anime: int) -> (float | None):
|
|
81
74
|
"""
|
|
82
75
|
Collegamento alle API di AniList per trovare
|
|
83
76
|
il voto dato all'anime dall'utente.
|
|
@@ -102,7 +95,7 @@ def getAnimePrivateRating(id_anime: int) -> (float | None):
|
|
|
102
95
|
}
|
|
103
96
|
|
|
104
97
|
header_anilist = {
|
|
105
|
-
'Authorization': 'Bearer '
|
|
98
|
+
'Authorization': f'Bearer {token}',
|
|
106
99
|
'Content-Type': 'application/json', 'Accept': 'application/json'
|
|
107
100
|
}
|
|
108
101
|
|
|
@@ -113,7 +106,7 @@ def getAnimePrivateRating(id_anime: int) -> (float | None):
|
|
|
113
106
|
return float(risposta.json()["data"]["MediaList"]["score"])
|
|
114
107
|
|
|
115
108
|
|
|
116
|
-
def requestModifyAnilist(query: str, var: dict):
|
|
109
|
+
def requestModifyAnilist(token, query: str, var: dict):
|
|
117
110
|
"""
|
|
118
111
|
Request alle API di Anilist.
|
|
119
112
|
Se la richiesta non va a buon fine, viene stampato un errore.
|
|
@@ -123,7 +116,7 @@ def requestModifyAnilist(query: str, var: dict):
|
|
|
123
116
|
var (dict): dizionario che contiene le variabili da passare alla query.
|
|
124
117
|
"""
|
|
125
118
|
|
|
126
|
-
header_anilist = {'Authorization': 'Bearer ' +
|
|
119
|
+
header_anilist = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json', 'Accept': 'application/json'}
|
|
127
120
|
risposta = requests.post('https://graphql.anilist.co',headers=header_anilist,json={'query' : query, 'variables' : var})
|
|
128
121
|
|
|
129
122
|
if risposta.status_code != 200:
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import re
|
|
2
3
|
import csv
|
|
3
4
|
from signal import signal, SIGINT
|
|
4
5
|
from concurrent.futures import ThreadPoolExecutor
|
|
5
6
|
from pySmartDL import SmartDL
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from threading import Thread
|
|
8
|
-
from awcli
|
|
9
|
+
from awcli import anilist, utilities as ut
|
|
10
|
+
from awcli.anime import Anime
|
|
9
11
|
from awcli.arg_parser import *
|
|
10
|
-
import awcli.anilist as anilist
|
|
11
12
|
|
|
12
13
|
def safeExit():
|
|
13
14
|
with open(f"{os.path.dirname(__file__)}/aw-cronologia.csv", 'w', newline='', encoding='utf-8') as file:
|
|
@@ -33,7 +34,7 @@ def fzf(elementi: list[str], prompt: str = "> ", multi: bool = False, cls: bool
|
|
|
33
34
|
"""
|
|
34
35
|
|
|
35
36
|
if cls:
|
|
36
|
-
my_print("",end="", cls=True)
|
|
37
|
+
ut.my_print("", end="", cls=True)
|
|
37
38
|
string = "\n".join(elementi)
|
|
38
39
|
comando = f"""fzf --tac --height={len(elementi) + 2} --cycle --ansi --tiebreak=begin --prompt="{prompt}" """
|
|
39
40
|
if multi:
|
|
@@ -58,12 +59,12 @@ def RicercaAnime() -> list[Anime]:
|
|
|
58
59
|
def check_search(s: str):
|
|
59
60
|
if s == "exit":
|
|
60
61
|
safeExit()
|
|
61
|
-
result = search(s)
|
|
62
|
+
result = ut.search(s)
|
|
62
63
|
if len(result) != 0:
|
|
63
64
|
return result
|
|
64
65
|
|
|
65
|
-
my_print("", end="", cls=True)
|
|
66
|
-
return my_input("Cerca un anime", check_search,"La ricerca non ha prodotto risultati", cls = True)
|
|
66
|
+
ut.my_print("", end="", cls=True)
|
|
67
|
+
return ut.my_input("Cerca un anime", check_search,"La ricerca non ha prodotto risultati", cls = True)
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
def animeScaricati(path: str) -> list[Anime]:
|
|
@@ -79,7 +80,7 @@ def animeScaricati(path: str) -> list[Anime]:
|
|
|
79
80
|
nomi = os.listdir(path)
|
|
80
81
|
|
|
81
82
|
if len(nomi) == 0:
|
|
82
|
-
my_print("Nessun anime scaricato", color='rosso')
|
|
83
|
+
ut.my_print("Nessun anime scaricato", color='rosso')
|
|
83
84
|
safeExit()
|
|
84
85
|
|
|
85
86
|
animes = list[Anime]()
|
|
@@ -100,10 +101,10 @@ def scegliEpisodi() -> list[int]:
|
|
|
100
101
|
"""
|
|
101
102
|
|
|
102
103
|
|
|
103
|
-
my_print(anime.name, cls=True)
|
|
104
|
+
ut.my_print(anime.name, cls=True)
|
|
104
105
|
#se contiene solo 1 ep sarà riprodotto automaticamente
|
|
105
106
|
if anime.ep == 1:
|
|
106
|
-
return 1
|
|
107
|
+
return [1]
|
|
107
108
|
|
|
108
109
|
ep = [str(i) for i in range(anime.ep, anime.ep_ini - 1, -1)]
|
|
109
110
|
return sorted([int(ep) for ep in fzf(ep, "Scegli un episodio: ", multi=downl).split("\n")])
|
|
@@ -121,7 +122,7 @@ def downloadPath(create: bool = True) -> str:
|
|
|
121
122
|
str: il percorso di download dell'anime.
|
|
122
123
|
"""
|
|
123
124
|
|
|
124
|
-
if (nome_os == "Android"):
|
|
125
|
+
if (ut.nome_os == "Android"):
|
|
125
126
|
path = f"/sdcard/Movies/Anime"
|
|
126
127
|
else:
|
|
127
128
|
path = f"{Path.home()}/Videos/Anime"
|
|
@@ -144,12 +145,12 @@ def scaricaEpisodio(ep: int, path: str):
|
|
|
144
145
|
nome_video = anime.ep_name(ep)
|
|
145
146
|
|
|
146
147
|
# se l'episodio non è ancora stato scaricato lo scarico, altrimenti skippo
|
|
147
|
-
my_print(nome_video, color="blu", end=":\n")
|
|
148
|
+
ut.my_print(nome_video, color="blu", end=":\n")
|
|
148
149
|
if not os.path.exists(f"{path}/{nome_video}.mp4"):
|
|
149
150
|
SDL = SmartDL(url_ep, f"{path}/{nome_video}.mp4")
|
|
150
151
|
SDL.start()
|
|
151
152
|
else:
|
|
152
|
-
my_print("già scaricato, skippo...", color="giallo")
|
|
153
|
+
ut.my_print("già scaricato, skippo...", color="giallo")
|
|
153
154
|
|
|
154
155
|
def openSyncplay(url_ep: str, nome_video: str, progress: int) -> tuple[bool, int]:
|
|
155
156
|
"""
|
|
@@ -165,24 +166,24 @@ def openSyncplay(url_ep: str, nome_video: str, progress: int) -> tuple[bool, int
|
|
|
165
166
|
int: il progresso dell'episodio.
|
|
166
167
|
"""
|
|
167
168
|
|
|
168
|
-
if
|
|
169
|
-
my_print("Aggiornare il path di syncplay nella configurazione tramite: aw-cli -a", color="rosso")
|
|
169
|
+
if "syncplay" not in ut.configData:
|
|
170
|
+
ut.my_print("Aggiornare il path di syncplay nella configurazione tramite: aw-cli -a", color="rosso")
|
|
170
171
|
safeExit()
|
|
171
172
|
|
|
172
173
|
|
|
173
174
|
args = f'''--force-media-title="{nome_video}" --start="{progress}" --fullscreen --keep-open'''
|
|
174
|
-
if
|
|
175
|
+
if ut.configData["player"]["type"] == "vlc":
|
|
175
176
|
args = f'''--meta-title "{nome_video}" --start-time="{progress}" --fullscreen'''
|
|
176
177
|
|
|
177
178
|
try :
|
|
178
|
-
out = os.popen(f'''{
|
|
179
|
+
out = os.popen(f'''{ut.configData["syncplay"]["path"]} -d --language it "{url_ep}" -- {args} 2>&1''').read()
|
|
179
180
|
except UnicodeDecodeError:
|
|
180
181
|
out = ""
|
|
181
182
|
|
|
182
183
|
duration_match = re.findall(r'duration(?:-change)?"?: (\d+)\.?[\d]*', out)
|
|
183
184
|
progress_match = re.findall(r'pos(?:ition"?)?:? (\d+).?\d+', out)
|
|
184
185
|
if not duration_match:
|
|
185
|
-
my_print("Errore, impossibile leggere l'output di Syncplay!", color="rosso")
|
|
186
|
+
ut.my_print("Errore, impossibile leggere l'output di Syncplay!", color="rosso")
|
|
186
187
|
return False, 0
|
|
187
188
|
|
|
188
189
|
duration = max(map(int, duration_match))
|
|
@@ -207,11 +208,11 @@ def openMPV(url_ep: str, nome_video: str, progress: int) -> tuple[bool, int]:
|
|
|
207
208
|
"""
|
|
208
209
|
|
|
209
210
|
|
|
210
|
-
if (nome_os == "Android"):
|
|
211
|
+
if (ut.nome_os == "Android"):
|
|
211
212
|
os.system(f'''am start --user 0 -a android.intent.action.VIEW -d "{url_ep}" -n is.xyz.mpv/.MPVActivity > /dev/null 2>&1''')
|
|
212
213
|
return True, 0
|
|
213
214
|
|
|
214
|
-
out = os.popen(f'''{
|
|
215
|
+
out = os.popen(f'''{ut.configData["player"]["path"]} "{url_ep}" --force-media-title="{nome_video}" --start="{progress}" --fullscreen --keep-open 2>&1''')
|
|
215
216
|
|
|
216
217
|
res = re.findall(r'(\d+):(\d+):(\d+) / [\d:]+ \((\d+)%\)', out.read())[-1]
|
|
217
218
|
progress = (int(res[0]) * 3600) + (int(res[1]) * 60) + int(res[2])
|
|
@@ -233,11 +234,11 @@ def openVLC(url_ep: str, nome_video: str, progress: int) -> tuple[bool, int]:
|
|
|
233
234
|
int: il progresso dell'episodio.
|
|
234
235
|
"""
|
|
235
236
|
|
|
236
|
-
if nome_os == "Android":
|
|
237
|
+
if ut.nome_os == "Android":
|
|
237
238
|
os.system(f'''am start --user 0 -a android.intent.action.VIEW -d "{url_ep}" -n org.videolan.vlc/.StartActivity -e "title" "{nome_video}" > /dev/null 2>&1''')
|
|
238
239
|
return True, 0
|
|
239
240
|
|
|
240
|
-
os.system(f'''{
|
|
241
|
+
os.system(f'''{ut.configData["player"]["path"]} "{url_ep}" --meta-title "{nome_video}" --start-time="{progress}" --fullscreen > /dev/null 2>&1''')
|
|
241
242
|
|
|
242
243
|
# se il file di configurazione di VLC esiste, prendo la posizione dell'ultimo episodio riprodotto
|
|
243
244
|
progress = 0
|
|
@@ -318,7 +319,7 @@ def updateAnilist(ep: int, voto_anilist: float, drop: bool = False):
|
|
|
318
319
|
"""
|
|
319
320
|
|
|
320
321
|
if anime.id_anilist == 0:
|
|
321
|
-
my_print("Impossibile aggiornare AniList: id anime non trovato!", color="rosso")
|
|
322
|
+
ut.my_print("Impossibile aggiornare AniList: id anime non trovato!", color="rosso")
|
|
322
323
|
return
|
|
323
324
|
|
|
324
325
|
voto = 0
|
|
@@ -331,16 +332,16 @@ def updateAnilist(ep: int, voto_anilist: float, drop: bool = False):
|
|
|
331
332
|
status_list = 'COMPLETED'
|
|
332
333
|
|
|
333
334
|
#chiedo di votare
|
|
334
|
-
if anilist
|
|
335
|
+
if ut.configData["anilist"]["rating"]:
|
|
335
336
|
is_number = lambda n: float(n) if n.replace('.', '', 1).isdigit() else None
|
|
336
|
-
voto = my_input("Inserisci un voto per l'anime" + (f" (voto corrente: {voto_anilist})" if voto_anilist else ""), is_number)
|
|
337
|
+
voto = ut.my_input("Inserisci un voto per l'anime" + (f" (voto corrente: {voto_anilist})" if voto_anilist else ""), is_number)
|
|
337
338
|
|
|
338
339
|
#chiedo di mettere tra i preferiti
|
|
339
|
-
if anilist
|
|
340
|
-
my_print(f"Riproduco {anime.name} Ep. {anime.ep}", color="giallo", cls=True)
|
|
340
|
+
if ut.configData["anilist"]["favorite"] and status_list == 'COMPLETED':
|
|
341
|
+
ut.my_print(f"Riproduco {anime.name} Ep. {anime.ep}", color="giallo", cls=True)
|
|
341
342
|
preferiti = fzf(["sì","no"], "Mettere l'anime tra i preferiti? ") == "sì"
|
|
342
343
|
|
|
343
|
-
Thread(target=anilist.updateAnilist, args=(anime.id_anilist, ep, status_list, voto, preferiti)).start()
|
|
344
|
+
Thread(target=anilist.updateAnilist, args=(ut.configData["anilist"]["token"],anime.id_anilist, ep, status_list, voto, preferiti)).start()
|
|
344
345
|
|
|
345
346
|
|
|
346
347
|
def openVideos(ep: int):
|
|
@@ -358,18 +359,18 @@ def openVideos(ep: int):
|
|
|
358
359
|
path = f"{downloadPath(create=False)}/{anime.name}/{nome_video}.mp4"
|
|
359
360
|
|
|
360
361
|
if os.path.exists(path):
|
|
361
|
-
url_ep = "file://" + path if nome_os == "Android" else path
|
|
362
|
+
url_ep = "file://" + path if ut.nome_os == "Android" else path
|
|
362
363
|
elif offline:
|
|
363
|
-
my_print(f"Episodio {nome_video} non scaricato, skippo...", color='giallo')
|
|
364
|
+
ut.my_print(f"Episodio {nome_video} non scaricato, skippo...", color='giallo')
|
|
364
365
|
return
|
|
365
366
|
else:
|
|
366
367
|
url_ep = anime.get_episodio(ep)
|
|
367
368
|
|
|
368
|
-
if not (offline or privato) and anilist
|
|
369
|
+
if not (offline or privato) and "anilist" in ut.configData:
|
|
369
370
|
executor = ThreadPoolExecutor(max_workers=1)
|
|
370
|
-
voto_anilist = executor.submit(anilist.getAnimePrivateRating, anime.id_anilist)
|
|
371
|
+
voto_anilist = executor.submit(anilist.getAnimePrivateRating, ut.configData["anilist"]["token"], ut.configData["anilist"]["user_id"], anime.id_anilist)
|
|
371
372
|
|
|
372
|
-
my_print(f"Riproduco {nome_video}...", color="giallo", cls=True)
|
|
373
|
+
ut.my_print(f"Riproduco {nome_video}...", color="giallo", cls=True)
|
|
373
374
|
progress = anime.progress[ep]
|
|
374
375
|
completed, progress = openPlayer(url_ep, nome_video, progress)
|
|
375
376
|
|
|
@@ -379,7 +380,7 @@ def openVideos(ep: int):
|
|
|
379
380
|
progress = 0
|
|
380
381
|
anime.ep_corrente = ep
|
|
381
382
|
#update watchlist anilist se ho fatto l'accesso
|
|
382
|
-
if not offline and anilist
|
|
383
|
+
if not offline and "anilist" in ut.configData:
|
|
383
384
|
updateAnilist(ep, voto_anilist.result())
|
|
384
385
|
else:
|
|
385
386
|
anime.ep_corrente = ep - 1
|
|
@@ -418,80 +419,79 @@ def getCronologia() -> list[Anime]:
|
|
|
418
419
|
|
|
419
420
|
#se il file esiste ma non contiene dati stampo un messaggio di errore
|
|
420
421
|
if len(animes) == 0:
|
|
421
|
-
my_print("Cronologia inesistente!", color='rosso')
|
|
422
|
+
ut.my_print("Cronologia inesistente!", color='rosso')
|
|
422
423
|
safeExit()
|
|
423
424
|
return animes
|
|
424
425
|
|
|
425
426
|
|
|
426
427
|
def setupConfig() -> None:
|
|
427
428
|
"""
|
|
428
|
-
Crea un file di configurazione chiamato "
|
|
429
|
+
Crea un file di configurazione chiamato "config.toml"
|
|
429
430
|
nella stessa directory dello script.
|
|
430
431
|
Le informazioni riportate saranno scelte dall'utente.
|
|
431
432
|
Sarà possibile scegliere il Player predefinito,
|
|
432
433
|
se collegare il proprio profilo AniList e
|
|
433
434
|
se inserire il path di syncplay.
|
|
434
435
|
"""
|
|
436
|
+
ut.configData.clear()
|
|
437
|
+
|
|
435
438
|
#player predefinito
|
|
436
|
-
my_print("", end="", cls=True)
|
|
437
|
-
my_print("AW-CLI - CONFIGURAZIONE", color="giallo")
|
|
439
|
+
ut.my_print("", end="", cls=True)
|
|
440
|
+
ut.my_print("AW-CLI - CONFIGURAZIONE", color="giallo")
|
|
438
441
|
|
|
439
|
-
player
|
|
440
|
-
if nome_os != "Android":
|
|
441
|
-
res = os.popen(f"whereis -b {player} 2>&1").read().removeprefix(f"{player}:").strip().split()
|
|
442
|
+
ut.configData["player"]["type"] = fzf(["vlc","mpv"], "Scegli il player predefinito: ")
|
|
443
|
+
if ut.nome_os != "Android":
|
|
444
|
+
res = os.popen(f"whereis -b {ut.configData["player"]["type"]} 2>&1").read().removeprefix(f"{ut.configData["player"]["type"]}:").strip().split()
|
|
442
445
|
if len(res) == 0:
|
|
443
|
-
my_print(f"Player {player} non trovato!", color="rosso")
|
|
444
|
-
player = my_input(f"Inserisci il path di {player} manualmente se è installato")
|
|
446
|
+
ut.my_print(f"Player {ut.configData["player"]["type"]} non trovato!", color="rosso")
|
|
447
|
+
ut.configData["player"]["path"] = ut.my_input(f"Inserisci il path di {ut.configData["player"]["type"]} manualmente se è installato")
|
|
445
448
|
else:
|
|
446
|
-
player = res[0]
|
|
447
|
-
my_print("AW-CLI - CONFIGURAZIONE", color="giallo", cls=True)
|
|
449
|
+
ut.configData["player"]["path"] = res[0]
|
|
450
|
+
ut.my_print("AW-CLI - CONFIGURAZIONE", color="giallo", cls=True)
|
|
448
451
|
|
|
449
|
-
#
|
|
450
|
-
ratingAnilist = "ratingAnilist: False"
|
|
451
|
-
preferitoAnilist = "preferitoAnilist: False"
|
|
452
|
-
dropAnilist = "dropAnilist: False"
|
|
453
|
-
|
|
452
|
+
#anilist
|
|
454
453
|
if fzf(["sì","no"], "Aggiornare automaticamente la watchlist con AniList? ") == "sì":
|
|
455
454
|
link = "https://anilist.co/api/v2/oauth/authorize?client_id=11388&response_type=token"
|
|
456
|
-
if nome_os == "
|
|
457
|
-
os.system(f"xdg-open '{link}' > /dev/null 2>&1")
|
|
458
|
-
else:
|
|
455
|
+
if ut.nome_os == "Darwin":
|
|
459
456
|
os.system(f"open '{link}' > /dev/null 2>&1")
|
|
457
|
+
else:
|
|
458
|
+
os.system(f"xdg-open '{link}' > /dev/null 2>&1")
|
|
459
|
+
|
|
460
460
|
|
|
461
461
|
#inserimento token
|
|
462
|
-
anilist
|
|
463
|
-
|
|
462
|
+
ut.configData["anilist"]["token"] = ut.my_input(f"Inserire il token di AniList ({link})", cls=True)
|
|
463
|
+
|
|
464
464
|
#prendo l'id dell'utente tramite query
|
|
465
465
|
with ThreadPoolExecutor() as executor:
|
|
466
|
-
|
|
467
|
-
|
|
466
|
+
ut.configData["anilist"]["rating"], ut.configData["anilist"]["favorite"], ut.configData["anilist"]["drop"] = False, False, False
|
|
467
|
+
future = executor.submit(anilist.getAnilistUserId, ut.configData["anilist"]["token"])
|
|
468
|
+
ut.my_print("AW-CLI - CONFIGURAZIONE", color="giallo", cls=True)
|
|
468
469
|
if fzf(["sì","no"], "Votare l'anime una volta completato? ") == "sì":
|
|
469
|
-
|
|
470
|
+
ut.configData["anilist"]["rating"] = True
|
|
470
471
|
|
|
471
472
|
if fzf(["sì","no"], "Chiedere se mettere l'anime tra i preferiti una volta completato? ") == "sì":
|
|
472
|
-
|
|
473
|
+
ut.configData["anilist"]["favorite"] = True
|
|
473
474
|
|
|
474
475
|
if fzf(["sì","no"], "Chiedere se droppare l'anime una volta rimosso dalla cronologia? ") == "sì":
|
|
475
|
-
|
|
476
|
+
ut.configData["anilist"]["drop"] = True
|
|
476
477
|
|
|
477
|
-
anilist
|
|
478
|
+
ut.configData["anilist"]["user_id"] = future.result()
|
|
478
479
|
|
|
479
|
-
syncplay
|
|
480
|
-
if nome_os != "Android":
|
|
480
|
+
#syncplay
|
|
481
|
+
if ut.nome_os != "Android":
|
|
481
482
|
res = os.popen(f"whereis -b syncplay 2>&1").read().removeprefix(f"syncplay:").strip().split()
|
|
482
483
|
if len(res) == 0:
|
|
483
|
-
my_print("Syncplay non trovato!", color="rosso")
|
|
484
|
-
syncplay = my_input(f"Inserisci il path di Syncplay (premere INVIO se non lo si desidera utilizzare)").replace("Program Files (x86)", "Progra~2")
|
|
484
|
+
ut.my_print("Syncplay non trovato!", color="rosso")
|
|
485
|
+
syncplay = ut.my_input(f"Inserisci il path di Syncplay (premere INVIO se non lo si desidera utilizzare)").replace("Program Files (x86)", "Progra~2")
|
|
486
|
+
if syncplay != "": ut.configData["syncplay"]["path"] = syncplay
|
|
485
487
|
else:
|
|
486
|
-
syncplay = res[0]
|
|
487
|
-
if syncplay == "":
|
|
488
|
-
syncplay = "Syncplay: None"
|
|
489
|
-
|
|
490
|
-
#creo il file
|
|
491
|
-
config = f"{os.path.dirname(__file__)}/aw.config"
|
|
492
|
-
with open(config, 'w') as config_file:
|
|
493
|
-
config_file.write(f"{player}\n{anilist.tokenAnilist}\n{ratingAnilist}\n{preferitoAnilist}\n{dropAnilist}\n{anilist.user_id}\n{syncplay}")
|
|
488
|
+
ut.configData["syncplay"]["path"] = res[0]
|
|
494
489
|
|
|
490
|
+
#creo il file
|
|
491
|
+
config = f"{os.path.dirname(__file__)}/config.toml"
|
|
492
|
+
with open(config, 'w') as f:
|
|
493
|
+
ut.toml.dump(ut.configData, f)
|
|
494
|
+
|
|
495
495
|
|
|
496
496
|
def reloadCrono(cronologia: list[Anime]):
|
|
497
497
|
"""
|
|
@@ -510,9 +510,9 @@ def reloadCrono(cronologia: list[Anime]):
|
|
|
510
510
|
if 0 not in [anime.status for anime in cronologia]:
|
|
511
511
|
return
|
|
512
512
|
|
|
513
|
-
my_print("Ricerco le nuove uscite...", color="giallo")
|
|
514
|
-
ultime_uscite = latest()
|
|
515
|
-
my_print(end="", cls=True)
|
|
513
|
+
ut.my_print("Ricerco le nuove uscite...", color="giallo")
|
|
514
|
+
ultime_uscite = ut.latest()
|
|
515
|
+
ut.my_print(end="", cls=True)
|
|
516
516
|
testo = []
|
|
517
517
|
|
|
518
518
|
for i, a in reversed(list(enumerate(cronologia))):
|
|
@@ -581,25 +581,20 @@ def removeFromCrono(number: int):
|
|
|
581
581
|
|
|
582
582
|
global log
|
|
583
583
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
if delete == "sì":
|
|
587
|
-
if anilist.dropAnilist:
|
|
588
|
-
drop = fzf(["sì","no"], f"Droppare {anime.name} su AniList? ")
|
|
589
|
-
|
|
590
|
-
if drop == "sì":
|
|
591
|
-
if anime.id_anilist == 0:
|
|
592
|
-
my_print("Impossibile droppare su AniList: id anime non trovato!", color="rosso")
|
|
593
|
-
sleep(1)
|
|
594
|
-
else:
|
|
595
|
-
updateAnilist(anime.ep_corrente, drop=True)
|
|
584
|
+
if fzf(["sì","no"], f"Si è sicuri di voler rimuovere {anime.name} dalla cronologia? ") == "no":
|
|
585
|
+
return
|
|
596
586
|
|
|
597
|
-
|
|
587
|
+
if "anilist" in ut.configData and ut.configData["anilist"]["drop"] and fzf(["sì","no"], f"Droppare {anime.name} su AniList? ") == "sì":
|
|
588
|
+
if anime.id_anilist == 0:
|
|
589
|
+
ut.my_print("Impossibile droppare su AniList: id anime non trovato!", color="rosso")
|
|
590
|
+
ut.sleep(1)
|
|
591
|
+
else:
|
|
592
|
+
updateAnilist(anime.ep_corrente, drop=True)
|
|
598
593
|
|
|
599
|
-
|
|
594
|
+
log.pop(number)
|
|
600
595
|
|
|
601
|
-
|
|
602
|
-
|
|
596
|
+
if fzf(["esci","continua"], cls=True) == "esci":
|
|
597
|
+
safeExit()
|
|
603
598
|
|
|
604
599
|
|
|
605
600
|
def updateScript():
|
|
@@ -607,7 +602,9 @@ def updateScript():
|
|
|
607
602
|
Aggiorna di default il programma in base
|
|
608
603
|
all'ultima versione stabile.
|
|
609
604
|
Se viene specificato il branch,
|
|
610
|
-
verrà installato
|
|
605
|
+
verrà installato que#se il file di configurazione non esiste viene chiesto all'utente di fare il setup
|
|
606
|
+
if args.avvia_config or not os.path.exists(f"{os.path.dirname(__file__)}/config.toml"):
|
|
607
|
+
setupConfig()st'ultimo.
|
|
611
608
|
"""
|
|
612
609
|
|
|
613
610
|
if args.update == None:
|
|
@@ -617,19 +614,16 @@ def updateScript():
|
|
|
617
614
|
|
|
618
615
|
os.system(comando)
|
|
619
616
|
|
|
620
|
-
my_print("aw-cli aggiornato con successo!", color="bianco")
|
|
617
|
+
ut.my_print("aw-cli aggiornato con successo!", color="bianco")
|
|
621
618
|
exit()
|
|
622
619
|
|
|
623
620
|
|
|
624
621
|
def main():
|
|
625
622
|
global log
|
|
626
623
|
global anime
|
|
627
|
-
global player_path
|
|
628
|
-
global syncplay_path
|
|
629
624
|
global openPlayer
|
|
630
625
|
global scelta_anime
|
|
631
626
|
global notSelected
|
|
632
|
-
global mpv
|
|
633
627
|
|
|
634
628
|
if update:
|
|
635
629
|
updateScript()
|
|
@@ -641,21 +635,14 @@ def main():
|
|
|
641
635
|
pass
|
|
642
636
|
|
|
643
637
|
#se il file di configurazione non esiste viene chiesto all'utente di fare il setup
|
|
644
|
-
if args.avvia_config or not os.path.exists(f"{os.path.dirname(__file__)}/
|
|
638
|
+
if args.avvia_config or not os.path.exists(f"{os.path.dirname(__file__)}/config.toml"):
|
|
645
639
|
setupConfig()
|
|
646
640
|
|
|
647
|
-
|
|
648
|
-
#se la prima riga del config corrisponde a una versione vecchia, faccio rifare il config
|
|
649
|
-
if player_path.startswith("Player") or mpv == None:
|
|
650
|
-
my_print("Ci sono stati dei cambiamenti nella configurazione...", color="giallo")
|
|
651
|
-
sleep(1)
|
|
652
|
-
setupConfig()
|
|
653
|
-
mpv, player_path, syncplay_path = getConfig()
|
|
641
|
+
ut.getConfig()
|
|
654
642
|
|
|
655
|
-
|
|
656
|
-
openPlayer = openMPV if mpv else openVLC
|
|
643
|
+
openPlayer = openMPV if ut.configData["player"]["type"] == "mpv" else openVLC
|
|
657
644
|
|
|
658
|
-
if nome_os != "Android" and args.syncpl:
|
|
645
|
+
if ut.nome_os != "Android" and args.syncpl:
|
|
659
646
|
openPlayer = openSyncplay
|
|
660
647
|
|
|
661
648
|
reload = True
|
|
@@ -664,13 +651,13 @@ def main():
|
|
|
664
651
|
if cronologia:
|
|
665
652
|
animelist = getCronologia()
|
|
666
653
|
elif lista:
|
|
667
|
-
animelist = latest(args.lista)
|
|
654
|
+
animelist = ut.latest(args.lista)
|
|
668
655
|
else:
|
|
669
656
|
animelist = RicercaAnime()
|
|
670
657
|
if offline:
|
|
671
658
|
animelist = [anime for anime in animelist if anime.name in [a.name for a in animeScaricati(downloadPath())]]
|
|
672
659
|
|
|
673
|
-
my_print("", end="", cls=True)
|
|
660
|
+
ut.my_print("", end="", cls=True)
|
|
674
661
|
esci = True
|
|
675
662
|
if cronologia and args.cronologia != 'r':
|
|
676
663
|
notSelected = True
|
|
@@ -695,7 +682,7 @@ def main():
|
|
|
695
682
|
removeFromCrono(scelta)
|
|
696
683
|
continue
|
|
697
684
|
|
|
698
|
-
anime.load_info() if not offline else downloaded_episodes(anime,f"{downloadPath()}/{anime.name}")
|
|
685
|
+
anime.load_info() if not offline else ut.downloaded_episodes(anime,f"{downloadPath()}/{anime.name}")
|
|
699
686
|
|
|
700
687
|
if info:
|
|
701
688
|
anime.print_info()
|
|
@@ -704,8 +691,8 @@ def main():
|
|
|
704
691
|
continue
|
|
705
692
|
|
|
706
693
|
if anime.ep == 0:
|
|
707
|
-
my_print("Eh, volevi! L'anime non è ancora stato rilasciato", color="rosso")
|
|
708
|
-
sleep(1)
|
|
694
|
+
ut.my_print("Eh, volevi! L'anime non è ancora stato rilasciato", color="rosso")
|
|
695
|
+
ut.sleep(1)
|
|
709
696
|
reload = False
|
|
710
697
|
continue
|
|
711
698
|
|
|
@@ -716,8 +703,8 @@ def main():
|
|
|
716
703
|
anime.ep_corrente = listaEpisodi[0] - 1
|
|
717
704
|
|
|
718
705
|
if listaEpisodi[0] > anime.ep:
|
|
719
|
-
my_print(f"L'episodio {listaEpisodi[0]} di {anime.name} non è ancora stato rilasciato!", color='rosso')
|
|
720
|
-
sleep(1)
|
|
706
|
+
ut.my_print(f"L'episodio {listaEpisodi[0]} di {anime.name} non è ancora stato rilasciato!", color='rosso')
|
|
707
|
+
ut.sleep(1)
|
|
721
708
|
if len(animelist) == 1:
|
|
722
709
|
safeExit()
|
|
723
710
|
reload = False
|
|
@@ -731,7 +718,7 @@ def main():
|
|
|
731
718
|
for ep in listaEpisodi:
|
|
732
719
|
scaricaEpisodio(ep, path)
|
|
733
720
|
|
|
734
|
-
my_print(f"\nVideo scaricato correttamente!\nLo puoi trovare nella cartella {path}\n", color="verde")
|
|
721
|
+
ut.my_print(f"\nVideo scaricato correttamente!\nLo puoi trovare nella cartella {path}\n", color="verde")
|
|
735
722
|
|
|
736
723
|
risp = fzf(["esci","indietro","guarda"])
|
|
737
724
|
if risp == "esci":
|
|
@@ -769,13 +756,10 @@ def main():
|
|
|
769
756
|
reload = True
|
|
770
757
|
|
|
771
758
|
log = []
|
|
772
|
-
player_path = ""
|
|
773
|
-
syncplay_path = ""
|
|
774
759
|
scelta_anime = ""
|
|
775
760
|
openPlayer = None
|
|
776
761
|
notSelected = True
|
|
777
762
|
completeLimit = 90
|
|
778
|
-
mpv = True
|
|
779
763
|
|
|
780
764
|
anime = Anime("", "")
|
|
781
765
|
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
|
+
import toml
|
|
3
4
|
import requests
|
|
4
|
-
from platform import system
|
|
5
5
|
from time import sleep
|
|
6
6
|
from html import unescape
|
|
7
|
-
|
|
7
|
+
from collections import defaultdict
|
|
8
8
|
from awcli.anime import Anime
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
_url = "https://www.animeworld.so"
|
|
11
|
+
configData = defaultdict(dict)
|
|
12
|
+
|
|
11
13
|
# controllo il tipo del dispositivo
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
def get_os() -> str:
|
|
15
|
+
out = os.popen("uname -a").read().strip().split()
|
|
16
|
+
nome_os = out[0]
|
|
17
|
+
if nome_os == "Linux":
|
|
18
|
+
if "Android" == out[-1]:
|
|
19
|
+
nome_os = "Android"
|
|
20
|
+
elif "WSL" in out[2]:
|
|
21
|
+
nome_os = "WSL"
|
|
22
|
+
return nome_os
|
|
23
|
+
|
|
24
|
+
nome_os = get_os()
|
|
25
|
+
|
|
20
26
|
|
|
21
27
|
def my_print(text: str = "", format: int = 1, color: str = "bianco", bg_color: str = "nero", cls: bool = False, end: str = "\n"):
|
|
22
28
|
"""
|
|
@@ -234,40 +240,26 @@ def downloaded_episodes(anime: Anime, path: str) -> None:
|
|
|
234
240
|
anime.ep = massimo
|
|
235
241
|
anime.ep_ini = minimo
|
|
236
242
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
def getConfig() -> tuple[bool, str, str]:
|
|
243
|
+
|
|
244
|
+
def getConfig() -> None:
|
|
240
245
|
"""
|
|
241
246
|
Prende le impostazioni scelte dall'utente
|
|
242
247
|
dal file di configurazione.
|
|
243
248
|
|
|
244
249
|
Returns:
|
|
245
|
-
|
|
246
|
-
mpv restituisce True se è stato scelto MPV, altrimenti false se è VLC.
|
|
247
|
-
player_path restituisce il path del player predefinito.
|
|
248
|
-
syncplay_path restituisce il path di syncplay.
|
|
250
|
+
None
|
|
249
251
|
"""
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
anilist.tokenAnilist = lines[1]
|
|
263
|
-
anilist.ratingAnilist = True if lines[2] == "ratingAnilist: True" else False
|
|
264
|
-
anilist.preferitoAnilist = True if lines[3] == "preferitoAnilist: True" else False
|
|
265
|
-
anilist.dropAnilist = True if lines[4] == "dropAnilist: True" else False
|
|
266
|
-
anilist.user_id = int(lines[5])
|
|
267
|
-
|
|
268
|
-
syncplay_path = f"/mnt/c/Windows/System32/cmd.exe /C '{lines[6]}'" if wsl else lines[6]
|
|
269
|
-
return mpv, player_path, syncplay_path
|
|
270
|
-
|
|
252
|
+
global configData
|
|
253
|
+
|
|
254
|
+
configPath = f"{os.path.dirname(__file__)}/config.toml"
|
|
255
|
+
|
|
256
|
+
with open(configPath, 'r') as f:
|
|
257
|
+
configData = toml.load(f)
|
|
258
|
+
|
|
259
|
+
if nome_os == "WSL":
|
|
260
|
+
configData["player"]["path"] = f'''"$(wslpath '{configData["player"]["path"]}')"'''
|
|
261
|
+
if "syncplay" in configData:
|
|
262
|
+
configData["syncplay"]["path"] = f"/mnt/c/Windows/System32/cmd.exe /C '{configData["syncplay"]["path"]}'"
|
|
271
263
|
|
|
272
264
|
headers = {
|
|
273
265
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
versione = "2.1.2"
|
|
@@ -7,12 +7,13 @@ installRequires = [
|
|
|
7
7
|
"requests",
|
|
8
8
|
"pySmartDL",
|
|
9
9
|
"wheel",
|
|
10
|
-
"regex",
|
|
10
|
+
"regex",
|
|
11
|
+
"toml",]
|
|
11
12
|
|
|
12
13
|
setup(
|
|
13
14
|
name="aw-cli",
|
|
14
15
|
packages=find_packages(include=["awcli"]),
|
|
15
|
-
version="2.1.
|
|
16
|
+
version="2.1.2",
|
|
16
17
|
python_requires=">3.10",
|
|
17
18
|
description="guarda anime dal terminale e molto altro!",
|
|
18
19
|
long_description=long_description,
|
aw_cli-2.1.1/awcli/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
versione = "2.1.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|