Support x many servers of any combination

This commit is contained in:
Luigi311
2022-06-13 22:30:41 -06:00
parent 7ef2986bde
commit 7695994ec2
6 changed files with 192 additions and 114 deletions

View File

@@ -2,8 +2,8 @@
DRYRUN = "True" DRYRUN = "True"
## Additional logging information ## Additional logging information
DEBUG = "True" DEBUG = "True"
## Debugging level, INFO is default, DEBUG is more verbose ## Debugging level, "info" is default, "debug" is more verbose
DEBUG_LEVEL = "INFO" DEBUG_LEVEL = "info"
## How often to run the script in seconds ## How often to run the script in seconds
SLEEP_DURATION = "3600" SLEEP_DURATION = "3600"
## Log file where all output will be written to ## Log file where all output will be written to
@@ -16,6 +16,7 @@ LOGFILE = "log.log"
## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers ## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers
## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly ## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly
## Comma seperated list for multiple servers
PLEX_BASEURL = "http://localhost:32400" PLEX_BASEURL = "http://localhost:32400"
## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ ## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
PLEX_TOKEN = "SuperSecretToken" PLEX_TOKEN = "SuperSecretToken"
@@ -26,6 +27,7 @@ PLEX_TOKEN = "SuperSecretToken"
## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly ## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly
## Comma seperated list for multiple servers
JELLYFIN_BASEURL = "http://localhost:8096" JELLYFIN_BASEURL = "http://localhost:8096"
## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key ## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key
JELLYFIN_TOKEN = "SuperSecretToken" JELLYFIN_TOKEN = "SuperSecretToken"

View File

@@ -6,7 +6,11 @@ Sync watched between jellyfin and plex
## Description ## Description
Keep in sync all your users watched history between jellyfin and plex locally. This uses the imdb ids and any other matching id to find the correct episode/movie between the two. This is not perfect but it works for most cases. Keep in sync all your users watched history between jellyfin and plex servers locally. This uses the imdb ids and any other matching id to find the correct episode/movie between the two. This is not perfect but it works for most cases. You can use this for as many servers as you want by enterying multiple options in the .env plex/jellyfin section seperated by commas.
## Configuration
## Installation ## Installation

185
main.py
View File

