Skip to content

Commit b55781c

Browse files
committed
separate tv submission types into individual classes
fixes #50
1 parent 18ba48a commit b55781c

4 files changed

Lines changed: 225 additions & 102 deletions

File tree

pythonbits/bb.py

Lines changed: 208 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -548,133 +548,244 @@ def _render_guess(self):
548548
def _render_search_title(self):
549549
return self['tv_specifier'].title
550550

551+
def subcategory(self):
552+
if type(self) == TvSubmission:
553+
if self['tv_specifier'].episode is None:
554+
return SeasonSubmission
555+
elif not isinstance(self['tv_specifier'].episode, abc.Sequence):
556+
return EpisodeSubmission
557+
else:
558+
return MultiEpisodeSubmission
559+
return type(self)
560+
561+
@staticmethod
562+
def tvdb_title_i18n(result):
563+
try:
564+
tvdb_sum = result.summary()
565+
imdb_id = tvdb_sum['show_imdb_id']
566+
i = imdb.IMDB()
567+
imdb_info = i.get_info(imdb_id)
568+
except Exception as e:
569+
log.error(e)
570+
return {'titles': {}}
571+
572+
imdb_sum = imdb_info.summary()
573+
tvdb_title = tvdb_sum['title']
574+
titles_d = {}
575+
# Original title
576+
titles_d['title'] = imdb_sum['title']
577+
# dict of international titles
578+
titles_d['titles'] = imdb_sum['titles']
579+
# "XWW" is IMDb's international title, but unlike TVDB, it doesn't
580+
# include the year if there are multiple shows with the same name.
581+
if 'XWW' in titles_d['titles']:
582+
titles_d['titles']['XWW'] = tvdb_title
583+
return titles_d
584+
585+
def _render_markers(self):
586+
return [self['source'], self['video_codec'],
587+
self['audio_codec'], self['container'],
588+
self['resolution']] + self['additional']
589+
590+
def _render_description(self):
591+
sections = [("Description", self['section_description']),
592+
("Information", self['section_information'])]
593+
594+
description = "\n".join(bb.section(*s) for s in sections)
595+
description += bb.release
596+
return description
597+
598+
@form_field('desc')
599+
def _render_form_description(self):
600+
ss = "".join(map(bb.img, self['screenshots']))
601+
return (self['description'] + "\n" +
602+
bb.section("Screenshots", bb.center(ss)) +
603+
bb.mi(self['mediainfo']))
604+
605+
606+
class EpisodeSubmission(TvSubmission):
551607
@form_field('title')
552608
def _render_form_title(self):
553-
markers_list = [self['source'], self['video_codec'],
554-
self['audio_codec'], self['container'],
555-
self['resolution']] + self['additional']
556-
markers = " / ".join(markers_list)
557-
558-
if self['tv_specifier'].episode is not None:
559-
return "{t} S{s:02d}E{e:02d} [{m}]".format(
560-
t=self['title'], s=self['tv_specifier'].season,
561-
e=self['tv_specifier'].episode,
562-
m=markers)
563-
else:
564-
return "{t} - Season {s} [{m}]".format(
565-
t=self['title'], s=self['tv_specifier'].season, m=markers)
609+
return "{t} S{s:02d}E{e:02d} [{m}]".format(
610+
t=self['title'], s=self['tv_specifier'].season,
611+
e=self['tv_specifier'].episode,
612+
m=" / ".join(self['markers']))
566613

567614
def _render_summary(self):
568615
t = tvdb.TVDB()
569616
result = t.search(self['tv_specifier'])
570617
summary = result.summary()
571-
572-
try:
573-
imdb_id = result.show['imdbId']
574-
i = imdb.IMDB()
575-
imdb_info = i.get_info(imdb_id)
576-
except Exception:
577-
summary['titles'] = {}
578-
else:
579-
imdb_sum = imdb_info.summary()
580-
tvdb_title = summary['title']
581-
# Original title
582-
summary['title'] = imdb_sum['title']
583-
# dict of international titles
584-
summary['titles'] = imdb_sum['titles']
585-
# "XWW" is IMDb's international title, but unlike TVDB, it doesn't
586-
# include the year if there are multiple shows with the same name.
587-
if 'XWW' in summary['titles']:
588-
summary['titles']['XWW'] = tvdb_title
618+
summary.update(self.tvdb_title_i18n(result))
589619
return summary
590620

591621
def _render_section_description(self):
592622
summary = self['summary']
593-
if 'episodesummary' in summary:
594-
return summary['seriessummary'] + bb.spoiler(
595-
summary['episodesummary'], "Episode description")
596-
else:
597-
return summary['seriessummary']
623+
return summary['seriessummary'] + bb.spoiler(
624+
summary['episodesummary'], "Episode description")
598625

599626
def _render_section_information(self):
600-
def imdb_link(r):
601-
return bb.link(r.name, "https://www.imdb.com"+r.id)
602-
603627
s = self['summary']
604628
links = [('TVDB', s['url'])]
605629

606630
if s['imdb_id']:
607631
links.append(('IMDb',
608632
"https://www.imdb.com/title/" + s['imdb_id']))
609-
# todo unify rating_bb and episode_fmt
610-
# get ratings from imdb
611-
i = imdb.IMDB()
612-
if self['tv_specifier'].episode is not None:
613-
if s['imdb_id']:
614-
rating, votes = i.get_rating(s['imdb_id'])
615633

616-
rating_bb = (bb.format_rating(rating[0], max=rating[1]) + " " +
617-
bb.s1("({votes} votes)".format(
618-
votes=votes)))
619-
else:
620-
rating_bb = ""
621-
622-
description = dedent("""\
623-
[b]Episode title[/b]: {title} ({links})
624-
[b]Aired[/b]: {air_date} on {network}
625-
[b]IMDb Rating[/b]: {rating}
626-
[b]Directors[/b]: {directors}
627-
[b]Writer(s)[/b]: {writers}
628-
[b]Content rating[/b]: {contentrating}""").format(
629-
title=s['episode_title'],
630-
links=", ".join(bb.link(*l) for l in links), # noqa: E741
631-
air_date=s['air_date'],
632-
network=s['network'],
633-
rating=rating_bb,
634-
directors=' | '.join(s['directors']),
635-
writers=' | '.join(s['writers']),
636-
contentrating=s['contentrating']
637-
)
634+
if s['imdb_id']:
635+
i = imdb.IMDB()
636+
rating, votes = i.get_rating(s['imdb_id'])
637+
638+
rating_bb = (bb.format_rating(rating[0], max=rating[1]) + " " +
639+
bb.s1("({votes} votes)".format(
640+
votes=votes)))
638641
else:
639-
description = dedent("""\
640-
[b]Network[/b]: {network}
641-
[b]Content rating[/b]: {contentrating}\n""").format(
642-
contentrating=s['contentrating'],
643-
network=s['network'],
642+
rating_bb = ""
643+
644+
description = dedent("""\
645+
[b]Episode title[/b]: {title} ({links})
646+
[b]Aired[/b]: {air_date} on {network}
647+
[b]IMDb Rating[/b]: {rating}
648+
[b]Directors[/b]: {directors}
649+
[b]Writer(s)[/b]: {writers}
650+
[b]Content rating[/b]: {contentrating}""").format(
651+
title=s['episode_title'],
652+
links=", ".join(bb.link(*l) for l in links), # noqa: E741
653+
air_date=s['air_date'],
654+
network=s['network'],
655+
rating=rating_bb,
656+
directors=' | '.join(s['directors']),
657+
writers=' | '.join(s['writers']),
658+
contentrating=s['contentrating']
644659
)
660+
return description
645661

646-
def episode_fmt(e):
647-
if not e['imdb_id']:
648-
return bb.link(e['title'], e['url']) + "\n"
649662

650-
try:
651-
rating, votes = i.get_rating(e['imdb_id'])
652-
except ValueError:
653-
return ''
654-
else:
655-
return (bb.link(e['title'], e['url']) + "\n" +
656-
bb.s1(bb.format_rating(*rating)))
663+
class MultiEpisodeSubmission(TvSubmission):
664+
@form_field('title')
665+
def _render_form_title(self):
666+
return "{t} S{s:02d}{es} [{m}]".format(
667+
t=self['title'], s=self['tv_specifier'].season,
668+
es="".join("E{:02d}".format(e)
669+
for e in self['tv_specifier'].episode),
670+
m=" / ".join(self['markers']))
671+
672+
def _render_summary(self):
673+
t = tvdb.TVDB()
674+
results = t.search(self['tv_specifier'])
675+
title_i18n = self.tvdb_title_i18n(results[0])
676+
summaries = []
677+
show_summary = results[0].show_summary()
678+
for result in results:
679+
summary = result.summary()
680+
summaries.append(summary)
681+
682+
ks = summaries[0].keys()
683+
assert all(s.keys() == ks for s in summaries)
684+
summary = {k: [s[k] for s in summaries] for k in ks}
685+
summary.update(**show_summary)
686+
summary.update(**title_i18n)
687+
return summary
657688

658-
with ThreadPoolExecutor() as executor:
659-
episodes = executor.map(episode_fmt, s['episodes'])
660-
description += "[b]Episodes[/b]:\n" + bb.list(episodes, style=1)
689+
def _render_section_description(self):
690+
summary = self['summary']
691+
return (summary['seriessummary'] +
692+
"".join(bb.spoiler(es, "Episode description")
693+
for es in summary['episodesummary']))
661694

662-
return description
695+
def _render_section_information(self):
696+
s = self['summary']
697+
links = [[('TVDB', u)] for u in s['url']]
698+
rating_bb = []
663699

664-
def _render_description(self):
665-
sections = [("Description", self['section_description']),
666-
("Information", self['section_information'])]
700+
for i, imdb_id in enumerate(s['imdb_id']):
701+
if imdb_id:
702+
links[i].append(
703+
('IMDb', "https://www.imdb.com/title/" + imdb_id))
667704

668-
description = "\n".join(bb.section(*s) for s in sections)
669-
description += bb.release
705+
i = imdb.IMDB()
706+
rating, votes = i.get_rating(imdb_id)
707+
708+
rating_bb.append(
709+
(bb.format_rating(rating[0], max=rating[1]) + " " +
710+
bb.s1("({votes} votes)".format(votes=votes))))
711+
else:
712+
rating_bb.append("")
713+
714+
description = dedent("""\
715+
[b]Episode titles[/b]: {title}
716+
[b]Aired[/b]: {air_date} on {network}
717+
[b]IMDb Rating[/b]: {rating}
718+
[b]Directors[/b]: {directors}
719+
[b]Writer(s)[/b]: {writers}
720+
[b]Content rating[/b]: {contentrating}""").format(
721+
title=' | '.join(
722+
"{} ({})".format(
723+
t, ", ".join(bb.link(*l) for l in ls)) # noqa: E741
724+
for t, ls in zip(s['episode_title'], links)),
725+
air_date=' | '.join(s['air_date']),
726+
network=s['network'],
727+
rating=' | '.join(rating_bb),
728+
directors=' | '.join(set(sum(s['directors'], []))),
729+
writers=' | '.join(set(sum(s['writers'], []))),
730+
contentrating=s['contentrating']
731+
)
670732
return description
671733

672-
@form_field('desc')
673-
def _render_form_description(self):
674-
ss = "".join(map(bb.img, self['screenshots']))
675-
return (self['description'] + "\n" +
676-
bb.section("Screenshots", bb.center(ss)) +
677-
bb.mi(self['mediainfo']))
734+
735+
class SeasonSubmission(TvSubmission):
736+
@form_field('title')
737+
def _render_form_title(self):
738+
return "{t} - Season {s} [{m}]".format(
739+
t=self['title'],
740+
s=self['tv_specifier'].season,
741+
m=" / ".join(self['markers']))
742+
743+
def _render_summary(self):
744+
t = tvdb.TVDB()
745+
result = t.search(self['tv_specifier'])
746+
summary = result.summary()
747+
summary.update(self.tvdb_title_i18n(result))
748+
return summary
749+
750+
def _render_section_description(self):
751+
summary = self['summary']
752+
return summary['seriessummary']
753+
754+
def _render_section_information(self):
755+
s = self['summary']
756+
links = [('TVDB', s['url'])]
757+
758+
imdb_id = s.get('show_imdb_id')
759+
if imdb_id:
760+
links.append(('IMDb',
761+
"https://www.imdb.com/title/" + imdb_id))
762+
763+
description = dedent("""\
764+
[b]Network[/b]: {network}
765+
[b]Content rating[/b]: {contentrating}\n""").format(
766+
contentrating=s['contentrating'],
767+
network=s['network'],
768+
)
769+
770+
i = imdb.IMDB()
771+
# todo unify rating_bb and episode_fmt
772+
773+
def episode_fmt(e):
774+
if not e['imdb_id']:
775+
return bb.link(e['title'], e['url']) + "\n"
776+
777+
try:
778+
rating, votes = i.get_rating(e['imdb_id'])
779+
except ValueError:
780+
return ''
781+
else:
782+
return (bb.link(e['title'], e['url']) + "\n" +
783+
bb.s1(bb.format_rating(*rating)))
784+
785+
with ThreadPoolExecutor() as executor:
786+
episodes = executor.map(episode_fmt, s['episodes'])
787+
description += "[b]Episodes[/b]:\n" + bb.list(episodes, style=1)
788+
return description
678789

679790

680791
class MovieSubmission(VideoSubmission):

pythonbits/imdb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def search(self, title):
114114
return self.get_info(result['imdb_id'])
115115

116116
def get_info(self, imdb_id):
117-
log.debug('getinfo')
117+
log.debug('imdb getinfo')
118118
with ThreadPoolExecutor() as executor:
119119
f_movie = executor.submit(self.imdb.get_title, imdb_id)
120120
f_credits = executor.submit(self.imdb.get_title_credits, imdb_id)

pythonbits/tvdb.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: utf-8 -*-
2+
from collections.abc import Sequence
23
import tvdb_api
34

45
from .api_utils import d
@@ -51,7 +52,7 @@ def summary(self):
5152
# 'seasons': len(self.show),
5253
# 'status': self.show['status'],
5354
'contentrating': self.show['rating'],
54-
'imdb_id': self.show['imdbId'],
55+
'show_imdb_id': self.show['imdbId'],
5556
}
5657

5758

@@ -80,8 +81,11 @@ def summary(self):
8081

8182

8283
class TvdbEpisode(TvdbResult):
84+
def show_summary(self):
85+
return super(TvdbEpisode, self).summary()
86+
8387
def summary(self):
84-
summary = super(TvdbEpisode, self).summary()
88+
summary = self.show_summary()
8589
summary.update(**{
8690
'season': self.episode['airedSeason'],
8791
'episode': self.episode['episodenumber'],
@@ -111,6 +115,12 @@ def search(self, tv_specifier):
111115
show = self.tvdb[tv_specifier.title]
112116
season = show[tv_specifier.season]
113117
if tv_specifier.episode is not None:
114-
episode = season[tv_specifier.episode]
115-
return TvdbEpisode(show, season, episode)
118+
if not isinstance(tv_specifier.episode, Sequence):
119+
episode = season[tv_specifier.episode]
120+
return TvdbEpisode(show, season, episode)
121+
122+
# multi-episode
123+
return [TvdbEpisode(show, season, season[e])
124+
for e in tv_specifier.episode]
125+
116126
return TvdbSeason(show, season)

0 commit comments

Comments
 (0)