Skip to content

Commit

Permalink
Added uoccin to extras
Browse files Browse the repository at this point in the history
  • Loading branch information
paranoidi committed Jul 26, 2016
1 parent c5606de commit 465a009
Show file tree
Hide file tree
Showing 21 changed files with 3,744 additions and 6 deletions.
18 changes: 18 additions & 0 deletions .gitignore
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/
14 changes: 8 additions & 6 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
The MIT License (MIT)

Copyright (c) 2016 FlexGet
The MIT License

Copyright (C) 2006, Riku 'Shrike' Lindblad
Copyright (C) 2007, Marko Koivusalo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -9,13 +11,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
36 changes: 36 additions & 0 deletions README.rst
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 added extras/__init__.py
Empty file.
Empty file added extras/input/__init__.py
Empty file.
146 changes: 146 additions & 0 deletions extras/input/from_uoccin.py
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 added extras/metainfo/__init__.py
Empty file.
103 changes: 103 additions & 0 deletions extras/metainfo/uoccin_lookup.py
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 added extras/output/__init__.py
Empty file.
Loading

0 comments on commit 465a009

Please sign in to comment.