Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Recommended shows version 2 #5782

Merged
merged 86 commits into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
06eb0fd
* Cache recommended shows in ShowUpdater
p0psicles Nov 10, 2018
4b42002
Added recommended shows to store.
p0psicles Nov 25, 2018
dfd5058
Added templates.
p0psicles Nov 25, 2018
488f80b
* Fixed getting recommended shows from Imdb
p0psicles Nov 26, 2018
a8b7aec
Removed debuggers.
p0psicles Nov 26, 2018
c5011d9
Implemented external id's for the recommended shows.
p0psicles Nov 26, 2018
7b06255
Changed recommended store.
p0psicles Dec 3, 2018
3c7545d
Created a generic update queue, as a thread that can be used
p0psicles Dec 8, 2018
1992f7d
Added basic functionality of adding a show, from recommended show.
p0psicles Dec 16, 2018
be2680d
Merge remote-tracking branch 'remotes/origin/develop' into feature/re…
p0psicles Dec 16, 2018
4781832
Fix set local vue variable selectedShowOptions from the add-show-opti…
p0psicles Dec 16, 2018
5410a87
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Dec 23, 2018
1152841
Fixed some post merge conflicts.
p0psicles Dec 23, 2018
d1088f4
Fixed some post merge conflicts.
p0psicles Dec 23, 2018
3e95527
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Jan 12, 2019
e5a2483
Implemented isotope sorting.
p0psicles Jan 13, 2019
b3a253f
Add the ability to add a recommended show by multiple indexers.
p0psicles Jan 13, 2019
f51b5ad
Added filter option.
p0psicles Jan 13, 2019
b6458dc
When adding shows, update the mapped_indexer and mapped_series_id in …
p0psicles Jan 13, 2019
9b070ee
Handle exceptions for when there is no connectivity.
p0psicles Jan 13, 2019
087e8ea
Merge remote-tracking branch 'remotes/origin/develop' into feature/re…
p0psicles Sep 25, 2019
9396434
Fixed rebase conflicts.
p0psicles Oct 4, 2019
df7240c
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Jul 9, 2021
b8da32a
Fix after merge conflicts
p0psicles Jul 9, 2021
7160d43
Add recommended.vue to index export
p0psicles Jul 9, 2021
b03e75a
Fix recommended.vue component
p0psicles Jul 10, 2021
a40aa62
Fix adding shows from recommended.vue
p0psicles Jul 10, 2021
b8c957b
mappedIndexer is not used.
p0psicles Jul 10, 2021
17cfb2c
runtime
p0psicles Jul 10, 2021
21bc723
Added field 'added' for adding a date.
p0psicles Jul 11, 2021
63e0c8c
Store recommended lists (subcats) in indexers/config.py
p0psicles Jul 11, 2021
ed8549d
Use indexers/config/indexers.js recommendedLists definition.
p0psicles Jul 11, 2021
64ffcb6
Use subcat, to specify the recommended list.
p0psicles Jul 11, 2021
83d6da3
Separated source and list. For ex. Source = trakt, List = popular.
p0psicles Jul 11, 2021
ccbabd1
Added trakt-authentication.vue component.
p0psicles Jul 13, 2021
f2a51b3
add feature: Route to add-new-show.vue
p0psicles Jul 13, 2021
6f7dd7d
Generate source->categories from recommeded table.
p0psicles Jul 13, 2021
34f6bc2
Added myAnimeList
p0psicles Jul 13, 2021
c2f41a4
Calculate three seasons for myanimelist (-3 months, now and + 3 months.
p0psicles Jul 16, 2021
376e739
Improved styling
p0psicles Jul 16, 2021
45551e3
Added button to start search for now shows, if list is empty.
p0psicles Jul 16, 2021
61a9d7f
Improved error handling / reporting
p0psicles Jul 17, 2021
00e6c18
Improved feedback
p0psicles Jul 17, 2021
1d0092e
Added config option for setting the recommended show update hour.
p0psicles Jul 17, 2021
356bcdd
Added feature to select individual trakt lists for caching.
p0psicles Jul 20, 2021
ad73335
Fix removed_from_medusa function.
p0psicles Jul 21, 2021
f48eaf6
Add the class "removed-from-medusa", but don't use it just yet.
p0psicles Jul 21, 2021
53fe37f
Pass force.
p0psicles Jul 23, 2021
2695972
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Jul 23, 2021
64f0059
imdb: use tmdb api to get tvdb and tmdb id's.
p0psicles Jul 23, 2021
0859b28
Catch connection error utorrent
p0psicles Jul 25, 2021
00b619c
fix linting
p0psicles Jul 25, 2021
e340497
fix lint-css
p0psicles Jul 25, 2021
b5534a9
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Jul 25, 2021
a120781
get genres when possible (not for anidb)
p0psicles Jul 25, 2021
c5e9c6a
Added support for Recommended list source anilist.co
p0psicles Jul 30, 2021
806a3ad
Disable selects until shows loaded.
p0psicles Jul 30, 2021
278bc0e
Adding loading notification
p0psicles Jul 30, 2021
e3493de
Add genres.
p0psicles Jul 30, 2021
c99edd4
also disable list select.
p0psicles Jul 30, 2021
cc5c173
restore check-overlay
p0psicles Jul 30, 2021
19c1d18
Clean up empty genres for anidb.
p0psicles Jul 30, 2021
665c620
Add save button, so you can enable trakt from the component.
p0psicles Aug 3, 2021
a3eeed6
Remove myanimelist references
p0psicles Aug 4, 2021
e1bf0ff
mvt adba
p0psicles Aug 4, 2021
261d70d
Added plot information to recommended shows.
p0psicles Aug 5, 2021
ff484d3
Moved recommended shows to dedicated database.
p0psicles Aug 5, 2021
9b18c3f
one to many underscore
p0psicles Aug 5, 2021
71993f7
fix lint
p0psicles Aug 6, 2021
f637e2c
fix pytest
p0psicles Aug 6, 2021
e514ab8
pylint
p0psicles Aug 6, 2021
fa53e86
Fix lint issue
p0psicles Aug 6, 2021
9708559
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Aug 6, 2021
f9f8f3d
Yarn dev
p0psicles Aug 6, 2021
2b3dd16
Remove unused mako.
p0psicles Aug 6, 2021
c65bdbd
Merge branch 'feature/rec-show-v2' of https://github.com/pymedusa/Med…
p0psicles Aug 6, 2021
b207ff3
Remove more unused mako.
p0psicles Aug 6, 2021
2e9421d
Merge remote-tracking branch 'origin/develop' into feature/rec-show-v2
p0psicles Aug 7, 2021
714c70b
Update changelog
p0psicles Aug 7, 2021
27a6220
update changelog
p0psicles Aug 7, 2021
9a19f1c
build runtime
p0psicles Aug 7, 2021
ce0759a
update changelog
p0psicles Aug 7, 2021
34bd96c
Fix jest tests (snapshots)
p0psicles Aug 7, 2021
6d04afc
Merge branch 'feature/rec-show-v2' of https://github.com/pymedusa/Med…
p0psicles Aug 7, 2021
5567c23
Don't comment, but xit test.
p0psicles Aug 7, 2021
306a5fd
use it.skip in stead
p0psicles Aug 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions medusa/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1172,9 +1172,9 @@ def initialize(self, console_logging=True):

app.show_update_scheduler = scheduler.Scheduler(show_updater.ShowUpdater(),
cycleTime=datetime.timedelta(hours=1),
threadName='SHOWUPDATER',
start_time=datetime.time(hour=app.SHOWUPDATE_HOUR,
minute=random.randint(0, 59)))
threadName='SHOWUPDATER')#,
# start_time=datetime.time(hour=app.SHOWUPDATE_HOUR,
# minute=random.randint(0, 59)))

