예제 #1
0
def get_movie_imdb_id(moviedb_id: int) -> tuple:
    """
    Retrieve a movie's IMDB ID given it's MovieDB ID.
    :param int moviedb_id: The movie's MovieDB ID
    :return tuple: True = Success or False = Fail, The movie's IMDB ID or status message
    """
    base_url = 'https://api.themoviedb.org/3/movie/'
    api_key = '?api_key=' + get_api_key()
    language = '&language=en-US'

    url = base_url + str(moviedb_id) + api_key + language

    response = moviedb_api_call(url)
    if response[0] is False:
        return response
    else:
        response_str = response[1]

    # print(response_str)

    # response_str = response_str.replace('\\\'', "'")
    # DEBUG
    # Logger.log_message(1, response_str)

    pattern = re.compile('"imdb_id":\s*"(tt\d{7})"')
    match = pattern.search(response_str)

    if match:
        return True, match.group(1)
    else:
        # MovieDB response does not match RegEx pattern. No IMDB ID.
        logger.log_message(
            1,
            'MovieDB response does not match RegEx pattern. No imdb_id found.')
        return False, 'WARNING: No IMDB found! '
예제 #2
0
def update_movie(movie: LibraryDBMovie) -> tuple:
    """
    Update movie object in LibraryDB.
    :param LibraryDB_Movie movie: LibraryDB_Movie to be updated in LibraryDB
    :return tuple: Status code. True = Success or False = Error, string description of status
    """
    conn = sqlite3.connect(globals.LIBRARYDB_PATH)
    try:
        c = conn.cursor()
        # UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];
        c.execute(
            'UPDATE Titles SET name = ?, movie_db_id = ?, imdb_id = ?, genres = ?, description = ?, release_date = ?, '
            + 'format = ?, posterUrl = ? WHERE title_id = ?',
            (movie.title, movie.movie_db_id, movie.imdb_id, movie.genre_ids,
             movie.description, movie.release_date, movie.title_format, movie.poster_url, movie.title_id))

        conn.commit()
        conn.close()
    except Exception as err:
        conn.commit()
        conn.close()
        logger.log_message(0, str(err))
        return False, "UPDATE ERROR: Check logs for details! "

    return True, 'Successful LibraryDB Update!'
예제 #3
0
 def process_input(entry: str) -> tuple:
     """
     Handle all option and special option actions.
     :param str entry: User's input
     :return tuple: True = Success or False = Fail, next menu or status message
     """
     if entry.upper() == 'B':
         menu_manager.back()
         return False, ''
     elif entry.upper() == 'Q':
         # Quit
         quit()
     if len(entry) < 4:
         # Entry is too short or too long, redisplay prompt
         logger.log_message(
             1, 'User entered less than four characters! ' + entry)
         return False, 'WARNING: Input was less than 4 characters! '
     else:
         # Input is good, query MovieDB
         response = moviedb.query(entry)
         if response[0]:
             if len(response[1]) == 0:
                 # logger.log_message(1, 'No movie found!')
                 return False, 'WARNING: No movie found! '
             else:
                 # Movies found, open Movie_Select
                 next_menu = MovieSelect(response[1], 'I')
                 return True, next_menu
         else:
             return response
