-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
3,744 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
*~ | ||
*.pyc | ||
*.swo | ||
*.swp | ||
.settings/ | ||
.project | ||
.pydevproject | ||
/.Python | ||
*.egg-info/ | ||
bin/ | ||
Scripts/ | ||
include/ | ||
lib/ | ||
local | ||
.idea/ | ||
*.iml | ||
dist/ | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
FlexGet extras | ||
============== | ||
|
||
This contains collection of plugins that are not considered widely used enough to be included in standard | ||
distribution package or are not actively maintained and supported by `FlexGet`_ development team. | ||
|
||
This repository also serves example how to do separate distribution package for plugins. | ||
|
||
You will need to have `FlexGet`_ virtualenv active when executing any of these commands or directly use it's | ||
`bin/` or `scripts`. Using `virtualenvwrapper`_ recommended. | ||
|
||
Install | ||
------- | ||
|
||
TBD, this may work | ||
|
||
pip install http://github.com/Flexget/extra/archive/master.zip | ||
|
||
|
||
Development | ||
----------- | ||
|
||
Clone and at the checkout directory run:: | ||
|
||
python setup.py develop | ||
|
||
Tests | ||
----- | ||
|
||
In the checkout directory run:: | ||
|
||
py.test | ||
|
||
|
||
.. _FlexGet: http://flexget.com | ||
.. _virtualenvwrapper: https://virtualenvwrapper.readthedocs.io/en/latest/install.html |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
from __future__ import unicode_literals, division, absolute_import | ||
from builtins import * # pylint: disable=unused-import, redefined-builtin | ||
|
||
import os | ||
|
||
from flexget import plugin | ||
from flexget.entry import Entry | ||
from flexget.event import event | ||
from flexget.utils import json | ||
|
||
try: | ||
from flexget.plugins.api_tvdb import lookup_series | ||
except ImportError: | ||
raise plugin.DependencyError(issued_by='uoccin', missing='api_tvdb', | ||
message='uoccin requires the `api_tvdb` plugin') | ||
|
||
|
||
def load_uoccin_data(path): | ||
udata = {} | ||
ufile = os.path.join(path, 'uoccin.json') | ||
if os.path.exists(ufile): | ||
try: | ||
with open(ufile, 'r') as f: | ||
udata = json.load(f) | ||
except Exception as err: | ||
raise plugin.PluginError('error reading %s: %s' % (ufile, err)) | ||
udata.setdefault('movies', {}) | ||
udata.setdefault('series', {}) | ||
return udata | ||
|
||
|
||
class FromUoccin(object): | ||
schema = { | ||
'type': 'object', | ||
'properties': { | ||
'path': {'type': 'string', 'format': 'path'}, | ||
'type': {'type': 'string', 'enum': ['movies', 'series', 'episodes']}, | ||
'tags': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}, | ||
'check_tags': {'type': 'string', 'enum': ['any', 'all', 'none'], 'default': 'any'}, | ||
'ep_flags': {'type': 'string', 'enum': ['watched', 'collected'], 'default': 'watched'}, | ||
}, | ||
'required': ['path', 'type'], | ||
'additionalProperties': False | ||
} | ||
|
||
def on_task_input(self, task, config): | ||
"""Creates an entry for each item in your uoccin watchlist. | ||
Example:: | ||
from_uoccin: | ||
path: /path/to/gdrive/uoccin | ||
type: series | ||
tags: [ 'favorite', 'hires' ] | ||
check_tags: all | ||
Options path and type are required while the others are for filtering: | ||
- 'any' will include all the items marked with one or more tags in the list | ||
- 'all' will only include the items marked with all the listed tags | ||
- 'none' will only include the items not marked with any of the listed tags. | ||
The entries created will have a valid imdb/tvdb url and id. | ||
""" | ||
imdb_lookup = plugin.get_plugin_by_name('imdb_lookup').instance | ||
udata = load_uoccin_data(config['path']) | ||
section = udata['movies'] if config['type'] == 'movies' else udata['series'] | ||
entries = [] | ||
for eid, itm in list(section.items()): | ||
if not itm['watchlist']: | ||
continue | ||
if 'tags' in config: | ||
n = len(set(config['tags']) & set(itm.get('tags', []))) | ||
if config['check_tags'] == 'any' and n <= 0: | ||
continue | ||
if config['check_tags'] == 'all' and n != len(config['tags']): | ||
continue | ||
if config['check_tags'] == 'none' and n > 0: | ||
continue | ||
if config['type'] == 'movies': | ||
entry = Entry() | ||
entry['url'] = 'http://www.imdb.com/title/' + eid | ||
entry['imdb_id'] = eid | ||
if itm['name'] != 'N/A': | ||
entry['title'] = itm['name'] | ||
else: | ||
try: | ||
imdb_lookup.lookup(entry) | ||
except plugin.PluginError as e: | ||
self.log.trace('entry %s imdb failed (%s)' % (entry['imdb_id'], e.value)) | ||
continue | ||
entry['title'] = entry.get('imdb_name') | ||
if 'tags' in itm: | ||
entry['uoccin_tags'] = itm['tags'] | ||
if entry.isvalid(): | ||
entries.append(entry) | ||
else: | ||
self.log.debug('Invalid entry created? %s' % entry) | ||
else: | ||
sname = itm['name'] | ||
try: | ||
sname = lookup_series(tvdb_id=eid).seriesname | ||
except LookupError: | ||
self.log.warning('Unable to lookup series %s from tvdb, using raw name.' % eid) | ||
surl = 'http://thetvdb.com/?tab=series&id=' + eid | ||
if config['type'] == 'series': | ||
entry = Entry() | ||
entry['url'] = surl | ||
entry['title'] = sname | ||
entry['tvdb_id'] = eid | ||
if 'tags' in itm: | ||
entry['uoccin_tags'] = itm['tags'] | ||
if entry.isvalid(): | ||
entries.append(entry) | ||
else: | ||
self.log.debug('Invalid entry created? %s' % entry) | ||
elif config['ep_flags'] == 'collected': | ||
slist = itm.get('collected', {}) | ||
for sno in list(slist.keys()): | ||
for eno in slist[sno]: | ||
entry = Entry() | ||
entry['url'] = surl | ||
entry['title'] = '%s S%02dE%02d' % (sname, int(sno), int(eno)) | ||
entry['tvdb_id'] = eid | ||
if entry.isvalid(): | ||
entries.append(entry) | ||
else: | ||
self.log.debug('Invalid entry created? %s' % entry) | ||
else: | ||
slist = itm.get('watched', {}) | ||
for sno in list(slist.keys()): | ||
for eno in slist[sno]: | ||
entry = Entry() | ||
entry['url'] = surl | ||
entry['title'] = '%s S%02dE%02d' % (sname, int(sno), eno) | ||
entry['tvdb_id'] = eid | ||
if entry.isvalid(): | ||
entries.append(entry) | ||
else: | ||
self.log.debug('Invalid entry created? %s' % entry) | ||
entries.sort(key=lambda x: x['title']) | ||
return entries | ||
|
||
|
||
@event('plugin.register') | ||
def register_plugin(): | ||
plugin.register(FromUoccin, 'from_uoccin', api_ver=2) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from __future__ import unicode_literals, division, absolute_import | ||
from builtins import * # pylint: disable=unused-import, redefined-builtin | ||
|
||
import os | ||
|
||
from flexget import plugin | ||
from flexget.event import event | ||
from flexget.utils import json | ||
|
||
|
||
def load_uoccin_data(path): | ||
udata = {} | ||
ufile = os.path.join(path, 'uoccin.json') | ||
if os.path.exists(ufile): | ||
try: | ||
with open(ufile, 'r') as f: | ||
udata = json.load(f) | ||
except Exception as err: | ||
raise plugin.PluginError('error reading %s: %s' % (ufile, err)) | ||
udata.setdefault('movies', {}) | ||
udata.setdefault('series', {}) | ||
return udata | ||
|
||
|
||
class UoccinLookup(object): | ||
schema = {'type': 'string', 'format': 'path'} | ||
|
||
# Run after metainfo_series / thetvdb_lookup / imdb_lookup | ||
@plugin.priority(100) | ||
def on_task_metainfo(self, task, config): | ||
"""Retrieves all the information found in the uoccin.json file for the entries. | ||
Example:: | ||
uoccin_lookup: /path/to/gdrive/uoccin | ||
Resulting fields on entries: | ||
on series (requires tvdb_id): | ||
- uoccin_watchlist (true|false) | ||
- uoccin_rating (integer) | ||
- uoccin_tags (list) | ||
on episodes (requires tvdb_id, series_season and series_episode): | ||
- uoccin_collected (true|false) | ||
- uoccin_watched (true|false) | ||
- uoccin_subtitles (list of language codes) | ||
(plus the 3 series specific fields) | ||
on movies (requires imdb_id): | ||
- uoccin_watchlist (true|false) | ||
- uoccin_collected (true|false) | ||
- uoccin_watched (true|false) | ||
- uoccin_rating (integer) | ||
- uoccin_tags (list) | ||
- uoccin_subtitles (list of language codes) | ||
""" | ||
if not task.entries: | ||
return | ||
udata = load_uoccin_data(config) | ||
movies = udata['movies'] | ||
series = udata['series'] | ||
for entry in task.entries: | ||
entry['uoccin_watchlist'] = False | ||
entry['uoccin_collected'] = False | ||
entry['uoccin_watched'] = False | ||
entry['uoccin_rating'] = None | ||
entry['uoccin_tags'] = [] | ||
entry['uoccin_subtitles'] = [] | ||
if 'tvdb_id' in entry: | ||
ser = series.get(str(entry['tvdb_id'])) | ||
if ser is None: | ||
continue | ||
entry['uoccin_watchlist'] = ser.get('watchlist', False) | ||
entry['uoccin_rating'] = ser.get('rating') | ||
entry['uoccin_tags'] = ser.get('tags', []) | ||
if all(field in entry for field in ['series_season', 'series_episode']): | ||
season = str(entry['series_season']) | ||
episode = entry['series_episode'] | ||
edata = ser.get('collected', {}).get(season, {}).get(str(episode)) | ||
entry['uoccin_collected'] = isinstance(edata, list) | ||
entry['uoccin_subtitles'] = edata if entry['uoccin_collected'] else [] | ||
entry['uoccin_watched'] = episode in ser.get('watched', {}).get(season, []) | ||
elif 'imdb_id' in entry: | ||
try: | ||
mov = movies.get(entry['imdb_id']) | ||
except plugin.PluginError as e: | ||
self.log.trace('entry %s imdb failed (%s)' % (entry['imdb_id'], e.value)) | ||
continue | ||
if mov is None: | ||
continue | ||
entry['uoccin_watchlist'] = mov.get('watchlist', False) | ||
entry['uoccin_collected'] = mov.get('collected', False) | ||
entry['uoccin_watched'] = mov.get('watched', False) | ||
entry['uoccin_rating'] = mov.get('rating') | ||
entry['uoccin_tags'] = mov.get('tags', []) | ||
entry['uoccin_subtitles'] = mov.get('subtitles', []) | ||
|
||
|
||
@event('plugin.register') | ||
def register_plugin(): | ||
plugin.register(UoccinLookup, 'uoccin_lookup', api_ver=2) |
Empty file.
Oops, something went wrong.