@@ -168,34 +168,49 @@ def setup_black_white_lists(library_mapping=None):
return blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users return blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users
def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=None): def setup_users(server_1, server_2, blacklist_users, whitelist_users, user_mapping=None):
# generate list of users from server 1 and server 2
server_1_type = server_1[0]
server_1_connection = server_1[1]
server_2_type = server_2[0]
server_2_connection = server_2[1]
server_1_users = []
if server_1_type == "plex":
server_1_users = [ x.title.lower() for x in server_1_connection.users ]
elif server_1_type == "jellyfin":
server_1_users = [ key.lower() for key in server_1_connection.users.keys() ]
server_2_users = []
if server_2_type == "plex":
server_2_users = [ x.title.lower() for x in server_2_connection.users ]
elif server_2_type == "jellyfin":
server_2_users = [ key.lower() for key in server_2_connection.users.keys() ]
# generate list of users from plex.users
plex_users = [ x.title.lower() for x in plex.users ]
jellyfin_users = [ key.lower() for key in jellyfin.users.keys() ]
# combined list of overlapping users from plex and jellyfin # combined list of overlapping users from plex and jellyfin
users = {} users = {}
for plex_user in plex_users: for server_1_user in server_1_users:
if user_mapping: if user_mapping:
jellyfin_plex_mapped_user = search_mapping(user_mapping, plex_user) jellyfin_plex_mapped_user = search_mapping(user_mapping, server_1_user)
if jellyfin_plex_mapped_user: if jellyfin_plex_mapped_user:
users[plex_user] = jellyfin_plex_mapped_user users[server_1_user] = jellyfin_plex_mapped_user
continue continue
if plex_user in jellyfin_users: if server_1_user in server_2_users:
users[plex_user] = plex_user users[server_1_user] = server_1_user
for jellyfin_user in jellyfin_users: for server_2_user in server_2_users:
if user_mapping: if user_mapping:
plex_jellyfin_mapped_user = search_mapping(user_mapping, jellyfin_user) plex_jellyfin_mapped_user = search_mapping(user_mapping, server_2_user)
if plex_jellyfin_mapped_user: if plex_jellyfin_mapped_user:
users[plex_jellyfin_mapped_user] = jellyfin_user users[plex_jellyfin_mapped_user] = server_2_user
continue continue
if jellyfin_user in plex_users: if server_2_user in server_1_users:
users[jellyfin_user] = jellyfin_user users[server_2_user] = server_2_user
logger(f"User list that exist on both servers {users}", 1) logger(f"User list that exist on both servers {users}", 1)
@@ -212,26 +227,84 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N
logger(f"Filtered user list {users_filtered}", 1) logger(f"Filtered user list {users_filtered}", 1)
plex_users = [] if server_1_type == "plex":
for plex_user in plex.users: output_server_1_users = []
if plex_user.title.lower() in users_filtered.keys() or plex_user.title.lower() in users_filtered.values(): for plex_user in server_1_connection.users:
plex_users.append(plex_user) if plex_user.title.lower() in users_filtered.keys() or plex_user.title.lower() in users_filtered.values():
output_server_1_users.append(plex_user)
elif server_1_type == "jellyfin":
output_server_1_users = {}
for jellyfin_user, jellyfin_id in server_1_connection.users.items():
if jellyfin_user.lower() in users_filtered.keys() or jellyfin_user.lower() in users_filtered.values():
output_server_1_users[jellyfin_user] = jellyfin_id
jellyfin_users = {} if server_2_type == "plex":
for jellyfin_user, jellyfin_id in jellyfin.users.items(): output_server_2_users = []
if jellyfin_user.lower() in users_filtered.keys() or jellyfin_user.lower() in users_filtered.values(): for plex_user in server_2_connection.users:
jellyfin_users[jellyfin_user] = jellyfin_id if plex_user.title.lower() in users_filtered.keys() or plex_user.title.lower() in users_filtered.values():
output_server_2_users.append(plex_user)
elif server_2_type == "jellyfin":
output_server_2_users = {}
for jellyfin_user, jellyfin_id in server_2_connection.users.items():
if jellyfin_user.lower() in users_filtered.keys() or jellyfin_user.lower() in users_filtered.values():
output_server_2_users[jellyfin_user] = jellyfin_id
if len(plex_users) == 0: if len(output_server_1_users) == 0:
raise Exception(f"No plex users found, users found {users} filtered users {users_filtered}") raise Exception(f"No users found for server 1, users found {users} filtered users {users_filtered}")
if len(jellyfin_users) == 0: if len(output_server_2_users) == 0:
raise Exception(f"No jellyfin users found, users found {users} filtered users {users_filtered}") raise Exception(f"No users found for server 2, users found {users} filtered users {users_filtered}")
logger(f"plex_users: {plex_users}", 1) logger(f"Server 1 users: {output_server_1_users}", 1)
logger(f"jellyfin_users: {jellyfin_users}", 1) logger(f"Server 2 users: {output_server_2_users}", 1)
return plex_users, jellyfin_users return output_server_1_users, output_server_2_users
def generate_server_connections():
servers = []
plex_baseurl = os.getenv("PLEX_BASEURL", None)
plex_token = os.getenv("PLEX_TOKEN", None)
plex_username = os.getenv("PLEX_USERNAME", None)
plex_password = os.getenv("PLEX_PASSWORD", None)
plex_servername = os.getenv("PLEX_SERVERNAME", None)
if plex_baseurl and plex_token:
plex_baseurl = plex_baseurl.split(",")
plex_token = plex_token.split(",")
if len(plex_baseurl) != len(plex_token):
raise Exception("PLEX_BASEURL and PLEX_TOKEN must have the same number of entries")
for i in range(len(plex_baseurl)):
servers.append(("plex", Plex(baseurl=plex_baseurl[i].strip(), token=plex_token[i].strip(), username=None, password=None, servername=None)))
if plex_username and plex_password and plex_servername:
plex_username = plex_username.split(",")
plex_password = plex_password.split(",")
plex_servername = plex_servername.split(",")
if len(plex_username) != len(plex_password) or len(plex_username) != len(plex_servername):
raise Exception("PLEX_USERNAME, PLEX_PASSWORD and PLEX_SERVERNAME must have the same number of entries")
for i in range(len(plex_username)):
servers.append(("plex", Plex(baseurl=None, token=None, username=plex_username[i].strip(), password=plex_password[i].strip(), servername=plex_servername[i].strip())))
jellyfin_baseurl = os.getenv("JELLYFIN_BASEURL", None)
jellyfin_token = os.getenv("JELLYFIN_TOKEN", None)
if jellyfin_baseurl and jellyfin_token:
jellyfin_baseurl = jellyfin_baseurl.split(",")
jellyfin_token = jellyfin_token.split(",")
if len(jellyfin_baseurl) != len(jellyfin_token):
raise Exception("JELLYFIN_BASEURL and JELLYFIN_TOKEN must have the same number of entries")
for i in range(len(jellyfin_baseurl)):
servers.append(("jellyfin", Jellyfin(baseurl=jellyfin_baseurl[i].strip(), token=jellyfin_token[i].strip())))
print(f"Servers: {servers}")
return servers
def main(): def main():
logfile = os.getenv("LOGFILE","log.log") logfile = os.getenv("LOGFILE","log.log")
@@ -252,34 +325,50 @@ def main():
library_mapping = json.loads(library_mapping) library_mapping = json.loads(library_mapping)
logger(f"Library Mapping: {library_mapping}", 1) logger(f"Library Mapping: {library_mapping}", 1)
plex = Plex()
jellyfin = Jellyfin()
# Create (black/white)lists # Create (black/white)lists
blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users = setup_black_white_lists(library_mapping) blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users = setup_black_white_lists(library_mapping)
# Create users list # Create server connections
plex_users, jellyfin_users = setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping) servers = generate_server_connections()
plex_watched = plex.get_plex_watched(plex_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping) for server_1 in servers:
jellyfin_watched = jellyfin.get_jellyfin_watched(jellyfin_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping) # If server is the final server in the list, then we are done with the loop
if server_1 == servers[-1]:
break
# clone watched so it isnt modified in the cleanup function so all duplicates are actually removed # Start server_2 at the next server in the list
plex_watched_filtered = copy.deepcopy(plex_watched) servers_2_ = servers[servers.index(server_1) + 1:]
jellyfin_watched_filtered = copy.deepcopy(jellyfin_watched) for server_2 in servers[servers.index(server_1) + 1:]:
print(f"server_1: {server_1}, server_2: {server_2}")
logger("Cleaning Plex Watched", 1) server_1_type = server_1[0]
plex_watched = cleanup_watched(plex_watched_filtered, jellyfin_watched_filtered, user_mapping, library_mapping) server_1_connection = server_1[1]
logger("Cleaning Jellyfin Watched", 1) server_2_type = server_2[0]
jellyfin_watched = cleanup_watched(jellyfin_watched_filtered, plex_watched_filtered, user_mapping, library_mapping) server_2_connection = server_2[1]
logger(f"plex_watched that needs to be synced to jellyfin:\n{plex_watched}", 1) # Create users list
logger(f"jellyfin_watched that needs to be synced to plex:\n{jellyfin_watched}", 1) server_1_users, server_2_users = setup_users(server_1, server_2, blacklist_users, whitelist_users, user_mapping)
# Update watched status server_1_watched = server_1_connection.get_watched(server_1_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping)
plex.update_watched(jellyfin_watched, user_mapping, library_mapping, dryrun) server_2_watched = server_2_connection.get_watched(server_2_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping)
jellyfin.update_watched(plex_watched, user_mapping, library_mapping, dryrun)
# clone watched so it isnt modified in the cleanup function so all duplicates are actually removed
server_1_watched_filtered = copy.deepcopy(server_1_watched)
server_2_watched_filtered = copy.deepcopy(server_2_watched)
logger("Cleaning Server 1 Watched", 1)
server_1_watched_filtered = cleanup_watched(server_1_watched, server_2_watched, user_mapping, library_mapping)
logger("Cleaning Server 2 Watched", 1)
server_2_watched_filtered = cleanup_watched(server_2_watched, server_1_watched, user_mapping, library_mapping)
logger(f"server 1 watched that needs to be synced to server 2:\n{server_1_watched_filtered}", 1)
logger(f"server 2 watched that needs to be synced to server 1:\n{server_2_watched_filtered}", 1)
# Update watched status
server_1_connection.update_watched(server_2_watched_filtered, user_mapping, library_mapping, dryrun)
server_2_connection.update_watched(server_1_watched_filtered, user_mapping, library_mapping, dryrun)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -6,16 +6,16 @@ logfile = os.getenv("LOGFILE","log.log")
def logger(message, log_type=0): def logger(message, log_type=0):
debug = str_to_bool(os.getenv("DEBUG", "True")) debug = str_to_bool(os.getenv("DEBUG", "True"))
debug_level = os.getenv("DEBUG_LEVEL", "INFO") debug_level = os.getenv("DEBUG_LEVEL", "info").lower()
output = str(message) output = str(message)
if log_type == 0: if log_type == 0:
pass pass
elif log_type == 1 and (debug or debug_level == "INFO"): elif log_type == 1 and (debug or debug_level == "info"):
output = f"[INFO]: {output}" output = f"[INFO]: {output}"
elif log_type == 2: elif log_type == 2:
output = f"[ERROR]: {output}" output = f"[ERROR]: {output}"
elif log_type == 3 and (debug and debug_level == "DEBUG"): elif log_type == 3 and (debug and debug_level == "debug"):
output = f"[DEBUG]: {output}" output = f"[DEBUG]: {output}"
else: else:
output = None output = None