예제 #4
0
 def process_input(entry: str) -> tuple:
     """
     Handle all option and special option actions.
     :param str entry: User's input
     :return tuple: False (to drop back into the Menu Manager loop), status message or next menu
     """
     if entry.upper() == 'B':
         menu_manager.back()
         return False, ''
     elif entry.upper() == 'Q':
         # Quit
         quit()
     # Check if entry is in the form of IMDB ID
     # tt9999999
     if len(entry) != 9:
         # Entry is too short or too long, redisplay prompt
         logger.log_message(
             1, 'Entry is ' + str(len(entry)) +
             ' characters long. Entry: ' + entry)
         return False, 'WARNING: Input should be 9 characters! '
     else:
         pattern = re.compile('tt\d{7}')
         match = pattern.search(entry)
         # logger.log_message(1, 'Looking for regex match...')
         if match:
             # Matches IMDB ID form, query MovieDB
             # logger.log_message(1, 'Searching MovieDB...')
             response = _query_moviedb(entry)
             if response[0] is False:
                 return response
             else:
                 # logger.log_message(1, 'Proper IMDB ID entered, opening Format_Select.')
                 format_menu = FormatSelect(response[1])
                 while True:
                     response = format_menu.menu_logic()
                     if response[0]:
                         # If selection is in options/special_options, process input
                         response = format_menu.process_input(response[1])
                         if response[0]:
                             # If format was successfully selected, return LibraryDB_Movie object
                             return True, MovieParams(response[1], 'I')
                         else:
                             # Format not successfully selected, back to format select menu
                             format_menu.val_input = False
                             format_menu.inval_prompt = response[1]
                             continue
                     else:
                         # Format not successfully selected, back to format select menu
                         format_menu.val_input = False
                         format_menu.inval_prompt = response[1]
                         continue
         else:
             # Entry is not IMDB ID, redisplay prompt
             logger.log_message(1, 'NOT AN IMDB ID! ' + entry)
             return False, 'NOT AN IMDB ID! '
예제 #5
0
    def __init__(self, movie: LibraryDBMovie, mode: str):
        """
        Create MovieParams menu object.
        :param LibraryDBMovie movie: Movie that needs edited.
        :param str mode: I or U, whether the movie is to be inserted or updated in LibraryDB
        """
        prompt = 'Selection: '
        self.mode = mode
        # Create a string of all the genre names of this movie
        genre_names = ' ('
        written = False
        for genre_num in movie.genre_ids.split(','):
            movie_genre = moviedb_genre.GENRE_DICT[genre_num]
            if movie_genre is Exception:
                logger.log_message(0, movie_genre)
            else:
                genre_names += movie_genre + ", "
                written = True
        if written:
            genre_names = genre_names[:-2]
        genre_names += ')'

        format_name = ' (' + librarydb_format.FORMAT_DICT[str(movie.title_format)] + ')'
        status_name = ' (' + librarydb_status.STATUS_DICT[str(movie.title_status)] + ')'

        options = {
            '1': 'Title: ' + movie.title,
            '2': 'MovieDB ID: ' + str(movie.movie_db_id),
            '3': 'Format: ' + str(movie.title_format) + format_name,
            '4': 'IMDB ID: ' + movie.imdb_id,
            '5': 'Genres: ' + movie.genre_ids + genre_names,
            '6': 'Description: ' + movie.description,
            '7': 'Release Date: ' + movie.release_date,
            '8': 'Poster URL: ' + movie.poster_url,
            '9': 'Status: ' + str(movie.title_status) + status_name
        }
        if mode == 'I':
            special_options = {
                'I': 'Insert into LibraryDB',
                'B': 'Back',
                'Q': 'Exit'
            }
        elif mode == 'U':
            special_options = {
                'U': 'Update LibraryDB Movie',
                'B': 'Back',
                'Q': 'Exit'
            }
        else:
            special_options = {
                'B': 'Back',
                'Q': 'Exit'
            }
        super().__init__(globals.VERSION + ' - ' + self.TITLE, prompt, options, special_options)
        self.movie = movie
예제 #6
0
def moviedb_api_call(url: str) -> tuple:
    """
    Make MovieDB API call and return the server response.
    :param url: API call URL
    :return tuple: True = Success or False = Fail, server response or status message
    """
    tries = 0
    while True:
        try:
            response = urllib.request.urlopen(url)
            response_str = str(response.read())
            break
        except HTTPError as err:
            logger.log_message(0, str(err))
            tries += 1
            if tries <= 5:
                logger.log_message(1, 'Retrying...(' + tries + ')')
            else:
                logger.log_message(0, 'Exceeded retry count. Try again later')
                return False, 'ERROR: Request to MovieDB timed out! '
        except URLError as err:
            logger.log_message(0, str(err))
            return False, 'ERROR: URLError, see logs! '

    response_str = response_str.replace("\\\'", "'")
    response_str = response_str.replace("\\\\/", "")
    return True, response_str
