VOD Image python script (Windows and Linux versions)

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

Tell us how can we improve this post?

+ = Verify Human or Spambot ?