View File

@@ -1,16 +1,10 @@
import requests, os import requests
from dotenv import load_dotenv
from src.functions import logger, search_mapping, str_to_bool, check_skip_logic, generate_library_guids_dict from src.functions import logger, search_mapping, str_to_bool, check_skip_logic, generate_library_guids_dict
load_dotenv(override=True)
jellyfin_baseurl = os.getenv("JELLYFIN_BASEURL")
jellyfin_token = os.getenv("JELLYFIN_TOKEN")
class Jellyfin(): class Jellyfin():
def __init__(self): def __init__(self, baseurl, token):
self.baseurl = jellyfin_baseurl self.baseurl = baseurl
self.token = jellyfin_token self.token = token
if not self.baseurl: if not self.baseurl:
raise Exception("Jellyfin baseurl not set") raise Exception("Jellyfin baseurl not set")
@@ -56,7 +50,7 @@ class Jellyfin():
return users return users
def get_jellyfin_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping=None): def get_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping=None):
users_watched = {} users_watched = {}
for user_name, user_id in users.items(): for user_name, user_id in users.items():
@@ -131,46 +125,45 @@ class Jellyfin():
def update_watched(self, watched_list, user_mapping=None, library_mapping=None, dryrun=False): def update_watched(self, watched_list, user_mapping=None, library_mapping=None, dryrun=False):
for user, libraries in watched_list.items(): for user, libraries in watched_list.items():
user_other = None
if user_mapping: if user_mapping:
user_other = None
if user in user_mapping.keys(): if user in user_mapping.keys():
user_other = user_mapping[user] user_other = user_mapping[user]
elif user in user_mapping.values(): elif user in user_mapping.values():
user_other = search_mapping(user_mapping, user) user_other = search_mapping(user_mapping, user)
if user_other:
logger(f"Swapping user {user} with {user_other}", 1)
user = user_other
user_id = None user_id = None
for key in self.users.keys(): for key in self.users.keys():
if user.lower() == key.lower(): if user.lower() == key.lower():
user_id = self.users[key] user_id = self.users[key]
break break
elif user_other and user_other.lower() == key.lower():
user_id = self.users[key]
break
if not user_id: if not user_id:
logger(f"{user} not found in Jellyfin", 2) logger(f"{user} {user_other} not found in Jellyfin", 2)
break break
jellyfin_libraries = self.query(f"/Users/{user_id}/Views", "get")["Items"] jellyfin_libraries = self.query(f"/Users/{user_id}/Views", "get")["Items"]
for library, videos in libraries.items(): for library, videos in libraries.items():
library_other = None
if library_mapping: if library_mapping:
library_other = None
if library in library_mapping.keys(): if library in library_mapping.keys():
library_other = library_mapping[library] library_other = library_mapping[library]
elif library in library_mapping.values(): elif library in library_mapping.values():
library_other = search_mapping(library_mapping, library) library_other = search_mapping(library_mapping, library)
if library_other:
logger(f"Swapping library {library} with {library_other}", 1)
library = library_other
if library not in [x["Name"] for x in jellyfin_libraries]: if library.lower() not in [x["Name"].lower() for x in jellyfin_libraries]:
logger(f"{library} not found in Jellyfin", 2) if library_other and library_other.lower() in [x["Name"].lower() for x in jellyfin_libraries]:
continue logger(f"Plex: Library {library} not found, but {library_other} found, using {library_other}", 1)
library = library_other
else:
logger(f"Library {library} {library_other} not found in Plex library list", 2)
continue
library_id = None library_id = None
for jellyfin_library in jellyfin_libraries: for jellyfin_library in jellyfin_libraries:

