Last active
February 18, 2021 18:36
-
-
Save danilvalov/720966d26e99f06aed41 to your computer and use it in GitHub Desktop.
FlexGet Kinopoisk plugin
This file contains hidden or 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
templates: | |
movies: | |
set: | |
path: /tmp/mnt/94E8B2B1E8B290CA/Torrents/download/DLNA/Movies | |
transmission: | |
host: ************ | |
port: **** | |
username: ************* | |
password: ************* | |
email: | |
from: **********@**********.ru | |
to: **********@**********.ru | |
title: FlexGet Notification | |
smtp_host: ************* | |
smtp_port: 25 | |
smtp_username: ************* | |
smtp_password: '*************' | |
tasks: | |
nnm-club: | |
rss: | |
url: http://nnm-club.me/forum/rss2.php?f=218&t=1&uk=************* | |
other_fields: [description] | |
ascii: yes | |
accept_all: yes | |
manipulate: | |
- title: | |
replace: | |
regexp: '[^\x00-\x80]+' | |
format: '' | |
- kinopoisk_id: | |
from: description | |
replace: | |
regexp: '(.|\n)*kinopoisk.ru/rating/([0-9]+)(.|\n)*' | |
format: '\2' | |
kinopoisk: | |
min_score: 7.0 | |
min_votes: 1000 | |
template: | |
- movies |
This file contains hidden or 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
from __future__ import unicode_literals, division, absolute_import | |
import urllib2, xmltodict | |
import logging | |
from flexget import plugin | |
from flexget.event import event | |
from flexget.plugins.filter.seen import FilterSeen | |
log = logging.getLogger('kinopoisk') | |
class FilterKinopoisk(FilterSeen): | |
""" | |
Kinopoisk filter | |
Using: | |
Add option to config.yml: | |
kinopoisk: | |
min_score: 7.0 # ignore movies with score below 7.0, default: 0 | |
min_votes: 1000 # ignore movies with votes below 1000, default: 0 | |
matching: 'strict' # ignore entries without kinopoisk_id, values: 'strict' or 'loose', default: 'strict' | |
scope: 'local' # use global or local storage, values: 'global' or 'local', default: 'global' | |
Please, replace values of '7.0' and '1000' to your | |
""" | |
schema = { | |
'oneOf': [ | |
{ | |
'type': 'object', | |
'properties': { | |
'min_score': {'type': 'number'}, | |
'min_votes': {'type': 'integer'}, | |
'matching': {'type': 'string', 'enum': ['strict', 'loose']}, | |
'scope': {'type': 'string', 'enum': ['global', 'local']} | |
} | |
} | |
] | |
} | |
def __init__(self): | |
# remember and filter by these fields | |
self.fields = ['kinopoisk_id'] | |
self.keyword = 'kinopoisk' | |
def is_number(self, s): | |
try: | |
float(s) | |
return True | |
except ValueError: | |
return False | |
@plugin.priority(0) # Make filter run after other filters, but before exists_movies | |
def on_task_filter(self, task, config): | |
if config is False: | |
return | |
# Reject all entries without kinopoisk id | |
if config.get('matching') != 'loose': | |
for entry in task.entries: | |
if 'kinopoisk_id' not in entry or not self.is_number(entry['kinopoisk_id']): | |
log.info('Rejecting %s because of missing movie kinopoisk id' % entry['title']) | |
entry.reject('Missing movie kinopoisk id') | |
# call super | |
super(FilterKinopoisk, self).on_task_filter(task, config.get('scope', True)) | |
# check that two copies of a movie have not been accepted this run | |
kinopoisk_ids = set() | |
for entry in task.accepted: | |
if not self.is_number(entry['kinopoisk_id']): | |
entry.reject('Kinopoisk ID not found') | |
continue | |
if entry['kinopoisk_id'] in kinopoisk_ids and self.is_number(entry['kinopoisk_id']): | |
entry.reject('Already accepted once in task') | |
continue | |
else: | |
kinopoisk_ids.add(entry['kinopoisk_id']) | |
try: | |
page = urllib2.urlopen('http://rating.kinopoisk.ru/' + entry['kinopoisk_id'] + '.xml') | |
except urllib2.HTTPError: | |
entry.reject('Rating is not found') | |
continue | |
doc = page.read() | |
page.close() | |
data = xmltodict.parse(doc) | |
score = float(data['rating']['kp_rating']['#text']) | |
votes = float(data['rating']['kp_rating']['@num_vote']) | |
if 'min_score' in config: | |
if score <= 0: | |
entry.reject('Score is zero') | |
continue | |
if score < config['min_score']: | |
entry.reject('Score (%s) below minimum (%s)' % (score, config['min_score'])) | |
continue | |
if 'min_votes' in config: | |
if votes < config['min_votes']: | |
entry.reject('Votes (%s) below minimum (%s)' % (votes, config['min_votes'])) | |
continue | |
log.debug('Accepting %s' % (entry['title'])) | |
@event('plugin.register') | |
def register_plugin(): | |
plugin.register(FilterKinopoisk, 'kinopoisk', api_ver=2) |
2018-04-22 21:21 CRITICAL task nnm-club BUG: Unhandled error in plugin kinopoisk: not well-formed (invalid token): line 1, column 0 Traceback (most recent call last): File "d:\program\python\python27\lib\site-packages\flexget\task.py", line 486, in __run_plugin return method(*args, **kwargs) File "d:\program\python\python27\lib\site-packages\flexget\event.py", line 23, in __call__ return self.func(*args, **kwargs) File "C:\Users\222\flexget\plugins\kinopoisk.py", line 90, in on_task_filter data = xmltodict.parse(doc) File "d:\program\python\python27\lib\site-packages\xmltodict.py", line 330, in parse parser.Parse(xml_input, True) ExpatError: not well-formed (invalid token): line 1, column 0
Как пофиксить? Спасибо.
Looks like sometimes it gives reponse in gzip format. It can be fixed like that:
doc = page.read()
page.close()
try:
data = xmltodict.parse(doc)
except ExpatError:
compressed_data = io.BytesIO(doc)
for compressed_data_item in gzip.GzipFile(fileobj=compressed_data):
data = xmltodict.parse(compressed_data_item)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Как пофиксить? Спасибо.