From 45f97936f0c65902ca1e91f38bc4274aa328d05c Mon Sep 17 00:00:00 2001 From: redstorm45 Date: Sun, 10 Dec 2017 13:54:53 +0100 Subject: [PATCH] =?UTF-8?q?Gesion=20des=20s=C3=A9ries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- file.py | 6 +-- main.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++------- piexel.py | 22 +-------- 3 files changed, 126 insertions(+), 40 deletions(-) diff --git a/file.py b/file.py index bf252fb..43ff7b4 100644 --- a/file.py +++ b/file.py @@ -13,7 +13,7 @@ class File: self.markers = {} self.api_id = api_id 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): _, ext = posixpath.splitext(self.name) @@ -64,9 +64,9 @@ class File: # 7) type: épisode / film if not self.fileable_type: for m in ['SERIE', 'EPISODE_NUM', 'SEASON_NUM']: - if m in self.markers: + if m in self.info: 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' def filename_same(self, other): diff --git a/main.py b/main.py index bde9540..17ac8dc 100644 --- a/main.py +++ b/main.py @@ -73,29 +73,33 @@ def visit_folder(domain, api, rules, tok): Lapi = [] for info in api.get_files(path=domain['server']+domain['path'], like=1, filable=1): 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é else: year = int(info['filable']['release_date'][:4]) 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) + 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) print('total api for ',domain['server']+domain['path'],':', len(Lapi)) # traite les films Lfilm_loc = [f for f in Lloc 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 Lepisode_loc = [f for f in Lloc 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']) -def handle_films(Lfilm_loc, Lfilm_api, api, rules, tok): +def handle_films(Lfilm_loc, Lfilm_api, domain, api, rules, tok): Lloc = Lfilm_loc Lapi = Lfilm_api @@ -165,13 +169,13 @@ def handle_films(Lfilm_loc, Lfilm_api, api, rules, tok): for f, _ in Llink2: Lunref.remove(f) - print('invalid:\n'+'\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('\n'*3) - print('unreferenced:\n'+'\n'.join(str(f) for f in sorted(Lunref, key=lambda e:e.title))) - print('\n'*3) + print('invalid:'+'\n'.join(str(f.api_fileid)+' '+str(f) for f in Linvalid)) + 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('unreferenced:'+'\n'.join(str(f) for f in sorted(Lunref, key=lambda e:e.title))) #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) for i, film in enumerate(Linvalid): 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') 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 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): for lang in file_.markers['lang']: - api.add_language(fileid, lang) + api.post_file_language(fileid, lang) time.sleep(0.5) for qual in file_.markers['quality']: - api.add_quality(fileid, qual) + api.post_file_qualities(fileid, qual) time.sleep(0.5) for sub in file_.markers['subtitle']: - api.add_subtitle(fileid, sub) + api.post_file_subtitle(fileid, sub) time.sleep(0.5) def main(): @@ -296,7 +400,7 @@ def main(): folders = api.get_folders() 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']] visit_folder(fold, api, applicable, tokens) diff --git a/piexel.py b/piexel.py index 77751c5..416c415 100644 --- a/piexel.py +++ b/piexel.py @@ -189,7 +189,7 @@ class Piexel: :param params: paramètres à passer """ 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): """ @@ -197,7 +197,7 @@ class Piexel: :param params: paramètres à passer """ 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): """ @@ -263,24 +263,6 @@ class Piexel: fields = self._get_request([], [], **params) 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__': piexel = Piexel('http://piexel.rez', 'app', 'token')