예제 #7
0
파일: basetabs.py 프로젝트: Perdu/poezio
 def log_message(self, txt, nickname, time=None, typ=1):
     """
     Log the messages in the archives.
     """
     name = safeJID(self.name).bare
     if not logger.log_message(name, nickname, txt, date=time, typ=typ):
         self.core.information(_('Unable to write in the log file'), 'Error')
예제 #8
0
 def log_message(self, txt, nickname, time=None, typ=1):
     """
     Log the messages in the archives.
     """
     name = safeJID(self.name).bare
     if not logger.log_message(name, nickname, txt, date=time, typ=typ):
         self.core.information('Unable to write in the log file', 'Error')
예제 #9
0
def query_by_imdb_id(imdb_id: str) -> tuple:
    """
    Query MovieDB API using an IMDB ID.
    :param str imdb_id: IMDB ID in the form ttNNNNNNN
    :return tuple: True = Success or False = Fail, MovieDB_Movie object or status message
    """
    base_url = 'https://api.themoviedb.org/3'
    api_key = 'api_key=' + get_api_key()

    find_by_imdb_id = '/find/'
    find_by_imdb_id2 = '?external_source=imdb_id&'

    url = base_url + find_by_imdb_id + imdb_id + find_by_imdb_id2 + api_key

    response = moviedb_api_call(url)
    if response[0] is False:
        return response
    else:
        response_str = response[1]

    # response_str = response_str.replace('\\\'', "'")
    # DEBUG
    # Logger.log_message(1, response_str)

    pattern = re.compile('"genre_ids":\[([\d,]+)\]' + '[\s\S]*' +
                         '"id":([\d]+?),' + '[\s\S]*' +
                         '"original_title":"([\s\S]+?)",' + '[\s\S]*' +
                         '"overview":"([\s\S]+?)",' + '[\s\S]*' +
                         '"release_date":"([\s\S]+?)",' + '[\s\S]*' +
                         '"poster_path":"/([\s\S]+?)"')
    match = pattern.search(response_str)

    if match:
        movie = MovieDBMovie(
            match.group(3), int(match.group(2)), match.group(4),
            match.group(5),
            'http://image.tmdb.org/t/p/original/' + match.group(6),
            match.group(1), imdb_id)
        return True, movie
    else:
        # MovieDB response does not match RegEx pattern. Incorrect imdb_id.
        logger.log_message(
            1,
            'MovieDB response does not match RegEx pattern. Incorrect imdb_id.'
        )
        return False, 'WARNING: Movie not found! '
예제 #10
0
    def __str__(self) -> str:
        """
        Convert LibraryDB_Movie object into a string.
        :return str: String representation of the LibraryDB_Movie object
        """
        str_rep = ''

        # Title
        str_rep += self.title

        # Release date
        if self.release_date is not None and self.release_date != '':
            str_rep += ' (' + self.release_date + ')'

        # Format
        try:
            format_name = librarydb_format.FORMAT_DICT[str(self.title_format)]
            str_rep += ' - ' + format_name
        except KeyError as err:
            logger.log_message(0, str(err))

        # Status
        try:
            status_name = librarydb_status.STATUS_DICT[str(self.title_status)]
            str_rep += '\nStatus: ' + status_name
        except KeyError as err:
            logger.log_message(0, str(err))

        # Genres
        if self.genre_ids is not None and self.genre_ids != '':
            str_rep += '\n'
            written = False
            for genre_num in self.genre_ids.split(','):
                movie_genre = moviedb_genre.GENRE_DICT[genre_num]
                if movie_genre is Exception:
                    logger.log_message(0, movie_genre)
                else:
                    str_rep += movie_genre + ", "
                    written = True
            if written:
                str_rep = str_rep[:-2]

        # IMDB ID
        if self.imdb_id is not None and self.imdb_id != '':
            str_rep += '\nIMDB: ' + self.imdb_id + '\t'
            # MovieDB ID
            str_rep += 'MovieDB: ' + str(self.movie_db_id)
        else:
            str_rep += '\nMovieDB: ' + str(self.movie_db_id)

        # Poster URL
        if self.poster_url is not None and self.poster_url != '':
            str_rep += '\nPoster: ' + self.poster_url

        # Description
        if self.description is not None and self.description != '':
            str_rep += '\n' + self.description

        return str_rep