View File

@@ -1,31 +1,22 @@
import re, os import re
from dotenv import load_dotenv
from src.functions import logger, search_mapping, check_skip_logic, generate_library_guids_dict from src.functions import logger, search_mapping, check_skip_logic, generate_library_guids_dict
from plexapi.server import PlexServer from plexapi.server import PlexServer
from plexapi.myplex import MyPlexAccount from plexapi.myplex import MyPlexAccount
load_dotenv(override=True)
plex_baseurl = os.getenv("PLEX_BASEURL")
plex_token = os.getenv("PLEX_TOKEN")
username = os.getenv("PLEX_USERNAME")
password = os.getenv("PLEX_PASSWORD")
servername = os.getenv("PLEX_SERVERNAME")
# class plex accept base url and token and username and password but default with none # class plex accept base url and token and username and password but default with none
class Plex: class Plex:
def __init__(self): def __init__(self, baseurl=None, token=None, username=None, password=None, servername=None):
self.baseurl = plex_baseurl self.baseurl = baseurl
self.token = plex_token self.token = token
self.username = username self.username = username
self.password = password self.password = password
self.servername = servername self.servername = servername
self.plex = self.plex_login() self.plex = self.login()
self.admin_user = self.plex.myPlexAccount() self.admin_user = self.plex.myPlexAccount()
self.users = self.get_plex_users() self.users = self.get_users()
def plex_login(self): def login(self):
try: try:
if self.baseurl and self.token: if self.baseurl and self.token:
# Login via token # Login via token
@@ -47,7 +38,7 @@ class Plex:
return None return None
def get_plex_users(self): def get_users(self):
users = self.plex.myPlexAccount().users() users = self.plex.myPlexAccount().users()
# append self to users # append self to users
@@ -55,7 +46,7 @@ class Plex:
return users return users
def get_plex_user_watched(self, user, library): def get_user_watched(self, user, library):
if self.admin_user == user: if self.admin_user == user:
user_plex = self.plex user_plex = self.plex
else: else:
@@ -110,7 +101,7 @@ class Plex:
return watched return watched
def get_plex_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping): def get_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping):
# Get all libraries # Get all libraries
libraries = self.plex.library.sections() libraries = self.plex.library.sections()
users_watched = {} users_watched = {}
@@ -129,7 +120,7 @@ class Plex:
for user in users: for user in users:
logger(f"Plex: Generating watched for {user.title} in library {library_title}", 0) logger(f"Plex: Generating watched for {user.title} in library {library_title}", 0)
user_name = user.title.lower() user_name = user.title.lower()
watched = self.get_plex_user_watched(user, library) watched = self.get_user_watched(user, library)
if watched: if watched:
if user_name not in users_watched: if user_name not in users_watched:
users_watched[user_name] = {} users_watched[user_name] = {}
@@ -141,22 +132,21 @@ class Plex:
def update_watched(self, watched_list, user_mapping=None, library_mapping=None, dryrun=False): def update_watched(self, watched_list, user_mapping=None, library_mapping=None, dryrun=False):
for user, libraries in watched_list.items(): for user, libraries in watched_list.items():
user_other = None
# If type of user is dict
if user_mapping: if user_mapping:
user_other = None
if user in user_mapping.keys(): if user in user_mapping.keys():
user_other = user_mapping[user] user_other = user_mapping[user]
elif user in user_mapping.values(): elif user in user_mapping.values():
user_other = search_mapping(user_mapping, user) user_other = search_mapping(user_mapping, user)
if user_other:
logger(f"Swapping user {user} with {user_other}", 1)
user = user_other
for index, value in enumerate(self.users): for index, value in enumerate(self.users):
if user.lower() == value.title.lower(): if user.lower() == value.title.lower():
user = self.users[index] user = self.users[index]
break break
elif user_other and user_other.lower() == value.title.lower():
user = self.users[index]
break
if self.admin_user == user: if self.admin_user == user:
user_plex = self.plex user_plex = self.plex
@@ -164,23 +154,22 @@ class Plex:
user_plex = PlexServer(self.baseurl, user.get_token(self.plex.machineIdentifier)) user_plex = PlexServer(self.baseurl, user.get_token(self.plex.machineIdentifier))
for library, videos in libraries.items(): for library, videos in libraries.items():
library_other = None
if library_mapping: if library_mapping:
library_other = None
if library in library_mapping.keys(): if library in library_mapping.keys():
library_other = library_mapping[library] library_other = library_mapping[library]
elif library in library_mapping.values(): elif library in library_mapping.values():
library_other = search_mapping(library_mapping, library) library_other = search_mapping(library_mapping, library)
if library_other:
logger(f"Swapping library {library} with {library_other}", 1)
library = library_other
# if library in plex library list # if library in plex library list
library_list = user_plex.library.sections() library_list = user_plex.library.sections()
if library.lower() not in [x.title.lower() for x in library_list]: if library.lower() not in [x.title.lower() for x in library_list]:
logger(f"Library {library} not found in Plex library list", 2) if library_other and library_other.lower() in [x.title.lower() for x in library_list]:
continue logger(f"Plex: Library {library} not found, but {library_other} found, using {library_other}", 1)
library = library_other
else:
logger(f"Library {library} {library_other} not found in Plex library list", 2)
continue
logger(f"Plex: Updating watched for {user.title} in library {library}", 1) logger(f"Plex: Updating watched for {user.title} in library {library}", 1)
library_videos = user_plex.library.section(library) library_videos = user_plex.library.section(library)
@@ -191,6 +180,7 @@ class Plex:
for movie_guid in movies_search.guids: for movie_guid in movies_search.guids:
movie_guid_source = re.search(r'(.*)://', movie_guid.id).group(1).lower() movie_guid_source = re.search(r'(.*)://', movie_guid.id).group(1).lower()
movie_guid_id = re.search(r'://(.*)', movie_guid.id).group(1) movie_guid_id = re.search(r'://(.*)', movie_guid.id).group(1)
# If movie provider source and movie provider id are in videos_movie_ids exactly, then the movie is in the list # If movie provider source and movie provider id are in videos_movie_ids exactly, then the movie is in the list
if movie_guid_source in videos_movies_ids.keys(): if movie_guid_source in videos_movies_ids.keys():
if movie_guid_id in videos_movies_ids[movie_guid_source]: if movie_guid_id in videos_movies_ids[movie_guid_source]: