JBOPS/reporting/plex_netflix_check.py

253 lines
10 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
2017-09-16 01:45:46 +00:00
"""
2018-03-23 17:13:22 +00:00
usage: plex_netflix_check.py [-h] [-l [...]] [-s ] [-t ]
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
Use instantwatcher.com to find if Plex items are on Netflix, Amazon, or both.
2017-09-16 01:45:46 +00:00
optional arguments:
-h, --help show this help message and exit
-l [ ...], --library [ ...]
Space separated list of case sensitive names to process. Allowed names are:
(choices: Your show or movie library names)
-s [], --search [] Search any name.
-t [], --type [] Refine search for name by using type.
2017-10-25 19:23:50 +00:00
(choices: movie, show)
-e [], --episodes [] Refine search for individual episodes.
(choices: True, False)
(default: False)
-site [], --site [] Refine search for name by using type.
(choices: Netflix, Amazon, Both)
(default: Both)
-sl [], --search_limit []
Define number of search returns from page. Zero returns all.
(default: 5)
If title is matched in both, Amazon is first then Netflix.
2017-09-16 01:45:46 +00:00
"""
2020-07-04 20:08:59 +00:00
from __future__ import print_function
2020-07-04 20:31:02 +00:00
from __future__ import unicode_literals
2017-09-15 18:05:22 +00:00
2020-07-04 20:23:47 +00:00
from builtins import str
2017-09-15 18:05:22 +00:00
import requests
2017-09-16 01:45:46 +00:00
import argparse
2017-09-15 18:05:22 +00:00
from xmljson import badgerfish as bf
from lxml.html import fromstring
from time import sleep
from plexapi.server import PlexServer, CONFIG
2017-09-15 18:05:22 +00:00
# pip install plexapi
# ## Edit ##
PLEX_URL = ''
PLEX_TOKEN = ''
if not PLEX_URL:
PLEX_URL = CONFIG.data['auth'].get('server_baseurl', '')
if not PLEX_TOKEN:
PLEX_TOKEN = CONFIG.data['auth'].get('server_token', '')
# ## /Edit ##
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
sess = requests.Session()
# Ignore verifying the SSL certificate
sess.verify = False # '/path/to/certfile'
# If verify is set to a path to a directory,
# the directory must have been processed using the c_rehash utility supplied
# with OpenSSL.
if sess.verify is False:
# Disable the warning that the request is insecure, we know that...
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
2017-10-25 19:23:50 +00:00
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
def instantwatch_search(name, media_type, site, search_limit):
2017-09-15 18:05:22 +00:00
NETFLIX_URL = 'http://www.netflix.com/title/'
2017-10-25 19:23:50 +00:00
limit = False
results_count = 0
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
if media_type == 'movie':
2017-09-15 19:02:45 +00:00
content_type = '1'
2017-10-25 19:23:50 +00:00
elif media_type == 'show':
content_type = '2'
elif media_type == 'episode':
content_type = '4'
2017-09-15 18:05:22 +00:00
else:
content_type = ''
2017-09-15 18:05:22 +00:00
2017-09-15 19:02:45 +00:00
payload = {'content_type': content_type,
'q': name.lower()}
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
if site == 'Netflix':
r = requests.get('http://instantwatcher.com/netflix/78/search'.rstrip('/'), params=payload)
2017-10-25 19:23:50 +00:00
elif site == 'Amazon':
r = requests.get('http://instantwatcher.com/amazon/search'.rstrip('/'), params=payload)
2017-10-25 19:23:50 +00:00
else:
r = requests.get('http://instantwatcher.com/u/search'.rstrip('/'), params=payload)
if r.status_code != 200:
print('{} not found: {}'.format(name, r.url))
return 0
2017-09-15 19:02:45 +00:00
results_lst = []
2017-09-15 18:05:22 +00:00
res_data = bf.data(fromstring(r.content))
2017-09-16 01:45:46 +00:00
2017-09-15 18:05:22 +00:00
res_data = res_data['html']['body']['div']['div'][1]
# Any matches?
res_results = res_data['div'][1]['div'][0]
title_check = res_data['div'][1]['div'][1]
2017-09-15 18:05:22 +00:00
try:
2017-10-25 19:23:50 +00:00
if res_results['span']:
total_results = res_results['span']
2017-09-15 18:05:22 +00:00
for data in total_results:
results_lst += [data['$']]
except Exception:
pass
print('{} found {}.'.format(results_lst[0], results_lst[1]))
2017-09-16 01:45:46 +00:00
result_count = int(results_lst[1].split(' ')[0])
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
amazon_id = ''
amazon_url = ''
2017-09-15 18:05:22 +00:00
# Title match
2017-09-16 01:45:46 +00:00
if result_count == 0:
2017-09-15 18:05:22 +00:00
print('0 matches, moving on.')
pass
else:
item_results_page = title_check['div']['div']
2017-09-16 01:45:46 +00:00
if result_count > 1:
2017-09-15 18:05:22 +00:00
for results in item_results_page:
2017-10-25 19:23:50 +00:00
for data in results['a']:
try:
amazon_id = data['@data-amazon-title-id']
amazon_url = data['@data-amazon-uri']
except Exception:
pass
2017-09-15 18:05:22 +00:00
for data in results['span']:
if data['@class'] == 'title' and search_limit != 0:
if str(data['a']['$']).lower().startswith(name.lower()):
2017-10-25 19:23:50 +00:00
if amazon_id:
if data['a']['@data-title-id'] == amazon_id:
print('Match found on Amazon for {}'.format(data['a']['$']))
print('Page: {}'.format(amazon_url))
else:
print('Match found on Netflix for {}'.format(data['a']['$']))
print('Page: {}{}'.format(NETFLIX_URL, data['a']['@data-title-id']))
results_count += 1
2017-09-16 01:45:46 +00:00
search_limit -= 1
if search_limit == 0:
2017-10-25 19:23:50 +00:00
limit = True
elif data['@class'] == 'title' and search_limit == 0 and limit is False:
2017-10-25 19:23:50 +00:00
if data['a']['$'].lower().startswith(name.lower()):
if amazon_id:
if data['a']['@data-title-id'] == amazon_id:
print('Match found on Amazon for {}'.format(data['a']['$']))
print('Page: {}'.format(amazon_url))
else:
print('Match found on Netflix for {}'.format(data['a']['$']))
print('Page: {}{}'.format(NETFLIX_URL, data['a']['@data-title-id']))
results_count += 1
2017-09-15 18:05:22 +00:00
2017-09-16 01:45:46 +00:00
elif result_count == 1:
2017-10-25 19:23:50 +00:00
for data in item_results_page['a']:
try:
amazon_id = data['@data-amazon-title-id']
amazon_url = data['@data-amazon-uri']
except Exception:
pass
2017-09-15 18:05:22 +00:00
for data in item_results_page['span']:
if data['@class'] == 'title':
2017-10-25 19:23:50 +00:00
if data['a']['$'].lower().startswith(name.lower()):
print('Match! For {}'.format(data['a']['$']))
if amazon_id:
if data['a']['@data-title-id'] == amazon_id:
print('Page: {}'.format(amazon_url))
else:
print('Page: {}{}'.format(NETFLIX_URL, data['a']['@data-title-id']))
results_count += 1
2017-09-15 18:05:22 +00:00
else:
print('Could not find exact name match.')
2017-10-25 19:23:50 +00:00
return results_count
def plex_library_search(lib_name, site, epi_search, search_limit):
for title in plex.library.section(lib_name).all():
print('Running check on {}'.format(title.title))
file_path = []
if title.type == 'show' and epi_search is True:
if instantwatch_search(title.title, title.type, site, search_limit) > 0:
print('Show was found. Searching for episode paths.')
for episode in title.episodes():
# Need to check episodes against sites to truly find episode matches.
# For now just return paths for episodes if Show name matches.
# print('Running check on {} - {}'.format(title.title, episode.title))
# show_ep = '{} - {}'.format(title.title, episode.title)
# if instantwatch_search(show_ep, 'episode', site) > 0:
file_path += [episode.media[0].parts[0].file]
elif title.type == 'movie':
if instantwatch_search(title.title, title.type, site, search_limit) > 0:
file_path = title.media[0].parts[0].file
else:
if instantwatch_search(title.title, title.type, site, search_limit) > 0:
print('Show was found but path is not defined.')
2017-09-15 18:05:22 +00:00
2017-10-25 19:23:50 +00:00
if file_path:
if type(file_path) is str:
print('File: {}'.format(file_path))
elif type(file_path) is list:
print('Files: \n{}'.format(' \n'.join(file_path)))
2017-09-15 19:02:45 +00:00
2017-09-16 01:45:46 +00:00
print('Waiting 5 seconds before next search.')
sleep(5)
2017-09-15 18:05:22 +00:00
2017-09-16 01:45:46 +00:00
def main():
sections_lst = [d.title for d in plex.library.sections() if d.type in ['show', 'movie']]
parser = argparse.ArgumentParser(description="Use instantwatcher.com to find if Plex items are on Netflix.",
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-l', '--library', metavar='', choices=sections_lst, nargs='+',
help='Space separated list of case sensitive names to process. Allowed names are:\n'
'(choices: %(choices)s)')
parser.add_argument('-s', '--search', metavar='', nargs='?', type=str,
2017-09-16 01:45:46 +00:00
help='Search any name.')
2017-10-25 19:23:50 +00:00
parser.add_argument('-m', '--media_type', metavar='', choices=['movie', 'show'], nargs='?',
help='Refine search for name by using media type.\n'
'(choices: %(choices)s)')
parser.add_argument('-e', '--episodes', metavar='', nargs='?', type=bool, default=False, choices=[True, False],
help='Refine search for individual episodes.\n'
'(choices: %(choices)s)\n(default: %(default)s)')
parser.add_argument('-site', '--site', metavar='', choices=['Netflix', 'Amazon', 'Both'], nargs='?',
default='Netflix', help='Refine search for name by using type.\n'
'(choices: %(choices)s)\n(default: %(default)s)')
2017-10-25 19:23:50 +00:00
parser.add_argument('-sl', '--search_limit', metavar='', nargs='?', type=int, default=5,
help='Define number of search returns from page. Zero returns all.'
'\n(default: %(default)s)')
2017-09-16 01:45:46 +00:00
opts = parser.parse_args()
# print(opts)
if opts.search:
2017-10-25 19:23:50 +00:00
instantwatch_search(opts.search, opts.media_type, opts.site, opts.search_limit)
2017-09-16 01:45:46 +00:00
else:
if len(opts.library) > 1:
for section in opts.library:
2017-10-25 19:23:50 +00:00
plex_library_search(section, opts.site, opts.episodes, opts.search_limit)
2017-09-16 01:45:46 +00:00
else:
2017-10-25 19:23:50 +00:00
plex_library_search(opts.library[0], opts.site, opts.episodes, opts.search_limit)
2017-09-16 01:45:46 +00:00
2017-09-16 01:45:46 +00:00
if __name__ == '__main__':
main()