예제 #11
0
def search_by_title(entry: str) -> tuple:
    """
    Query LibraryDB's movie titles for the search term.
    :param str entry: Search term
    :return tuple: True = Success or False = Error, List of LibraryDB movies
    """
    try:
        conn = sqlite3.connect(globals.LIBRARYDB_PATH)
        c = conn.cursor()

        t = ('%' + entry + '%',)
        c.execute('SELECT * FROM Titles WHERE name LIKE ?', t)

        movies = []
        while True:
            result = c.fetchone()
            if result is None:
                break
            else:
                movie = LibraryDBMovie(result[1],  # title
                                       result[2],  # movie_db_id
                                       result[7],  # title_format
                                       result[9],  # title_status
                                       result[3],  # imdb_id
                                       result[4],  # genre_ids
                                       result[5],  # description
                                       result[6],  # release_date
                                       result[8],  # poster_url
                                       result[0])  # title_id
                movies.append(movie)

        conn.commit()
        conn.close()
    except Exception as err:
        logger.log_message(0, str(err))
        return False, 'ERROR: Check logs. '

    return True, movies
예제 #12
0
def insert_movie(movie: LibraryDBMovie) -> tuple:
    """
    Insert movie object into LibraryDB.
    :param LibraryDB_Movie movie: LibraryDB_Movie to be inserted into LibraryDB
    :return tuple: Status code. True = Success or False = Error, string description of status
    """
    conn = sqlite3.connect(globals.LIBRARYDB_PATH)
    try:
        c = conn.cursor()
        c.execute(
            'INSERT INTO Titles (name, movie_db_id, imdb_id, genres, description, release_date, format, posterUrl) '
            + 'VALUES (?,?,?,?,?,?,?,?)',
            (movie.title, movie.movie_db_id, movie.imdb_id, movie.genre_ids,
             movie.description, movie.release_date, movie.title_format, movie.poster_url))

        conn.commit()
        conn.close()
    except Exception as err:
        conn.commit()
        conn.close()
        logger.log_message(0, str(err))
        return False, "INSERT ERROR: Check logs for details! "

    return True, 'Successful LibraryDB Insert!'
예제 #13
0
    def process_input(self, entry: str) -> tuple:
        """
        Handle all option and special option actions.
        :param str entry: User's input
        :return tuple: True = Success or False = Fail, new value of parameter or status message
        """
        if entry.upper() == 'B':
            return False, ''
        elif entry.upper() == 'Q':
            quit()
        # Check input validity
        # Check if key is in menu
        if self._param_name == 'format' or self._param_name == 'movie_db_id':
            try:
                entry = int(entry)
            except Exception as err:
                logger.log_message(0, str(err))
                self.val_input = False
                return False, self._param_name + ' is not int! '

            if self._param_name == 'format':
                try:
                    librarydb_format.FORMAT_DICT[str(entry)]
                except KeyError:
                    logger.log_message(0, 'Format not valid! ' + str(entry))
                    self.val_input = False
                    return False, 'Format entered is not valid! '
                # Add to movie object
                return True, str(entry)

            elif self._param_name == 'movie_db_id':
                # No special criteria, add to movie object
                return True, entry
        elif self._param_name == 'imdb_id' or self._param_name == 'genres' or self._param_name == 'release_date' \
                or self._param_name == 'posterUrl' or self._param_name == 'name' or self._param_name == 'description':
            # String format
            if self._param_name == 'imdb_id':
                # Match IMDB ID in the form of 'tt9999999'
                p = re.compile('^tt\d{7}$')
                match = p.search(entry)
                if match:
                    # Good input
                    return True, entry
                else:
                    self.val_input = False
                    return False, 'Invalid IMDB ID! '
            elif self._param_name == 'genres':
                print('genre regex check.')
                # Match genres in comma-separated list, without trailing comma
                p = re.compile('^(\d+)(,(\d+))*$')
                match = p.search(entry)
                if match:
                    print('checking genres entered')
                    for genre_num in entry.split(','):
                        try:
                            moviedb_genre.GENRE_DICT[genre_num]
                        except KeyError:
                            logger.log_message(0, str(genre_num) + ' is not a valid genre number!')
                            self.val_input = False
                            return False, str(genre_num) + ' is not a valid genre number! '
                    # Good input
                    print('Good to go!')
                    return True, entry
                else:
                    self.val_input = False
                    return False, 'Improper Genre string! '
            elif self._param_name == 'release_date':
                # Match date YYYY-MM-DD
                p = re.compile('^(19|20)\d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])$')
                match = p.search(entry)
                if match:
                    # Good input
                    return True, entry
                else:
                    self.val_input = False
                    return False, 'Improper release date format! '
            elif self._param_name == 'posterUrl':
                # Match poster url
                p = re.compile('^(http|https)://image.tmdb.org/t/p/original/[\d\w]+.(jpg|png)$')
                match = p.search(entry)
                if match:
                    # Good input
                    return True, entry
                else:
                    self.val_input = False
                    return False, 'Improper poster url format! '
            elif self._param_name == 'name':
                # No special criteria, add to movie object
                return True, entry
            elif self._param_name == 'description':
                # No special criteria, add to movie object
                return True, entry
        else:
            # param_name not properly set
            logger.log_message(0, 'param_name not properly set! ' + self._param_name)
            self.val_input = False
            return False, 'param_name not properly set! See logs. '
