Windows
# Written with the following library versions:
# tmdbv3api 1.9.0
# ipytv 0.2.4
# ANY OTHER VERSIONS OF THESE LIBRARIES IS NOT SUPPORTED!
import os
import re
import logging
import argparse
import configparser
from tmdbv3api import TMDb, Movie, TV
from ipytv import playlist
# Initialize the TMDb object and set language and debug properties
tmdbobj = TMDb()
tmdbobj.language = 'en'
tmdbobj.debug = True
# Initialize the Movie and TV objects
movieobj = Movie()
tvobj = TV()
def configure_logging():
config = configparser.ConfigParser()
config.read('VODimage.conf')
# Default logging configuration
log_to_file = False
log_level = logging.ERROR
if config.has_section('Logging'):
log_to_file = config.getboolean('Logging', 'log_to_file', fallback=False)
log_level_str = config.get('Logging', 'log_level', fallback='ERROR')
# Convert log_level from string to integer constant
log_level = getattr(logging, log_level_str.upper(), logging.ERROR)
if log_to_file:
logging.basicConfig(filename=config.get('Logging', 'log_file', fallback='vod_processing.log'), level=log_level,
format='%(asctime)s - %(levelname)s - %(message)s')
else:
logging.basicConfig(level=log_level,
format='%(asctime)s - %(levelname)s - %(message)s')
def log_info(message):
print(message) # Print to console for visibility
logging.info(message) # Log to the file if configured to do so
def search_tmdb(search_query, is_movie=True):
# Search TMDB for either movie or TV show based on the given flag.
if is_movie:
results = movieobj.search(search_query)['results']
else:
results = tvobj.search(search_query)['results']
return results
def process_vod(vod, file):
try:
attributes = vod.attributes
title = vod.name
log_info("Title: {}".format(title))
processed = False
if "Movie VOD" in str(attributes):
# Process Movie VOD
title = re.sub(r'(\s*)HD : (\s*)', ' ', title)
title = re.sub(r'\b\d{4}\b', '', title).strip()
title = title.strip()
log_info("Search term for TMDB: {}".format(title))
search_results = search_tmdb(title)
if search_results:
res = search_results[0]
poster_path = res.get('poster_path')
Poster = "https://image.tmdb.org/t/p/w500" + poster_path if poster_path else "NONE"
with open(file, "a+") as file3:
file3.write("#EXTINF:0 " + str("tvg-logo=" + '"' + Poster + '",' + " group-title=" + '"' + "Movie VOD" + '", ' + title) + '\n')
file3.write("#EXTGRP:Movie VOD" '\n')
file3.write(vod.url + '\n')
processed = True
elif "TV VOD" in str(attributes):
# Process TV VOD
original_title = title
title = re.sub(r'(\s*)HD : | AU | NZ(\s*)', ' ', title)
# Construct a regex pattern to match the specified strings and everything after them
pattern = r'(\b(?:' + '|'.join(['Jimmy Fallon', 'Jimmy Kimmel', 'Stephen Colbert', '1923', 'Seth Meyers', 'The Daily Show']) + r')\b).*'
# Remove anything after the specified strings
title = re.sub(pattern, r'\1', title)
title = re.sub(r'\bS\d+E\d+\b', '', title)
title = re.sub(r'\b\d{4}\b', '', title).strip()
title = title.strip()
log_info("Search term for TMDB: {}".format(title))
search_results = search_tmdb(title, is_movie=False)
if search_results:
res = search_results[0]
poster_path = res.get('poster_path')
Poster = "https://image.tmdb.org/t/p/w500" + poster_path if poster_path else "DEFAULT_POSTER_URL"
with open(file, "a+") as file3:
file3.write("#EXTINF:0 " + str("tvg-logo=" + '"' + Poster + '",' + " group-title=" + '"' + "TV VOD" + '", ' + original_title) + '\n')
file3.write("#EXTGRP:TV VOD" '\n')
file3.write(vod.url + '\n')
processed = True
if processed:
log_info("VOD processed successfully.")
else:
log_info("No processing done for this VOD.")
log_info("") # Add a blank line after each VOD processed
except KeyError as e:
log_info("Key error occurred: {}".format(str(e)))
except IndexError as e:
log_info("Index error occurred: {}".format(str(e)))
except Exception as e:
log_info("An unexpected error occurred: {}".format(str(e)))
def print_example_config(output_file):
example_config = """
[UserVariables]
api_key = your_api_key_here
m3u_url = your_m3u_url_here
output_file = /path/to/example.m3u
[Logging]
log_to_file = True
log_file = VODimage.log
log_level = ERROR
"""
print("VODimage.conf has been created in this directory. Please open it and modify the variables.")
print("Example Configuration File:")
print(example_config)
# Save the example configuration to a file
with open(output_file, 'w') as config_file:
config_file.write(example_config)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Process VODs and generate M3U file')
parser.add_argument('--config', default='VODimage.conf', help='Config file (default: VODimage.conf)')
parser.add_argument('--api_key', help='TMDB API key')
parser.add_argument('--m3u_url', help='M3U playlist URL')
parser.add_argument('--output_file', help='Output M3U file')
parser.add_argument('--setup', action='store_true', help='Print example configuration and save as VODimage.conf')
args = parser.parse_args()
if args.setup:
# Specify the filename for the example config file
example_config_file = 'VODimage.conf'
print_example_config(example_config_file)
exit(0)
# Load user configuration
config = configparser.ConfigParser()
config.read(args.config)
# Configure logging
configure_logging()
# Initialize variables
api_key = args.api_key or config.get('UserVariables', 'api_key', fallback=None)
m3u_url = args.m3u_url or config.get('UserVariables', 'm3u_url', fallback=None)
output_file = args.output_file or config.get('UserVariables', 'output_file', fallback=None)
# Check if any required arguments are missing
if not api_key or not m3u_url or not output_file:
logging.error("Missing required arguments. Provide either through command-line or in the config file.")
exit(1)
# User-defined variables
TMDb.api_key = api_key
M3Uurl = m3u_url
file = output_file
# Check if file exists and remove if it does
if os.path.exists(file):
os.remove(file)
# Open file and write #EXTM3U on the first line and close it
with open(file, "w+") as file2:
file2.write("#EXTM3U" + '\n')
# Load playlist and leverage m3u-ipytv, sort if Movie or TV VOD
pl = playlist.loadu(M3Uurl)
# Count the VODs
total_vods = sum(1 for _ in pl)
log_info("Total VODs to process: {}".format(total_vods))
# Process each VOD
for i, vod in enumerate(pl):
log_info("Processing VOD {} of {}".format(i + 1, total_vods))
process_vod(vod, file)
log_info("") # Add a blank line in the log after each VOD processed to aid readability
log_info("Processing completed.")
Linux
#!/usr/bin/env python3
# Written with the following library versions:
# tmdbv3api 1.9.0
# ipytv 0.2.4
# ANY OTHER VERSIONS OF THESE LIBRARIES IS NOT SUPPORTED!
import os
import re
import logging
import argparse
import configparser
from tmdbv3api import TMDb, Movie, TV
from ipytv import playlist
# Initialize the TMDb object and set language and debug properties
tmdbobj = TMDb()
tmdbobj.language = 'en'
tmdbobj.debug = True
# Initialize the Movie and TV objects
movieobj = Movie()
tvobj = TV()
def configure_logging():
config = configparser.ConfigParser()
config.read('VODimage.conf')
# Default logging configuration
log_to_file = False
log_level = logging.ERROR
if config.has_section('Logging'):
log_to_file = config.getboolean('Logging', 'log_to_file', fallback=False)
log_level_str = config.get('Logging', 'log_level', fallback='ERROR')
# Convert log_level from string to integer constant
log_level = getattr(logging, log_level_str.upper(), logging.ERROR)
if log_to_file:
logging.basicConfig(filename=config.get('Logging', 'log_file', fallback='vod_processing.log'), level=log_level,
format='%(asctime)s - %(levelname)s - %(message)s')
else:
logging.basicConfig(level=log_level,
format='%(asctime)s - %(levelname)s - %(message)s')
def log_info(message):
print(message) # Print to console for visibility
logging.info(message) # Log to the file if configured to do so
def search_tmdb(search_query, is_movie=True):
# Search TMDB for either movie or TV show based on the given flag.
if is_movie:
results = movieobj.search(search_query)['results']
else:
results = tvobj.search(search_query)['results']
return results
def process_vod(vod, file):
try:
attributes = vod.attributes
title = vod.name
log_info("Title: {}".format(title))
processed = False
if "Movie VOD" in str(attributes):
# Process Movie VOD
title = re.sub(r'(\s*)HD : (\s*)', ' ', title)
title = re.sub(r'\b\d{4}\b', '', title).strip()
title = title.strip()
log_info("Search term for TMDB: {}".format(title))
search_results = search_tmdb(title)
if search_results:
res = search_results[0]
poster_path = res.get('poster_path')
Poster = "https://image.tmdb.org/t/p/w500" + poster_path if poster_path else "NONE"
with open(file, "a+") as file3:
file3.write("#EXTINF:0 " + str("tvg-logo=" + '"' + Poster + '",' + " group-title=" + '"' + "Movie VOD" + '", ' + title) + '\n')
file3.write("#EXTGRP:Movie VOD" '\n')
file3.write(vod.url + '\n')
processed = True
elif "TV VOD" in str(attributes):
# Process TV VOD
original_title = title
title = re.sub(r'(\s*)HD : | AU | NZ(\s*)', ' ', title)
# Construct a regex pattern to match the specified strings and everything after them
pattern = r'(\b(?:' + '|'.join(['Jimmy Fallon', 'Jimmy Kimmel', 'Stephen Colbert', '1923', 'Seth Meyers', 'The Daily Show']) + r')\b).*'
# Remove anything after the specified strings
title = re.sub(pattern, r'\1', title)
title = re.sub(r'\bS\d+E\d+\b', '', title)
title = re.sub(r'\b\d{4}\b', '', title).strip()
title = title.strip()
log_info("Search term for TMDB: {}".format(title))
search_results = search_tmdb(title, is_movie=False)
if search_results:
res = search_results[0]
poster_path = res.get('poster_path')
Poster = "https://image.tmdb.org/t/p/w500" + poster_path if poster_path else "DEFAULT_POSTER_URL"
with open(file, "a+") as file3:
file3.write("#EXTINF:0 " + str("tvg-logo=" + '"' + Poster + '",' + " group-title=" + '"' + "TV VOD" + '", ' + original_title) + '\n')
file3.write("#EXTGRP:TV VOD" '\n')
file3.write(vod.url + '\n')
processed = True
if processed:
log_info("VOD processed successfully.")
else:
log_info("No processing done for this VOD.")
log_info("") # Add a blank line after each VOD processed
except KeyError as e:
log_info("Key error occurred: {}".format(str(e)))
except IndexError as e:
log_info("Index error occurred: {}".format(str(e)))
except Exception as e:
log_info("An unexpected error occurred: {}".format(str(e)))
def print_example_config(output_file):
example_config = """
[UserVariables]
api_key = your_api_key_here
m3u_url = your_m3u_url_here
output_file = /path/to/example.m3u
[Logging]
log_to_file = True
log_file = VODimage.log
log_level = INFO
"""
print("VODimage.conf has been created in this directory. Please open it and modify the variables.")
print("Example Configuration File:")
print(example_config)
# Save the example configuration to a file
with open(output_file, 'w') as config_file:
config_file.write(example_config)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Process VODs and generate M3U file')
parser.add_argument('--config', default='VODimage.conf', help='Config file (default: VODimage.conf)')
parser.add_argument('--api_key', help='TMDB API key')
parser.add_argument('--m3u_url', help='M3U playlist URL')
parser.add_argument('--output_file', help='Output M3U file')
parser.add_argument('--setup', action='store_true', help='Print example configuration and save as VODimage.conf')
args = parser.parse_args()
if args.setup:
# Specify the filename for the example config file
example_config_file = 'VODimage.conf'
print_example_config(example_config_file)
exit(0)
# Load user configuration
config = configparser.ConfigParser()
config.read(args.config)
# Configure logging
configure_logging()
# Initialize variables
api_key = args.api_key or config.get('UserVariables', 'api_key', fallback=None)
m3u_url = args.m3u_url or config.get('UserVariables', 'm3u_url', fallback=None)
output_file = args.output_file or config.get('UserVariables', 'output_file', fallback=None)
# Check if any required arguments are missing
if not api_key or not m3u_url or not output_file:
logging.error("Missing required arguments. Provide either through command-line or in the config file.")
exit(1)
# User-defined variables
TMDb.api_key = api_key
M3Uurl = m3u_url
file = output_file
# Check if file exists and remove if it does
if os.path.exists(file):
os.remove(file)
# Open file and write #EXTM3U on the first line and close it
with open(file, "w+") as file2:
file2.write("#EXTM3U" + '\n')
# Load playlist and leverage m3u-ipytv, sort if Movie or TV VOD
pl = playlist.loadu(M3Uurl)
# Count the VODs
total_vods = sum(1 for _ in pl)
log_info("Total VODs to process: {}".format(total_vods))
# Process each VOD
for i, vod in enumerate(pl):
log_info("Processing VOD {} of {}".format(i + 1, total_vods))
process_vod(vod, file)
log_info("") # Add a blank line in the log after each VOD processed to aid readability
log_info("Processing completed.")
Total 0 Votes
0
0