# snatcher used for manual search, manual picked results
app.manual_snatch_scheduler = scheduler.Scheduler(SnatchQueue(),
Expand Down
6 changes: 6 additions & 0 deletions medusa/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,12 @@ def __init__(self):
self.FALLBACK_PLEX_API_URL = 'https://tvdb2.plex.tv'
self.TVDB_API_KEY = '0629B785CE550C8D'

# show updater recommeded show caching
self.CACHE_RECOMMENDED_SHOWS = True
self.CACHE_RECOMMENDED_TRAKT = True
self.CACHE_RECOMMENDED_IMDB = False
self.CACHE_RECOMMENDED_ANIDB = True


app = MedusaApp()
for app_key, app_value in app.__dict__.items():
Expand Down
26 changes: 25 additions & 1 deletion medusa/databases/cache_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,30 @@ def inc_major_version(self):
major_version, minor_version = self.connection.version
major_version += 1
self.connection.action('UPDATE db_version SET db_version = ?;', [major_version])
log.info('[CACHE-DB] Updated major version to: {}.{}', *self.connection.version)
return self.connection.version

return self.connection.version


class AddRecommendedTable(ClearProviderTables):
"""Add table to cache the recommended shows."""

def test(self):
return self.hasTable('recommended')

def execute(self):
self.connection.action(
"""CREATE TABLE "recommended" (
`recommended_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`source` INTEGER NOT NULL,
`series_id` INTEGER NOT NULL,
`mapped_indexer` INTEGER,
`mapped_series_id` INTEGER,
`title` TEXT NOT NULL,
`rating` NUMERIC,
`votes` INTEGER,
`is_anime` INTEGER DEFAULT 0,
`image_href` TEXT,
`image_src` TEXT
)"""
)
22 changes: 21 additions & 1 deletion medusa/helpers/externals.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from medusa.indexers.indexer_api import indexerApi
from medusa.indexers.indexer_config import indexerConfig
from medusa.indexers.indexer_exceptions import IndexerException, IndexerShowAlreadyInLibrary, IndexerUnavailable
from medusa.indexers.utils import mappings
from medusa.indexers.utils import mappings, reverse_mappings
from medusa.logger.adapters.style import BraceAdapter

from requests.exceptions import RequestException
Expand Down Expand Up @@ -174,6 +174,26 @@ def check_existing_shows(indexed_show, indexer):
indexerApi(indexer).name))


def save_externals_to_db(indexer, series_id, externals):
"""Save the indexers external id's to the db."""
sql_l = []

for external in externals:
if external in reverse_mappings and externals[external]:
sql_l.append(['INSERT OR IGNORE '
'INTO indexer_mapping (indexer_id, indexer, mindexer_id, mindexer) '
'VALUES (?,?,?,?)',
[series_id,
indexer,
externals[external],
int(reverse_mappings[external])
]])

if sql_l:
main_db_con = db.DBConnection()
main_db_con.mass_action(sql_l)


def load_externals_from_db(indexer=None, indexer_id=None):
"""Load and recreate the indexers external id's.

Expand Down
59 changes: 59 additions & 0 deletions medusa/server/api/v2/recommended.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# coding=utf-8
"""Request handler for series and episodes."""
from __future__ import unicode_literals

import logging


from medusa.indexers.indexer_config import EXTERNAL_IMDB, EXTERNAL_ANIDB, EXTERNAL_TRAKT
from medusa.logger.adapters.style import BraceAdapter
from medusa.server.api.v2.base import (
BaseRequestHandler,
BooleanField,
IntegerField,
ListField,
StringField,
iter_nested_items,
set_nested_value
)
from medusa.show.recommendations.recommended import get_recommended_shows
from medusa.show.recommendations.anidb import AnidbPopular
from medusa.show.recommendations.imdb import ImdbPopular
from medusa.show.recommendations.trakt import TraktPopular
from simpleanidb import REQUEST_HOT
from medusa.tv.series import Series, SeriesIdentifier

from six import itervalues, viewitems

from tornado.escape import json_decode

log = BraceAdapter(logging.getLogger(__name__))
log.logger.addHandler(logging.NullHandler())


class RecommendedHandler(BaseRequestHandler):
"""Series request handler."""

#: resource name
name = 'recommended'

identifier = ('identifier', r'\w+')
#: path param
path_param = ('path_param', r'\w+')
allowed_methods = ('GET',)

def http_get(self, identifier, path_param=None):
"""Query available recommended show lists."""

if identifier and identifier not in ('anidb', 'trakt', 'imdb'):
return self._bad_request("Invalid recommended list identifier '{0}'".format(identifier))

data = {}

recommended_mappings = {'imdb': EXTERNAL_IMDB, 'anidb': EXTERNAL_ANIDB, 'trakt': EXTERNAL_TRAKT}
shows = get_recommended_shows(source=recommended_mappings.get(identifier))

if shows:
data = [show.to_json() for show in shows]

return self._ok(data)
5 changes: 5 additions & 0 deletions medusa/server/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
from medusa.server.api.v2.episodes import EpisodeHandler
from medusa.server.api.v2.internal import InternalHandler
from medusa.server.api.v2.log import LogHandler
from medusa.server.api.v2.recommended import RecommendedHandler
from medusa.server.api.v2.series import SeriesHandler
from medusa.server.api.v2.series_asset import SeriesAssetHandler
from medusa.server.api.v2.series_legacy import SeriesLegacyHandler
from medusa.server.api.v2.series_operation import SeriesOperationHandler
from medusa.server.api.v2.stats import StatsHandler

from medusa.server.web import (
CalendarHandler,
KeyHandler,
Expand Down Expand Up @@ -109,6 +111,9 @@ def get_apiv2_handlers(base):
# /api/v2/authenticate
AuthHandler.create_app_handler(base),

# /api/v2/recommeded
RecommendedHandler.create_app_handler(base),

# Always keep this last!
NotFoundHandler.create_app_handler(base)
]
Expand Down
11 changes: 10 additions & 1 deletion medusa/server/web/home/add_shows.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def popularAnime(self, list_type=REQUEST_HOT):
"""
Fetches list recommeded shows from anidb.info.
"""
t = PageTemplate(rh=self, filename='addShows_recommended.mako')
t = PageTemplate(rh=self, filename='addShows_recommended_vue.mako')
e = None

try:
Expand All @@ -226,6 +226,15 @@ def popularAnime(self, list_type=REQUEST_HOT):
enable_anime_options=True, blacklist=[], whitelist=[],
controller='addShows', action='recommendedShows', realpage='popularAnime')

def recommended(self):
"""
Serve Vue page addShows_recommeded_vue.mako
"""
t = PageTemplate(rh=self, filename='addShows_recommended_vue.mako')

return t.render(title='Recommended shows', header='Recommended shows',
controller='addShows', action='recommendedShows', realpage='recommended')

def addShowToBlacklist(self, seriesid):
# URL parameters
data = {'shows': [{'ids': {'tvdb': seriesid}}]}
Expand Down
37 changes: 21 additions & 16 deletions medusa/show/recommendations/anidb.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

from medusa import app
from medusa.cache import recommended_series_cache
from medusa.indexers.indexer_config import INDEXER_TVDBV2
from medusa.indexers.indexer_config import INDEXER_TVDBV2, EXTERNAL_ANIDB
from medusa.logger.adapters.style import BraceAdapter
from medusa.session.core import MedusaSession
from medusa.show.recommendations.recommended import (
MissingTvdbMapping, RecommendedShow, cached_aid_to_tvdb, create_key_from_series,
BasePopular, MissingTvdbMapping, RecommendedShow, cached_aid_to_tvdb, create_key_from_series,
update_recommended_series_cache_index
)

Expand All @@ -27,17 +27,22 @@
log.logger.addHandler(logging.NullHandler())


class AnidbPopular(object): # pylint: disable=too-few-public-methods
class AnidbPopular(BasePopular): # pylint: disable=too-few-public-methods

BASE_URL = 'https://anidb.net/perl-bin/animedb.pl?show=anime&aid={aid}'
TITLE = 'Anidb Popular'
CACHE_SUBFOLDER = __name__.split('.')[-1] if '.' in __name__ else __name__

def __init__(self):
"""Class retrieves a specified recommended show list from Trakt.

List of returned shows is mapped to a RecommendedShow object
"""
self.cache_subfolder = __name__.split('.')[-1] if '.' in __name__ else __name__
self.session = MedusaSession()
self.recommender = 'Anidb Popular'
self.base_url = 'https://anidb.net/perl-bin/animedb.pl?show=anime&aid={aid}'
self.default_img_src = 'poster.png'
super(AnidbPopular, self).__init__()
self.cache_subfolder = AnidbPopular.CACHE_SUBFOLDER
self.recommender = AnidbPopular.TITLE
self.source = EXTERNAL_ANIDB
self.base_url = AnidbPopular.BASE_URL

@recommended_series_cache.cache_on_arguments(namespace='anidb', function_key_generator=create_key_from_series)
def _create_recommended_show(self, series, storage_key=None):
Expand All @@ -55,25 +60,24 @@ def _create_recommended_show(self, series, storage_key=None):
rec_show = RecommendedShow(
self,
series.aid,
series.title,
unicode(series.title),
INDEXER_TVDBV2,
tvdb_id,
**{'rating': series.rating_permanent,
'votes': series.count_permanent,
'image_href': self.base_url.format(aid=series.aid),
'ids': {'tvdb': tvdb_id,
'aid': series.aid
}
}
'ids': {
'tvdb_id': tvdb_id,
'anidb_id': series.aid
},
'is_anime': True
}
)

# Check cache or get and save image
use_default = self.default_img_src if not series.picture.url else None
rec_show.cache_image(series.picture.url, default=use_default)

# By default pre-configure the show option anime = True
rec_show.is_anime = True

return rec_show

def fetch_popular_shows(self, list_type=REQUEST_HOT):
Expand All @@ -90,6 +94,7 @@ def fetch_popular_shows(self, list_type=REQUEST_HOT):
try:
recommended_show = self._create_recommended_show(show, storage_key='anidb_{0}'.format(show.aid))
if recommended_show:
recommended_show.save_to_db()
result.append(recommended_show)
except MissingTvdbMapping:
log.info('Could not parse AniDB show {0}, missing tvdb mapping', show.title)
Expand Down
Loading