Gesion des séries
This commit is contained in:
parent
3788f4147a
commit
45f97936f0
3 changed files with 126 additions and 40 deletions
6
file.py
6
file.py
|
@ -13,7 +13,7 @@ class File:
|
||||||
self.markers = {}
|
self.markers = {}
|
||||||
self.api_id = api_id
|
self.api_id = api_id
|
||||||
self.api_fileid = api_fileid
|
self.api_fileid = api_fileid
|
||||||
self.fileable_type = {None: None, 'App//Film':'film', 'App//Episode':'episode'}[api_fileable_type]
|
self.fileable_type = {None: None, 'App\\Film':'film', 'App\\Episode':'episode'}[api_fileable_type]
|
||||||
|
|
||||||
def get_ext(self):
|
def get_ext(self):
|
||||||
_, ext = posixpath.splitext(self.name)
|
_, ext = posixpath.splitext(self.name)
|
||||||
|
@ -64,9 +64,9 @@ class File:
|
||||||
# 7) type: épisode / film
|
# 7) type: épisode / film
|
||||||
if not self.fileable_type:
|
if not self.fileable_type:
|
||||||
for m in ['SERIE', 'EPISODE_NUM', 'SEASON_NUM']:
|
for m in ['SERIE', 'EPISODE_NUM', 'SEASON_NUM']:
|
||||||
if m in self.markers:
|
if m in self.info:
|
||||||
self.fileable_type = 'episode'
|
self.fileable_type = 'episode'
|
||||||
if not self.fileable_type and 'TITLE' in self.markers:
|
if (not self.fileable_type) and 'TITLE' in self.info:
|
||||||
self.fileable_type = 'film'
|
self.fileable_type = 'film'
|
||||||
|
|
||||||
def filename_same(self, other):
|
def filename_same(self, other):
|
||||||
|
|
138
main.py
138
main.py
|
@ -73,29 +73,33 @@ def visit_folder(domain, api, rules, tok):
|
||||||
Lapi = []
|
Lapi = []
|
||||||
for info in api.get_files(path=domain['server']+domain['path'], like=1, filable=1):
|
for info in api.get_files(path=domain['server']+domain['path'], like=1, filable=1):
|
||||||
nfo = {}
|
nfo = {}
|
||||||
if not info['filable']:
|
if ('filable' not in info) or ('filable_type' not in info):
|
||||||
print('nfo:', info) # le fileable associé a été supprimé
|
print('nfo:', info) # le fileable associé a été supprimé
|
||||||
else:
|
else:
|
||||||
year = int(info['filable']['release_date'][:4])
|
year = int(info['filable']['release_date'][:4])
|
||||||
nfo['YEAR'] = year
|
nfo['YEAR'] = year
|
||||||
F = file.File(info['path'][len(domain['server']):], info['name'], nfo, api_id=info['filable_id'], api_fileid=info['id'], api_fileable_type=info['fileable_type'])
|
F = file.File(info['path'][len(domain['server']):], info['name'], nfo, api_id=info['filable_id'], api_fileid=info['id'], api_fileable_type=info['filable_type'])
|
||||||
F.extract_title(tok)
|
F.extract_title(tok)
|
||||||
|
match = filerule.match_rules(F.path+'/'+F.name, rules)
|
||||||
|
if match:
|
||||||
|
F.info = match[1]
|
||||||
|
F.info['YEAR'] = nfo['YEAR'] # may not work :-(
|
||||||
Lapi.append(F)
|
Lapi.append(F)
|
||||||
print('total api for ',domain['server']+domain['path'],':', len(Lapi))
|
print('total api for ',domain['server']+domain['path'],':', len(Lapi))
|
||||||
|
|
||||||
# traite les films
|
# traite les films
|
||||||
Lfilm_loc = [f for f in Lloc if f.fileable_type == 'film']
|
Lfilm_loc = [f for f in Lloc if f.fileable_type == 'film']
|
||||||
Lfilm_api = [f for f in Lapi if f.fileable_type == 'film']
|
Lfilm_api = [f for f in Lapi if f.fileable_type == 'film']
|
||||||
handle_films(Lfilm_loc, Lfilm_api, api, rules, tok)
|
handle_films(Lfilm_loc, Lfilm_api, domain, api, rules, tok)
|
||||||
|
|
||||||
# traite les épisodes
|
# traite les épisodes
|
||||||
Lepisode_loc = [f for f in Lloc if f.fileable_type == 'episode']
|
Lepisode_loc = [f for f in Lloc if f.fileable_type == 'episode']
|
||||||
Lepisode_api = [f for f in Lapi if f.fileable_type == 'episode']
|
Lepisode_api = [f for f in Lapi if f.fileable_type == 'episode']
|
||||||
handle_episodes(Lepisode_loc, Lepisode_api, api, rules, tok)
|
handle_episodes(Lepisode_loc, Lepisode_api, domain, api, rules, tok)
|
||||||
|
|
||||||
print('visit finished ',domain['server']+domain['path'])
|
print('visit finished ',domain['server']+domain['path'])
|
||||||
|
|
||||||
def handle_films(Lfilm_loc, Lfilm_api, api, rules, tok):
|
def handle_films(Lfilm_loc, Lfilm_api, domain, api, rules, tok):
|
||||||
Lloc = Lfilm_loc
|
Lloc = Lfilm_loc
|
||||||
Lapi = Lfilm_api
|
Lapi = Lfilm_api
|
||||||
|
|
||||||
|
@ -165,13 +169,13 @@ def handle_films(Lfilm_loc, Lfilm_api, api, rules, tok):
|
||||||
for f, _ in Llink2:
|
for f, _ in Llink2:
|
||||||
Lunref.remove(f)
|
Lunref.remove(f)
|
||||||
|
|
||||||
print('invalid:\n'+'\n'.join(str(f.api_fileid)+' '+str(f) for f in Linvalid))
|
print('invalid:'+'\n'.join(str(f.api_fileid)+' '+str(f) for f in Linvalid))
|
||||||
print('missing (', len(Lmissing), '):\n','\n'.join([str(e.api_id)+':'+repr(e)+'('+e.title+')' for e in sorted(Lmissing, key=lambda e:e.title)]))
|
print('missing (', len(Lmissing), '):','\n'.join([str(e.api_id)+':'+repr(e)+'('+e.title+')' for e in sorted(Lmissing, key=lambda e:e.title)]))
|
||||||
print('\n'*3)
|
print('unreferenced:'+'\n'.join(str(f) for f in sorted(Lunref, key=lambda e:e.title)))
|
||||||
print('unreferenced:\n'+'\n'.join(str(f) for f in sorted(Lunref, key=lambda e:e.title)))
|
|
||||||
print('\n'*3)
|
|
||||||
#print('unreferenced titles:\n', '\n'.join(sorted([f.title for f in Lunref])))
|
#print('unreferenced titles:\n', '\n'.join(sorted([f.title for f in Lunref])))
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
# Supprime les fichiers invalides (dossiers/ ne répondent à aucune règle)
|
# Supprime les fichiers invalides (dossiers/ ne répondent à aucune règle)
|
||||||
for i, film in enumerate(Linvalid):
|
for i, film in enumerate(Linvalid):
|
||||||
print('['+str(i+1)+'/'+str(len(Linvalid))+']'+'invalid:', film)
|
print('['+str(i+1)+'/'+str(len(Linvalid))+']'+'invalid:', film)
|
||||||
|
@ -270,23 +274,123 @@ def handle_films(Lfilm_loc, Lfilm_api, api, rules, tok):
|
||||||
print('film '+film.title+' not posted')
|
print('film '+film.title+' not posted')
|
||||||
raise Exception('end')
|
raise Exception('end')
|
||||||
|
|
||||||
# TODO: traiter les films non postés
|
# TODO: traiter les films non postés (Lcannot_post)
|
||||||
|
|
||||||
def handle_episodes(Lepisode_loc, Lepisode_api, api, rules, tok):
|
def handle_episodes(Lepisode_loc, Lepisode_api, domain, api, rules, tok):
|
||||||
Lloc = Lepisode_loc
|
Lloc = Lepisode_loc
|
||||||
Lapi = Lepisode_api
|
Lapi = Lepisode_api
|
||||||
|
|
||||||
# supprime les fichiers invalides
|
# fichiers invalides
|
||||||
|
Linvalid = [f for f in Lapi if (not tok.conf.is_valid_file(f.name)) or not (filerule.match_rules(f.path+'/'+f.name, rules))]
|
||||||
|
Lapi = [f for f in Lapi if tok.conf.is_valid_file(f.name)]
|
||||||
|
|
||||||
|
# Compare avec la liste de l'api
|
||||||
|
Lmissing = [f for f in Lapi if f not in Lloc] # fichiers non présents localement
|
||||||
|
Lunref = [f for f in Lloc if f not in Lapi] # fichiers non référencés
|
||||||
|
|
||||||
|
# de même avec les noms de séries
|
||||||
|
Lseries_loc = list(set([f.info['SERIE'] for f in Lloc]))
|
||||||
|
Lseries_api = list(set([f.info['SERIE'] for f in Lapi]))
|
||||||
|
|
||||||
|
Lunref_serie = [s for s in Lseries_loc if s not in Lseries_api]
|
||||||
|
|
||||||
|
# récupère les séries, et les correspondances des noms locaux
|
||||||
|
APIseries = api.get_series(episodes=1)
|
||||||
|
APIepisodes = api.get_episodes(files=1)
|
||||||
|
APIepisodes_byid = {e['id']:e for e in APIepisodes}
|
||||||
|
APIfiles_byid = {f.api_id:f for f in Lapi}
|
||||||
|
series_id_bytitle = {}
|
||||||
|
series_id_bysimpletitle = {}
|
||||||
|
for s in APIseries:
|
||||||
|
series_id_bysimpletitle[s['title'].lower()] = s['id']
|
||||||
|
for e_id in [e['id'] for e in s['episodes']]:
|
||||||
|
e = APIepisodes_byid[e_id]
|
||||||
|
if 'files' in e:
|
||||||
|
for f in e['files']:
|
||||||
|
serie_title = APIfiles_byid[f['id']].info['SERIE']
|
||||||
|
series_id_bytitle[serie_title] = s['id']
|
||||||
|
|
||||||
|
# tente de lier les séries par nom simplifié
|
||||||
|
for s in Lseries_loc:
|
||||||
|
if s.lower() in series_id_bysimpletitle:
|
||||||
|
series_id_bytitle[s] = series_id_bysimpletitle[s.lower()]
|
||||||
|
if s in Lunref_serie:
|
||||||
|
Lunref_serie.remove(s)
|
||||||
|
|
||||||
|
# Supprime les fichiers invalides (dossiers/ ne répondent à aucune règle)
|
||||||
|
for i, episode in enumerate(Linvalid):
|
||||||
|
print('['+str(i+1)+'/'+str(len(Linvalid))+']'+'invalid:', episode)
|
||||||
|
try:
|
||||||
|
resp = api.delete_file(id=episode.api_fileid)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print('episode '+episode.title+' not deleted')
|
||||||
|
raise Exception('end')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Supprime les fichiers qui n'existent plus
|
||||||
|
for i, episode in enumerate(Lmissing):
|
||||||
|
print('['+str(i+1)+'/'+str(len(Lmissing))+']'+'missing:', episode)
|
||||||
|
try:
|
||||||
|
resp = api.delete_file(id=episode.api_fileid)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print('episode '+episode.title+' not deleted')
|
||||||
|
raise Exception('end')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Poste les séries non présentes, récupère les références correspondantes
|
||||||
|
series_not_found = []
|
||||||
|
for i, serie in enumerate(Lunref_serie):
|
||||||
|
print('['+str(i+1)+'/'+str(len(Lunref_serie))+']'+'unref_serie:', serie)
|
||||||
|
try:
|
||||||
|
resp = api.post_serie(title=serie)
|
||||||
|
if 'id' in resp:
|
||||||
|
series_id_bytitle[serie] = resp['id']
|
||||||
|
print('response: ', resp)
|
||||||
|
else:
|
||||||
|
series_not_found.append(serie)
|
||||||
|
print('not found: ', resp)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print('serie '+serie+' not posted')
|
||||||
|
raise Exception('end')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# filtre les épisodes, enlève les séries non référencées
|
||||||
|
Lunref = [f for f in Lunref if f.info['SERIE'] in series_id_bytitle]
|
||||||
|
|
||||||
|
# Poste les episodes locaux
|
||||||
|
for i, episode in enumerate(Lunref):
|
||||||
|
print('['+str(i+1)+'/'+str(len(Lunref))+']'+'post:', episode)
|
||||||
|
try:
|
||||||
|
serie_id = series_id_bytitle[episode.info['SERIE']]
|
||||||
|
episode_num = int(episode.info['EPISODE_NUM'])
|
||||||
|
season_num = int(episode.info['SEASON_NUM'])
|
||||||
|
resp = api.post_episode(serie_id=serie_id, episode=episode_num, season=season_num)
|
||||||
|
if 'id' in resp:
|
||||||
|
resp = api.post_file(path=domain['server']+episode.path, name=episode.name, type='episode', type_id=resp["id"])
|
||||||
|
print('response: ',resp)
|
||||||
|
else:
|
||||||
|
print('episode not posted:', resp)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print('episode '+episode.title+' not posted')
|
||||||
|
#raise Exception('end')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# TODO: traiter les séries non référencées (series_not_found)
|
||||||
|
|
||||||
|
|
||||||
def post_markers(api, file_, fileid):
|
def post_markers(api, file_, fileid):
|
||||||
for lang in file_.markers['lang']:
|
for lang in file_.markers['lang']:
|
||||||
api.add_language(fileid, lang)
|
api.post_file_language(fileid, lang)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
for qual in file_.markers['quality']:
|
for qual in file_.markers['quality']:
|
||||||
api.add_quality(fileid, qual)
|
api.post_file_qualities(fileid, qual)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
for sub in file_.markers['subtitle']:
|
for sub in file_.markers['subtitle']:
|
||||||
api.add_subtitle(fileid, sub)
|
api.post_file_subtitle(fileid, sub)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -296,7 +400,7 @@ def main():
|
||||||
folders = api.get_folders()
|
folders = api.get_folders()
|
||||||
rules = api.get_paths()
|
rules = api.get_paths()
|
||||||
|
|
||||||
for fold in folders:
|
for fold in folders[1:]:
|
||||||
applicable = [filerule.FileRule(re.escape(fold['path'])+'\\/'+r['regex'], conf) for r in rules if int(r['indexer_folder_id']) == fold['id']]
|
applicable = [filerule.FileRule(re.escape(fold['path'])+'\\/'+r['regex'], conf) for r in rules if int(r['indexer_folder_id']) == fold['id']]
|
||||||
visit_folder(fold, api, applicable, tokens)
|
visit_folder(fold, api, applicable, tokens)
|
||||||
|
|
||||||
|
|
22
piexel.py
22
piexel.py
|
@ -189,7 +189,7 @@ class Piexel:
|
||||||
:param params: paramètres à passer
|
:param params: paramètres à passer
|
||||||
"""
|
"""
|
||||||
fields = self._get_request(['title'], ['title'], **params)
|
fields = self._get_request(['title'], ['title'], **params)
|
||||||
return self._get_response('series', fields, 'post')
|
return self._get_response('serie', fields, 'post')
|
||||||
|
|
||||||
def post_episode(self, **params):
|
def post_episode(self, **params):
|
||||||
"""
|
"""
|
||||||
|
@ -197,7 +197,7 @@ class Piexel:
|
||||||
:param params: paramètres à passer
|
:param params: paramètres à passer
|
||||||
"""
|
"""
|
||||||
fields = self._get_request(['season', 'episode', 'serie_id'], ['season', 'episode', 'serie_id'], **params)
|
fields = self._get_request(['season', 'episode', 'serie_id'], ['season', 'episode', 'serie_id'], **params)
|
||||||
return self._get_response('episodes', fields, 'post')
|
return self._get_response('episode', fields, 'post')
|
||||||
|
|
||||||
def post_broken(self, **params):
|
def post_broken(self, **params):
|
||||||
"""
|
"""
|
||||||
|
@ -263,24 +263,6 @@ class Piexel:
|
||||||
fields = self._get_request([], [], **params)
|
fields = self._get_request([], [], **params)
|
||||||
return self._get_response('file/'+str(id), fields, 'delete')
|
return self._get_response('file/'+str(id), fields, 'delete')
|
||||||
|
|
||||||
def add_language(self, id, lang):
|
|
||||||
"""
|
|
||||||
Ajoute une langue à un fichier
|
|
||||||
"""
|
|
||||||
return self._get_response('languages/'+str(id)+'/attach', {'value':lang}, 'post')
|
|
||||||
|
|
||||||
def add_subtitle(self, id, subtitle):
|
|
||||||
"""
|
|
||||||
Ajoute un sous-titre à un fichier
|
|
||||||
"""
|
|
||||||
return self._get_response('subtitle-languages/'+str(id)+'/attach', {'value':subtitle}, 'post')
|
|
||||||
|
|
||||||
def add_quality(self, id, quality):
|
|
||||||
"""
|
|
||||||
Ajoute une langue à un fichier
|
|
||||||
"""
|
|
||||||
return self._get_response('qualities/'+str(id)+'/attach', {'value':quality}, 'post')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
piexel = Piexel('http://piexel.rez', 'app', 'token')
|
piexel = Piexel('http://piexel.rez', 'app', 'token')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue