-
-
Save danilvalov/720966d26e99f06aed41 to your computer and use it in GitHub Desktop.
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 |
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) |
My flexget paths:
~/.flexget/config.yml
~/.flexget/plugins/kinopoisk.py
~/.flexget/templates/movies.template
You can delete this lines:
template:
- movies
and use default template.
Added handler for incorrect kinopoisk response.
@danilvalov how we login to nnmclub? where to set cookies or what's uk
?
@danilvalov it seems kinopoisk rating algorithm (parser) doesn't work anymore.
@danilvalov how to find kinopoisk id from the page of torrent website, not from field of rss feed (where link in the field).
@XBeg9
It works for me:
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ Morgan (2016) BDRip [H.264/720p-LQ] [2.13GB]` by kinopoisk plugin because score (5.71) below minimum (7.0)
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ The Shallows (2016) BDRip [1.46GB]` by kinopoisk plugin because score (6.272) below minimum (7.0)
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ The BFG (2016) BDRip [2.19GB]` by kinopoisk plugin because score (6.129) below minimum (7.0)
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ Run the Tide (2016) WEB-DL [H.264/720p-LQ] [3.12GB]` by kinopoisk plugin because score is zero
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ Run the Tide (2016) WEB-DL [H.264/1080p-LQ] [3.43GB]` by kinopoisk plugin because already accepted once in task
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ End of a Gun (2016) HDRip [1.36GB]` by kinopoisk plugin because score is zero
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `/ Morgan (2016) BDRip [1.42GB]` by kinopoisk plugin because already accepted once in task
2016-12-07 19:11 VERBOSE task nnm-club REJECTED: `- / Ben-Hur (2016) HDRip [Line] [2.05GB]` by kinopoisk plugin because score (5.892) below minimum (7.0)
@githubroman
The following regexp finds kinopoisk ids in kinopoisk urls on any page:
https://gist.github.com/danilvalov/720966d26e99f06aed41#file-config-yml-L34
For example:
you have the following description:
<description><a href="https://nnmclub.to/forum/viewtopic.php?t=1080824">тема на форуме</a><br><span style="text-align: center; display: block;"><span style="color: Indigo"><span style="font-size: 20px; line-height: normal"><span style="font-weight: bold"> Морган / Morgan (2016) BDRip [H.264/720p-LQ]</span></span></span></span><span style="text-align: center; display: block;"><span style="color: gray"><span style="font-weight: bold">«Don't let it out»</span></span></span> <hr /><img src="{ASSETS}/forum/image.php?link=http://s020.radikal.ru/i713/1612/4b/0b3129627bb5.jpg"><span style="font-weight: bold">Производство:</span> США / Scott Free Productions<br /><span style="font-weight: bold">Жанр:</span> Ужасы, Фантастика, Триллер, Детектив<br /><br /><span style="font-weight: bold">Режиссер:</span> Люк Скотт<br /><span style="font-weight: bold">Актеры:</span> Кейт Мара, Аня Тейлор-Джой, Роуз Лесли, Майкл Йар, Тоби Джонс, Крис Салливан, Бойд Холбрук, Винетт Робинсон, Мишель Йео, Брайан Кокс<br /><br /><span style="font-weight: bold">Описание:</span><br />Сотрудница по устранению аварий отправляется в отдаленный секретный филиал, где должна расследовать и оценить потери от ужасной катастрофы. На месте она узнает, что случившееся было вызвано, казалось бы, невинным «человеком», чье существование само по себе является опасной тайной.<br /><br /><span id="kpjsrch"></span> <a id="kp_id" href="http://www.kinopoisk.ru/film/906340/" target="_blank" rel="nofollow"><img src="https://www.kinopoisk.ru/rating/906340.gif"></a> <a id="imdb_id" href="http://www.imdb.com/title/tt4520364/" target="_blank" rel="nofollow"><img src="http://imdb.snick.ru/ratefor/02/tt4520364.png"></a><br /><span style="font-size: 11px; line-height: normal"><span style="font-weight: bold">Возраст:</span> <span style="color: #FF0000"><span style="font-weight: bold">18+</span></span> <span style="color: #CC0000">(зрителям, достигшим 18 лет. запрещено для детей)</span></span><br /><span style="font-size: 11px; line-height: normal"><span style="font-weight: bold">Рейтинг MPAA:</span> <span style="color: #FF6000"><span style="font-weight: bold">R</span> (лицам до 17 лет обязательно присутствие взрослого)</span></span><br /><span style="font-size: 11px; line-height: normal"><span style="font-weight: bold">Дата мировой премьеры:</span> 1 сентября 2016</span><br /><span style="font-size: 11px; line-height: normal"><span style="font-weight: bold">Дата российской премьеры:</span> 8 сентября 2016, «Двадцатый Век Фокс СНГ»</span><br /><br /><span style="font-weight: bold">Релиз от:</span> <img src="{ASSETS}/forum/image.php?link=http://s020.radikal.ru/i712/1503/80/49b7bc4e3261.gif"> <span style="color: blue">NNMClub</span><br /><br /><span style="font-weight: bold">Продолжительность:</span> 01:31:52<br /><span style="font-weight: bold">Качество видео:</span> BDRip <a href="http://sendfile.su/1288607" rel="nofollow" class="postLink"><img src="{ASSETS}/forum/image.php?link=http://nnmclub.to/forum/images/channel/sample_light_nnm.png"></a><br /><span style="font-weight: bold">Перевод:</span> Дублированный (iTunes)<br /><span style="font-weight: bold">Вид субтитров:</span> Вшитые отключаемые<br /><span style="font-weight: bold">Язык субтитров:</span> Русский (форсированные на иностранные надписи)<br /><br /><span style="font-weight: bold">Видео:</span> H.264/AVC, 1280x536, 2938 kbps, 23.976 fps<br /><span style="font-weight: bold">Аудио:</span> AC3, 6 ch, 384 Kbps - Русский </a><div class="clear"></div> </a><div class="clear"></div> <div class="clear"></div><span style="text-align: center; display: block;"><span style="font-weight: bold">Скриншоты:</span><br /><a href="http://i5.imageban.ru/out/2016/12/07/d35e0e0ae99ca77b3ebdc69e77ec85cf.png" class="highslide" onclick="return hs.expand(this,{slideshowGroup: '8668771'})" rel="nofollow"><img src="{ASSETS}/forum/image.php?link=http://i4.imageban.ru/out/2016/12/07/4fc737ff3ff2f5e21f4fdc8e3027e635.png"></a> <a href="http://i2.imageban.ru/out/2016/12/07/7637dcf726f41bd78ef402e4ef8b78c9.png" class="highslide" onclick="return hs.expand(this,{slideshowGroup: '8668771'})" rel="nofollow"><img src="{ASSETS}/forum/image.php?link=http://i3.imageban.ru/out/2016/12/07/a3af40b6b0117e8618196ce7ec2f6056.png"></a> <a href="http://i5.imageban.ru/out/2016/12/07/618b741b4b80ac0c1d462339ed545cf0.png" class="highslide" onclick="return hs.expand(this,{slideshowGroup: '8668771'})" rel="nofollow"><img src="{ASSETS}/forum/image.php?link=http://i1.imageban.ru/out/2016/12/07/163e19955ccd5ff8e8773cddb5f1c29e.png"></a> <a href="http://i3.imageban.ru/out/2016/12/07/8db0d0a44c1afe42868e6a84f4341f4c.png" class="highslide" onclick="return hs.expand(this,{slideshowGroup: '8668771'})" rel="nofollow"><img src="{ASSETS}/forum/image.php?link=http://i3.imageban.ru/out/2016/12/07/85bec5c826a2796e7378cd5d37ea22fe.png"></a><br /></span><br /><span style="text-align: center; display: block;"><a href="http://nnmclub.to/?q=Morgan+2016&amp;w=title" rel="nofollow" class="postLink"><span style="font-size: 16px; line-height: normal"><span style="color: #800000"><span style="font-weight: bold">Все одноименные релизы в Клубе</span></span></span></a></span><br /><span style="font-size: 12px; line-height: normal"><span style="font-weight: bold">Время раздачи:</span> 24/7 до первых 10-и скачавших</span></description>
and we can see the following part:
... href="http://www.kinopoisk.ru/film/906340/" ...
The script find this url by regexp and get the kinopoisk id.
You can use this manipulate for any pages with kinopoisk urls. Or you can rewrite the regexp to get the kinopoisk id from another data types.
how we login to nnmclub? where to set cookies or what's uk ?
uk
is the passkey from the update profile page:
https://nnmclub.to/forum/profile.php?mode=editprofile
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
Как пофиксить? Спасибо.
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)
Hey.
I am trying to implement a plug-in in your config. It is not clear where to throw myself with the plugin file.
He throws in Flexget root juts error.
2016-02-26 20:43 CRITICAL manager [/tasks/nnm-club] The key
kinopoisk
is not valid here. Only known plugin names are valid keys.2016-02-26 20:43 CRITICAL manager Failed to load config file: Did not pass schema validation.
Could not start manager: Did not pass schema validation.