예제 #14
0
 def update_movie(self, param_num: str, new_param_val: Union[str, int]) -> None:
     """
     Update LibraryDB_Movie parameter.
     :param str param_num: Number of parameter to be updated
     :param Union[str, int] new_param_val: New value of the parameter
     :return None: Nothing
     """
     if param_num == 0:
         # parameter wasn't properly updated.
         pass
     if param_num == '1':
         # Param_Edit title
         self.movie.title = new_param_val
         self._options[param_num] = 'Title: ' + new_param_val
     elif param_num == '2':
         # Param_Edit movie_db_id
         self.movie.movie_db_id = new_param_val
         self._options[param_num] = 'MovieDB ID: ' + new_param_val
     elif param_num == '3':
         # Param_Edit format
         self.movie.title_format = new_param_val
         format_name = ' (' + librarydb_format.FORMAT_DICT[new_param_val] + ')'
         self._options[param_num] = 'Format: ' + new_param_val + format_name
     elif param_num == '4':
         # Param_Edit imdb_id
         self.movie.imdb_id = new_param_val
         self._options[param_num] = 'IMDB ID: ' + new_param_val
     elif param_num == '5':
         # Param_Edit genres
         self.movie.genre_ids = new_param_val
         # Create a string of all the genre names of this movie
         genre_names = ' ('
         written = False
         for genre_num in new_param_val.split(','):
             movie_genre = moviedb_genre.GENRE_DICT[genre_num]
             if movie_genre is Exception:
                 logger.log_message(0, movie_genre)
             else:
                 genre_names += movie_genre + ', '
                 written = True
         if written:
             genre_names = genre_names[:-2]
         genre_names += ')'
         self._options[param_num] = 'Genres: ' + new_param_val + genre_names
     elif param_num == '6':
         # Param_Edit description
         self.movie.description = new_param_val
         self._options[param_num] = 'Description: ' + new_param_val
     elif param_num == '7':
         # Param_Edit release_data
         self.movie.release_date = new_param_val
         self._options[param_num] = 'Release Date: ' + new_param_val
     elif param_num == '8':
         # Param_Edit posterUrl
         self.movie.poster_url = new_param_val
         self._options[param_num] = 'Poster URL: ' + new_param_val
     else:
         logger.log_message(0, 'Param num not set in Movie_Params.update_movie()')
         status_message = StatusMessage('An Error Occurred', 'Press [Enter] to exit...',
                                        'An error occurred in Movie_Params.update_movie(). See logs for details.')
         status_message.menu_logic()
         exit(1)