Example #1
0
    def parse_filename(self, filepath):
        ''' Uses PTN to get as much info as possible from path
        filepath (str): absolute path to movie file

        Parses parent directory name first, then file name if folder name seems incomplete.

        Returns dict of metadata
        '''

        dirname = os.path.split(filepath)[0].split(os.sep)[-1]

        logging.info(
            'Parsing directory name for movie information: {}.'.format(
                dirname))

        meta_data = PTN.parse(dirname)
        for i in ('excess', 'episode', 'episodeName', 'season', 'garbage',
                  'website'):
            meta_data.pop(i, None)

        if len(meta_data) > 3:
            meta_data["release_name"] = dirname
            logging.info('Found {} in filename.'.format(meta_data))
        else:
            logging.debug(
                'Parsing directory name does not look accurate. Parsing file name.'
            )
            filename = os.path.basename(filepath)
            meta_data = PTN.parse(filename)
            logging.info('Found {} in file name.'.format(meta_data))
            if len(meta_data) < 2:
                logging.warning(
                    'Little information found in file name. Movie may be incomplete.'
                )
            meta_data['release_title'] = filename

        title = meta_data.get('title')
        if title and title[-1] == '.':
            meta_data['title'] = title[:-1]

        # Make sure this matches our key names
        if 'year' in meta_data:
            meta_data['year'] = str(meta_data['year'])
        meta_data['videocodec'] = meta_data.pop('codec', None)
        meta_data['audiocodec'] = meta_data.pop('audio', None)

        if meta_data.get('edition'):
            meta_data['edition'] = ' '.join(meta_data['edition'].sort())

        qual = meta_data.pop('quality', '')
        for source, aliases in core.CONFIG['Quality']['Aliases'].items():
            if any(a.lower() == qual.lower() for a in aliases):
                meta_data['source'] = source
                break
        meta_data['source'] = meta_data.get('source', None)

        meta_data['releasegroup'] = meta_data.pop('group', None)

        return meta_data
    def parse_filename(self, data):
        ''' Parses filename for release information
        :param data: dict movie info

        PTN only returns information it finds, so we start with a blank dict
            of keys that we NEED to have, then update it with PTN's data. This
            way when we rename the file it will insert a blank string instead of
            throwing a missing key exception.

        Might eventually replace this with Hachoir-metadata

        Returns dict of parsed data
        '''

        filename = data['filename']
        path = data['path']

        # This is our base dict. Contains all neccesary keys, though they can all be empty if not found.
        metadata = {
            'title': '',
            'year': '',
            'resolution': '',
            'releasegroup': '',
            'audiocodec': '',
            'videocodec': '',
            'source': '',
            'imdbid': ''
        }

        titledata = PTN.parse(os.path.basename(filename))
        # this key is useless
        if 'excess' in titledata:
            titledata.pop('excess')

        if len(titledata) <= 2:
            logging.info(
                u'Parsing filename doesn\'t look accurate. Parsing parent folder name.'
            )
            path_list = path.split(os.sep)
            titledata = PTN.parse(path_list[-1])
            logging.info(u'Found {} in parent folder.'.format(titledata))
        else:
            logging.info(u'Found {} in filname.'.format(titledata))

        # Make sure this matches our key names
        if 'codec' in titledata:
            titledata['videocodec'] = titledata.pop('codec')
        if 'audio' in titledata:
            titledata['audiocodec'] = titledata.pop('audio')
        if 'quality' in titledata:
            titledata['source'] = titledata.pop('quality')
        if 'group' in titledata:
            titledata['releasegroup'] = titledata.pop('group')
        metadata.update(titledata)

        return metadata
Example #3
0
def analyze(input, name, season='', episode='', resolution='', quality=''):

    matches = []
    data = []

    # If for some reason there is not magnet or torrent link but result is shown remove it.
    for torrent in input:
        if torrent.has_key('Magnet') or torrent.has_key('Torrent'):
            data.append(torrent)

    for torrent in data:
        # Has key is used to check if PTN can extract certain info from filename for filtering results.
        # (PTN creates a dict with found parameters as keys).

        key1 = PTN.parse(torrent['Episode Name']).has_key('season')
        key2 = PTN.parse(torrent['Episode Name']).has_key('episode')
        key3 = PTN.parse(torrent['Episode Name']).has_key('resolution')
        key4 = PTN.parse(torrent['Episode Name']).has_key('quality')

        # f-i checks if value for parameter is entered (the only that can't be blank is show title).
        f = season != ''
        g = episode != ''
        h = resolution != ''
        i = quality != ''
        a = PTN.parse(torrent['Episode Name'])['title'].lower() != name.lower()

        # Checks if a value for parameter is entered and matches PTN result (if data is available).
        b = True
        c = True
        d = True
        e = True
        if key1:
            b = PTN.parse(torrent['Episode Name'])['season'] != season

        if key2:
            c = PTN.parse(torrent['Episode Name'])['episode'] != episode

        if key3:
            d = PTN.parse(torrent['Episode Name'])['resolution'].lower(
            ) != resolution.lower()

        if key4:
            e = PTN.parse(
                torrent['Episode Name'])['quality'].lower() != quality.lower()

        n1 = (not key1) and f
        n2 = (not key2) and g
        n3 = (not key3) and h
        n4 = (not key4) and i

        # If parameter exists and required add torrent to matches.
        if not (a or (b and f) or (c and g) or (d and h) or (e and i)):
            matches.append(torrent)

# If parameter required but does not exist remove the value from matches (this required because of the way PTN works).
        if (n1 or n2 or n3 or n4) and matches != []:
            matches.remove(torrent)

    return matches
Example #4
0
    def parse_filename(self, filepath):
        ''' Uses PTN to get as much info as possible from path
        filepath (str): absolute path to file

        Returns dict of metadata
        '''
        logging.info(
            'Parsing filename for movie information: {}.'.format(filepath))

        titledata = PTN.parse(os.path.basename(filepath))
        # remove usless keys before measuring length
        for i in ('excess', 'episode', 'episodeName', 'season', 'garbage',
                  'website'):
            titledata.pop(i, None)

        if len(titledata) < 3:
            logging.debug(
                'Parsing filename does not look accurate. Parsing parent folder name.'
            )

            fname = os.path.split(filepath)[0].split(os.sep)[-1]
            titledata = PTN.parse(fname)
            titledata['release_title'] = fname
            logging.info('Found {} in parent folder.'.format(titledata))
            if len(titledata) < 2:
                logging.warning(
                    'Little information found in parent folder name. Movie may be incomplete.'
                )
        else:
            titledata['release_name'] = os.path.basename(filepath)
            logging.info('Found {} in filename.'.format(titledata))

        title = titledata.get('title')
        if title and title[-1] == '.':
            titledata['title'] = title[:-1]

        # Make sure this matches our key names
        if 'year' in titledata:
            titledata['year'] = str(titledata['year'])
        titledata['videocodec'] = titledata.pop('codec', None)
        titledata['audiocodec'] = titledata.pop('audio', None)

        qual = titledata.pop('quality', None)
        for source, aliases in core.CONFIG['Quality']['Aliases'].items():
            if any(a.lower() == qual.lower() for a in aliases):
                titledata['source'] = source
                break
        titledata['source'] = titledata.get('source', None)

        titledata['releasegroup'] = titledata.pop('group', None)

        return titledata
Example #5
0
    def parse_filename(self, filepath):
        ''' Uses PTN to get as much info as possible from path
        filepath: str absolute path to file

        Returns dict of Metadata
        '''
        logging.info(u'Parsing {} for movie information.'.format(filepath))

        # This is our base dict. Contains all neccesary keys, though they can all be empty if not found.
        metadata = {
            'title': '',
            'year': '',
            'resolution': '',
            'releasegroup': '',
            'audiocodec': '',
            'videocodec': '',
            'source': '',
            'imdbid': ''
        }

        titledata = PTN.parse(os.path.basename(filepath))
        # this key is useless
        if 'excess' in titledata:
            titledata.pop('excess')

        if len(titledata) < 2:
            logging.info(
                u'Parsing filename doesn\'t look accurate. Parsing parent folder name.'
            )

            path_list = os.path.split(filepath)[0].split(os.sep)
            titledata = PTN.parse(path_list[-1])
            logging.info(u'Found {} in parent folder.'.format(titledata))
        else:
            logging.info(u'Found {} in filename.'.format(titledata))

        title = titledata.get('title')
        if title and title[-1] == '.':
            titledata['title'] = title[:-1]

        # Make sure this matches our key names
        if 'codec' in titledata:
            titledata['videocodec'] = titledata.pop('codec')
        if 'audio' in titledata:
            titledata['audiocodec'] = titledata.pop('audio')
        if 'quality' in titledata:
            titledata['source'] = titledata.pop('quality')
        if 'group' in titledata:
            titledata['releasegroup'] = titledata.pop('group')
        metadata.update(titledata)

        return metadata
Example #6
0
def parse_media_info(name):
    parsed = PTN.parse(name)

    if parsed.get('episode'):
        return parsed

    # additional processing required

    seasonsmatch = re.search(
        "(.*)[ .]([sS][0-9]{1,2}-[sS][0-9]{1,2}|COMPLETE)", name)

    if seasonsmatch:
        parsed['title'] = seasonsmatch.group(1).replace('.', ' ')
        parsed['seasons'] = seasonsmatch.group(2)
        return parsed

    seasonmatch = re.search("(.*)[ .][sS]([0-9]{1,2})", name)

    if seasonmatch:
        parsed['title'] = seasonmatch.group(1).replace('.', ' ')
        parsed['season'] = int(seasonmatch.group(2))
        return parsed

    if parsed.get('year'):
        # more likely a movie if not an episode
        moviematch = re.match("(.*)([1-2]{1}[0-9]{3})[ .]", name)
        if moviematch:
            parsed['title'] = moviematch.group(1).replace('.', ' ').strip()

    return parsed
Example #7
0
    def analyze_file(self, file):
        file_type = file.get('type')
        if file_type == 'video':
            title = file['title']
            parsed = PTN.parse(title)

            parsed_title = parsed.get('title')
            parsed_year = parsed.get('year')
            parsed_season = parsed.get('season')
            parsed_episode = parsed.get('episode')

            if parsed_season and parsed_episode:
                file['search_type'] = 'tv'
                file['parsed_title'] = parsed_title
                file['parsed_year'] = parsed_year
                file['parsed_season'] = parsed_season
                file['parsed_episode'] = parsed_episode

            elif parsed_title is not None and parsed_year:
                file['search_type'] = 'movie'
                file['parsed_title'] = parsed_title
                file['parsed_year'] = parsed_year
            else:
                file['search_type'] = 'skip'
        else:
            file['search_type'] = 'skip'
        return file
Example #8
0
def fuzzy_title(releases, titles, year='\n'):
    ''' Score and remove releases based on title match
    releases (list[dict]): scene release metadata to score and filter
    titles (list): titles to match against
    year (str): year of movie release           <optional -default '\n'>

    If titles is an empty list every result is treated as a perfect match
    Matches releases based on release_title.split(year)[0]. If year is not passed,
        matches on '\n', which will include the entire string.

    Iterates through releases and removes any entry that does not
        fuzzy match 'title' > 70.
    Adds fuzzy_score / 20 points to ['score']

    Returns list[dict]
    '''

    logging.info('Checking title match.')

    reject = 0
    if titles == [] or titles == [None]:
        logging.debug(
            'No titles available to compare, scoring all as perfect match.')
        for result in releases:
            if result['reject_reason']:
                reject += 1
                continue
            result['score'] += 20
    else:
        for result in releases:
            if result['reject_reason']:
                reject += 1
                continue
            if result['type'] == 'import':
                logging.debug(
                    '{} is an Import, sorting as a perfect match.'.format(
                        result['title']))
                result['score'] += 20
                continue

            rel_title_ss = result.get('ptn',
                                      PTN.parse(result['title']))['title']

            logging.debug(
                'Comparing release substring {} with titles {}.'.format(
                    rel_title_ss, titles))
            matches = [_fuzzy_title(rel_title_ss, title) for title in titles]
            if any(match > 70 for match in matches):
                result['score'] += int(max(matches) / 5)
            else:
                logging.debug(
                    '{} best title match was {}%, removing search result.'.
                    format(result['title'], max(matches)))
                result[
                    'reject_reason'] = 'mismatch title (best match was {}%)'.format(
                        max(matches))
                reject += 1

    logging.info('Keeping {} releases.'.format(len(releases) - reject))
    return releases
Example #9
0
def update_available_eps(url, show_id):
    db, cursor = get_db()
    #print(url)

    ep = requests.get('%s%s' % (config.get("eztv", "host"), url))
    eps = BeautifulSoup(ep.text, "lxml")

    for episode in eps.find_all('tr'):
        ep_string = str(episode.find('a', class_="epinfo"))
        parsed_data = PTN.parse(ep_string)
        quality = parsed_data['quality'] if 'quality' in parsed_data else 'Unknown'
        resolution = parsed_data['resolution'] if 'resolution' in parsed_data else 'Unknown'

        info = re.findall(episode_info_regex, ep_string)
        if len(info) > 0:
            season = info[0][1]
            number = info[0][2]
        else:
            continue

        ep_id = re.findall(episode_id_regex, ep_string)
        if len(ep_id) > 0:
            episode_id = ep_id[0]

        
        magnet = episode.find('a', class_="magnet")
        if magnet is not None:
            magnet = magnet['href']
            cursor.execute("INSERT INTO episodes (`show_id`, `episode_id`, `number`, `season`, `magnet`, `downloaded`, `quality`, `resolution`) VALUES (%s, %s, %s, %s, %s, 0, %s, %s) ON DUPLICATE KEY UPDATE magnet = %s, quality = %s, resolution = %s", (show_id, episode_id, number, season, magnet, quality, resolution, magnet, quality, resolution, ))
            
    db.commit()
Example #10
0
def store_show(info):

    shows = []
    show = PTN.parse(info)
    shows.append(show)

    #Checking for shows in memory, if no shows found add new list with one new show.
    try:
        file = open('myshows.txt', 'rb')
    except IOError:
        file = open('myshows.txt', 'wb')

    try:
        file = open('myshows.txt', 'rb')
        storedshows = pickle.load(file)
    except EOFError:
        file = open('myshows.txt', 'wb')
        pickle.dump(shows, file)
        storedshows = shows

    # Checking if show exists in memory, if not add.
    if not any(value['title'] == show['title'] for value in storedshows):
        file = open('myshows.txt', 'rb')
        shows = pickle.load(file)
        shows.append(show)
        file = open('myshows.txt', 'wb')
        pickle.dump(shows, file)

    # Return the list of shows.
    file = open('myshows.txt', 'rb')
    return pickle.load(file)
    file.close()
Example #11
0
def score_year(releases, year):
    ''' Increase score for each group of 'words' match
    releases (list[dict]): scene release metadata to score and filter
    year (int): expected year

    Iterates through releases and adds 20 points to every
        entry with exact year match
    Keeps releases without year or 1 year higher or lower.

    Returns list[dict]
    '''

    logging.info('Checking year match.')

    reject = 0

    for r in releases:
        if r['reject_reason']:
            reject += 1
            continue
        if 'ptn' not in r:
            r['ptn'] = PTN.parse(r['title'])
        if 'year' in r['ptn']:
            if r['ptn']['year'] == year:
                r['score'] += 20
            if abs(year - r['ptn']['year']) > 1:
                reject += 1
                r['reject_reason'] = 'Year mismatch'

    return releases
def handle_comic_file(comic_file):
    print('Handling comic file', comic_file)
    superdir = os.path.dirname(comic_file)
    name, ext = os.path.splitext(os.path.basename(comic_file))
    comic_parse = PTN.parse(name)
    print(comic_parse)
    # The parser matches comic book title and issue number both into 'title' key.
    # Compile the regex that matches for comic issue numbers.
    issue_regex = re.compile('(\d{1,3}(\.\d*)*\s*$)')
    # Split the title by regex matching.
    title_split = issue_regex.split(comic_parse['title'])
    # Strip trailing spaces from the title.
    title = title_split[0].strip()
    # If the split found a match and actually split, make the second half the issue number.
    if len(title_split) >= 2:
        issue = ' ' + title_split[1].strip()
    else:
        issue = ''
    # A Free Comic Book Day issue has no issue number, so it replaces the issue number value.
    if 'fcbd' in comic_parse:
        if comic_parse['fcbd']:
            issue = ' FCBD'
    if 'year' in comic_parse:
        year = ' (' + str(comic_parse['year']) + ')'
    else:
        year = ''
    # Construct the renamed filename.
    rename = title + issue + year
    comic_file_renamed = os.path.join(superdir, rename+ext)
    print('Renaming', comic_file, '->', comic_file_renamed)
    shutil.move(comic_file, comic_file_renamed)
    move_or_overwrite(comic_file_renamed, dest_comic, os.path.join(dest_comic, rename+ext))
 def __init__(self, fullpath, fullname):
     self.fileName = fullname
     self.movieName = os.path.splitext(fullname)[
         0]  #Remove extension from name
     self.filePath = fullpath
     self.seriesType = False
     parsedFile = PTN.parse(self.movieName)
     self.parsedGroup, self.parsedSeason, self.parsedEpisode, self.parsedYear = "", "", "", ""
     parsedMovieName = parsedFile['title']
     print(self.fileName)
     match = input(parsedMovieName + '?')
     if match != "":
         parsedMovieName = match
     if 'group' in parsedFile:
         self.parsedGroup = parsedFile['group'].replace("[", "").replace(
             "]", "")  #Remove [] from YTS.AM
     if 'season' in parsedFile:
         self.seriesType = True
         self.parsedSeason = str(parsedFile['season']).rjust(2, '0')
         self.parsedEpisode = str(parsedFile['episode']).rjust(2, '0')
     if 'year' in parsedFile:
         self.parsedYear = parsedFile['year']
     self.findSub = parsedMovieName
     if self.parsedYear != "":
         self.findSub = self.findSub + ' ' + str(self.parsedYear)
     return
Example #14
0
    def __init__(self, name):
        ptn_dict = PTN.parse(name)
        key_list = [
            "resolution",
            "codec",
            "season",
            "episode",
            "bitDepth",
            "audio",
            "quality",
            "encoder",
            "title",
            "year",
            "remux",
        ]

        for key in key_list:
            setattr(self, key, ptn_dict.get(key))

        # Write REMUX instead of Blu-Ray
        self.quality = "REMUX" if self.remux else self.quality

        self.sortkeys = {
            "se": self.season,
            "ep": self.episode,
            "res": self.resolution,
            "title": self.title,
            "year": self.year,
        }
Example #15
0
def getName(name): #Returns the title of a Show or Movie

   try:
        return PTN.parse(name)['title']
       
   except KeyError:
        return "Unsorted"
Example #16
0
    def test_all_raw(self):
        json_input = os.path.join(os.path.dirname(__file__),
                                  "files/input.json")
        with open(json_input) as input_file:
            torrents = json.load(input_file)

        json_output = os.path.join(os.path.dirname(__file__),
                                   "files/output_raw.json")
        with open(json_output) as output_file:
            expected_results = json.load(output_file)

        self.assertEqual(len(torrents), len(expected_results))
        excess_elements = 0
        for torrent, expected_result in zip(torrents, expected_results):
            print("Test: {}".format(torrent.encode("utf-8", "replace")))
            result = PTN.parse(torrent, standardise=False)
            if "excess" in result:
                print("excess: {}".format(
                    str(result["excess"]).encode("utf-8", "replace")))
                if isinstance(result["excess"], list):
                    excess_elements += len(result["excess"])
                else:
                    excess_elements += 1
            for key in expected_result:
                self.assertIn(key, result, torrent.encode("utf-8", "replace"))
                self.assertEqual(expected_result[key], result[key], key)
            for key in result.keys():
                if key not in ("encoder", "excess",
                               "site"):  # Not needed in tests
                    self.assertIn(key, expected_result)
        print("Excess elements total: {}".format(excess_elements))
Example #17
0
def destination_guess(file):
    def _is_match(a, b):
        return a['season'] == b['season'] and a['episode'] == b['episode']

    def _append_moved(mlist, mdata):
        mlist.append({'season': mdata['season'], 'episode': mdata['episode']})

    metadata = PTN.parse(file.name)

    if not _is_tv_episode(metadata):
        print(f'    x Not TV: missing title, season and/or episode {metadata}')
        return None

    title = metadata['title'].title()

    moved_episodes = TV_MOVED.get(title)
    if moved_episodes is None:
        TV_MOVED[title] = []

    for entry in TV_MOVED[title]:
        if _is_match(metadata, entry):
            return None

    _append_moved(TV_MOVED[title], metadata)

    return TV_BASE.joinpath(metadata['title'].title())
Example #18
0
def scan(root, name):
	ext = [".3g2", ".3gp", ".amv", ".asf", ".asx", ".avi", ".drc", ".flv", ".f4v", ".f4p", ".f4a", ".f4b", ".mkv", ".mov", ".qt", ".mp4", ".m4p", ".m4v", ".mpg", ".mp2", ".mpeg", ".mpe", ".mpv", ".m2v", ".ogv", ".rm", ".rmvb", ".svi", ".webm", ".wmv"]
	#found = [] # array for all the files found
	cache = {} # cache for imdb json results
	info = [] # item info
	#def generate():
	#	for root, dirs, files in os.walk(path):
	#		for name in files:
	if name.endswith(tuple(ext)):
		file_location = root.split("\\") # ['E:', 'TV-Series', 'Top Gear', 'Season 1']
		foldername = ""
		if (len(file_location)-1 >= 0):
			temp = file_location[len(file_location)-1] # current folder name - either season name or title
			foldername = temp if ("season" not in temp.lower()) else file_location[len(file_location)-2]
		info = PTN.parse(name)
		# Check if title exists, if not - use folder name instead
		if (info["title"] == ""): info["title"] = foldername
		# Add item type - movie or tv-show
		info["type"] = "tv_shows" if ("episode" in info) else "movies"
		# Add file location
		#info["location"] = root
		# Remove extension from title in case it stays there
		for extension in ext: info["title"] = re.sub(extension.lower(), '', info["title"])
		# Quick-fix for movies - add empty episode and season values
		if ("episode" not in info): info["episode"] = ""
		if ("season" not in info): info["season"] = ""
		# Save to the found_on_imdb key
		info["found_on_imdb"] = imdbJSONResponse(root + "\\" + name, info["title"], info["type"], info["season"], info["episode"], cache, 5)
		# Add to the resulting list
		#found.append(info)
	#return json.dumps(found)
	result = json.dumps(info) + "\n" if info else ''
	return result
	
Example #19
0
 def solveName(self, filePath, fileName):
     parsedGroup, parsedSeason, parsedEpisode, parsedYear = "", "", "", ""
     assetFileName = os.path.splitext(fileName)[
         0]  #Remove extension from name
     assetIsSeries = False
     parsedFile = PTN.parse(assetFileName)
     parsedAssetName = parsedFile['title']
     #print (self.assetFileName)
     if 'group' in parsedFile:
         parsedGroup = parsedFile['group'].replace("[", "").replace(
             "]", "")  #Remove [] from YTS.AM
     if 'season' in parsedFile:
         assetIsSeries = True
         parsedSeason = str(parsedFile['season']).rjust(2, '0')
         parsedEpisode = str(parsedFile['episode']).rjust(2, '0')
     if 'year' in parsedFile:
         parsedYear = parsedFile['year']
     # Add imdb page tt number here
     assetAttributes = {
         "dizi": assetIsSeries,
         "isim": parsedAssetName,
         "grup": parsedGroup,
         "sezon": parsedSeason,
         "bölüm": parsedEpisode,
         "yıl": str(parsedYear),
         "dosyaisim": assetFileName,
         "dosyadizin": filePath,
         "imdbsayfa": ""
     }
     return assetAttributes  #Returns Dictionary
Example #20
0
def checklatest(show):

    title = PTN.parse(show)['title']
    # Formatting the name for TV.com -name must be accurate ("ie daredevil= marvels daredevil).
    output = ''
    fshow = title.replace(' ', '-')

    # Getting search engine (TV.com).
    resp = requests.get("http://www.tv.com/shows/" + fshow)
    soup = BeautifulSoup(
        resp.content,
        "lxml",
    )

    result = soup.find('p', {'class': 'highlight_season'}).text.strip('\n')
    data = [int(s) for s in result.split() if s.isdigit()]

    # Formatting for normal S##E##
    if data[0] < 10:
        output += 'S' + '0' + str(data[0])
    else:
        output += 'S' + str(data[0])

    if data[1] < 10:
        output += 'E' + '0' + str(data[1])
    else:
        output += 'E' + str(data[1])

    return show + ' ' + output
Example #21
0
    def test_parser(self):
        json_input = os.path.join(os.path.dirname(__file__), 'files/input.json')
        with open(json_input) as input_file:
            torrents = json.load(input_file)

        json_output = os.path.join(os.path.dirname(__file__), 'files/output.json')
        with open(json_output) as output_file:
            expected_results = json.load(output_file)

        self.assertEqual(len(torrents), len(expected_results))

        for torrent, expected_result in zip(torrents, expected_results):
            print("Test:" + torrent)
            result = PTN.parse(torrent)
            print (f"\nIn:{torrent}\nEx:{expected_result}\n\n")

            for key in expected_result:
                if not expected_result[key]:
                    self.assertNotIn(key, result)
                else:
                    self.assertIn(key, result)
                    result1 = result[key]
                    if key == 'excess' and type(result1) == list:
                        result1 = ', '.join(result1)
                    self.assertEqual(result1, expected_result[key])
Example #22
0
def file_type_is_video(filename):
    """
	function which identify if files is a video files

	if normaly we use the file extension  to know if it's a video.

	what about folder containing video files ?

	this function use  dictionnary keys of the PTN library to know if it's a video or not

	"""

    metadata = PTN.parse(filename)

    if 'codec' in metadata.keys():
        if 'resolution' in metadata.keys():
            if 'quality' in metadata.keys():
                return True
        elif 'quality' in metadata.keys():
            return True

    elif 'resolution' in metadata.keys():

        if check_video_extension(filename):
            return True
        else:
            return False

    elif 'quality' in metadata.keys():

        if check_video_extension(filename):
            return True
        else:
            return False
Example #23
0
 def parse_info_from_name(self, name):
     if name:
         info = dict_2_default_dict(PTN.parse(name))
         year = info['year'] if info['year'] else None
         title = get_title_from_name(name)
         quality = info['quality'] if info['quality'] else None
         return dict_2_default_dict({**info, "year": year, "title": title, "quality": quality})
     return dict_2_default_dict({"year": None, "title": None, "quality": None})
Example #24
0
 def get_episode_info(fn):
     try:
         parsed = PTN.parse(fn)
         episode_num = parsed.get("episode")
         season_num = parsed.get("season")
         year = parsed.get("year")
         return [season_num, episode_num, year]
     except TypeError:
         return [None, None, None]
Example #25
0
    def __init__(self, name):
        self.ptn_parsed_dict = PTN.parse(name, standardise=False)
        self.metas2get = ['resolution', 'codec',
                          'bitDepth', 'audio', 'quality', 'encoder']

        for obj in self.metas2get:
            current_obj_value = self.ptn_parsed_dict.get(obj)
            if self.ptn_parsed_dict.get(obj):
                setattr(self, obj, current_obj_value)
Example #26
0
 def parse_name(self):
     info = PTN.parse(self.path.name)
     self._get_title_if_not_set(info)
     self._get_year_if_not_set(info)
     if info.get("season"):
         self.season = str(info.get("season")).zfill(2)
         self.episode = str(info.get("episode")).zfill(2)
     print("Title and year from filename are:")
     print("%s [%s]" % (self.title, self.year))
Example #27
0
def list_top100(url='/precompiled/data_top100_207.json'):
    url = _host + url

    data = requests.get(url).json()
    movies = {}

    for movie in data:
        se = movie['seeders']
        le = movie['leechers']
        id = movie['id']
        name = movie['name']
        info = PTN.parse(name)
        quality = info['quality'] if 'quality' in info else 'Unknown'
        resolution = info['resolution'] if 'resolution' in info else 'Unknown'
        year = info['year'] if 'year' in info else 'XXXX'
        title = info['title'].strip().rstrip('.').lower()
        lookup_title = '%s %s' % (title, year)
        ih = movie['info_hash']

        magnet = 'magnet:?xt=urn:btih:' + ih + print_trackers()

        if lookup_title not in movies:
            movies[lookup_title] = {}

        movies[lookup_title][id] = {
            'hash':
            hash(lookup_title),
            'title':
            title,
            'id':
            id,
            'magnet':
            magnet,
            'le':
            le,
            'se':
            se,
            'year':
            year,
            'raw':
            name,
            'quality':
            quality,
            'resolution':
            resolution,
            'parse':
            info,
            'good':
            (quality.lower() in ('brrip', 'bluray', 'webrip', 'web-dl'))
            and resolution == '1080p',
            'decent':
            (quality.lower() in ('brrip', 'bluray', 'webrip', 'web-dl'))
            and resolution == '720p'
        }

    return movies
Example #28
0
def get_movie(my_call, search_lst):
    for item, var in my_call.items():
        search_me = str(var[b'name'], 'utf-8')
        new_srch = PTN.parse(search_me.lower())
        if 'episode' in new_srch and 'season' in new_srch:
            continue
        choice = process.extractOne(new_srch['title'], search_lst)
        if choice[1] > 95:
            print(choice)
            print(item, var)
Example #29
0
 def extract_movie_info(self):
     """
     If package PTN (parse torrent name) fails to detect a title and a year, a batch of homemade regular
     expressions are deployed to give it a try.
     """
     movie_info = PTN.parse(self.title)
     try:
         self.title = movie_info["title"]
         self.year = movie_info["year"]
     except KeyError:
         self._parse_movie_name()
def get_movies():
    with requests.Session() as s:
        r = s.post(url_login, data=payload_login)
        r = s.get(url_top_movies)
        data = r.text
        soup = BeautifulSoup(data, 'html.parser')

        body_element = soup.find('table', {'class': 'torrentlist'})
        movies = body_element.find_all('td', {'align': 'left'})

        films = []

        for movie in movies:
            if movie.a is not None and movie.a.b is not None:
                title = movie.a.b.text
                link = movie.a['href']
                id = link.split('=')[1]
                movie = PTN.parse(title)["title"]

                film = dict()
                film["year"] = 1933
                film["movieID"] = id
                film["title"] = title
                film["movie"] = movie
                film["imdb"] = "9.0"
                film["rotten"] = "8.3"
                film["metacritic"] = "8.7"
                film[
                    "plot"] = "When the menace known as the Joker emerges from his mysterious past, he wreaks havoc and chaos on the people of Gotham, the Dark Knight must accept one of the greatest psychological and physical tests of his ability to fight injustice."
                film[
                    "poster"] = "https://images-na.ssl-images-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg"
                '''
                res = requests.get('http://www.omdbapi.com/?t=' + movie +
                                   '&apikey=a345b6e2').text

                res = json.loads(res)
                try:
                    film["poster"] = res['Poster']
                    film["plot"] = res['Plot']
                    film["imdb"] = res['Ratings'][0]['Value']
                    film["rotten"] = res['Ratings'][1]['Value']
                    film["metacritic"] = res['Ratings'][2]['Value']
                except KeyError:
                    continue
                except IndexError:
                    film["imdb"] = '-'
                    film["rotten"] = '-'
                    film["metacritic"] = '-'
                    '''

                films.append(film)

        return {"movies": films}
    def test_parser(self):
        json_input = os.path.join(os.path.dirname(__file__), 'files/input.json')
        with open(json_input) as input_file:
            torrents = json.load(input_file)

        json_output = os.path.join(os.path.dirname(__file__), 'files/output.json')
        with open(json_output) as output_file:
            expected_results = json.load(output_file)

        for torrent, expected_result in zip(torrents, expected_results):
            result = PTN.parse(torrent)
            self.assertEqual(result, expected_result)
def parse():
    """
    Endpoint for parsing a list of torrent names for scene information

    Receives a list of strings and returns objects containing the scene information
    For more information on the name parsing see https://github.com/divijbindlish/parse-torrent-name
    """
    filenames = request.get_json()

    pretty_names = {filename:PTN.parse(filename) for filename in filenames}

    return jsonify(pretty_names)
Example #33
0
    def add_file(self, filepath):
        name = os.path.splitext(os.path.basename(filepath))[0]
        torrent = PTN.parse(name)

        file_id = hash_str(filepath)
        imdb_id = self.imdb.query(torrent['title'], year=torrent.get('year'))

        if imdb_id:
            media_id = hash_str(imdb_id)
            self.imdb.request_media(imdb_id)  # prepare request

            if not media_id in self.medias:
                self.medias[media_id] = {'files': set(), 'imdb_id': imdb_id}

            if ('season' in torrent) and ('episode' in torrent):
                self.imdb.request_media_season(imdb_id, str(torrent['season']))

        else:
            media_id = hash_str(torrent['title'])

            if not media_id in self.medias:
                self.medias[media_id] = {
                    'files': set(),
                    'seasons': dict() if 'season' in torrent else None,
                    'title': torrent['title'],
                    'year': torrent.get('year')
                }

        self.files[file_id] = {
            **self.get_file_metadata(filepath), 'episode_number':
            str(torrent['episode']) if 'episode' in torrent else None,
            'filepath':
            filepath,
            'media_id':
            media_id,
            'quality':
            torrent.get('quality'),
            'resolution':
            torrent.get('resolution'),
            'season_number':
            str(torrent['season']) if 'season' in torrent else None,
            'size':
            os.path.getsize(filepath)
        }

        media = self.medias[media_id]
        media['files'].add(file_id)

        LOG.info("Adding file '%s' (%s)", filepath, file_id)

        self.imdb.save_cache()
        self.publish()
Example #34
0
def displayList(mode="display"):
    search_string=str(ui.lineEdit_5.text()).lower()
    movies=getMovieList()
    if mode=="search" and search_string=="":
        mode="display"
    global movieList
    ui.listView.clear()
    for movie in movies:
        movieInfo = ptn.parse(movie)
        movie=movieInfo["title"].title()
        movieList.append(movieInfo)
        itemString = QtCore.QString(movie)
        item = QtGui.QListWidgetItem(itemString)
        if mode=="search":
            if search_string in movieInfo["title"].lower():
                ui.listView.addItem(item)
        else:
            ui.listView.addItem(item)
def handle_comic(comic_file):
    print 'Handling '+comic_file
    superdir = os.path.dirname(comic_file)
    name, ext = os.path.splitext(os.path.basename(comic_file))
    comic_parse = PTN.parse(name)
    print comic_parse
    # The parser matches comic book title and issue number both into 'title' key.
    # Compile the regex that matches for comic issue numbers.
    issue_regex = re.compile('(\d{1,3}(\.\d*)*\s*$)')
    # Split the title by regex matching.
    title_split = issue_regex.split(comic_parse['title'])
    # Strip trailing spaces from the title.
    title = title_split[0].strip()
    # If the split found a match and actually split, make the second half the issue number.
    if len(title_split) >= 2:
        issue = ' ' + title_split[1].strip()
    else:
        issue = ''
    # A Free Comic Book Day issue has no issue number, so it replaces the issue number value.
    if 'fcbd' in comic_parse:
        if comic_parse['fcbd']:
            issue = ' FCBD'
    if 'year' in comic_parse:
        year = ' (' + str(comic_parse['year']) + ')'
    else:
        year = ''
    # Construct the renamed filename.
    rename = title + issue + year
    comic_file_renamed = os.path.join(superdir, rename + ext)
    print('Renaming', comic_file, '->', comic_file_renamed)
    c = comicvine_api.Comicvine()
    # comic_file_name = get_file_name(file_path)
    # print(urllib.request.urlopen('http://comicvine.gamespot.com/api/search/?format=json&api_key=' + comicvine_api_key +
    #              '&query=dick+grayson&resource_type=character').read())
    # print(pycomicvine.Series.description)
    # print(c[comic_file_name])
    # comicvine.Volume.search(comic_file_name)
    sys.exit(0)
    def test_parser(self):
        json_input = os.path.join(os.path.dirname(__file__), 'files/input.json')
        with open(json_input) as input_file:
            torrents = json.load(input_file)

        json_output = os.path.join(os.path.dirname(__file__), 'files/output.json')
        with open(json_output) as output_file:
            expected_results = json.load(output_file)

        self.assertEqual(len(torrents), len(expected_results))

        for torrent, expected_result in zip(torrents, expected_results):
            print("Test: " + torrent)
            result = PTN.parse(torrent)
            for key in expected_result:
                if not expected_result[key]:
                    self.assertNotIn(key, result)
                else:
                    self.assertIn(key, result)
                    result1 = result[key]
                    if key == 'excess' and type(result1) == list:
                        result1 = ', '.join(result1)
                    self.assertEqual(result1, expected_result[key])
def handle_subtitle_file(subtitle_file):
    print('Handling subtitle file', subtitle_file)
    superdir = os.path.dirname(subtitle_file)
    name, ext = os.path.splitext(os.path.basename(subtitle_file))
    subtitle_parse = PTN.parse(name)
    print(subtitle_parse)
def handle_video_file(video_file):
    print('Handling video file', video_file)
    superdir = os.path.dirname(video_file)
    name, ext = os.path.splitext(os.path.basename(video_file))
    video_parse = PTN.parse(name)
    print(video_parse)
    if 'sample' not in video_parse:
        # Retrieve traits common to both movies and TV shows.
        title = str(video_parse['title'])
        # Get the year of release.
        if 'year' in video_parse:
            year = ' (' + str(video_parse['year']) + ')'
        else:
            year = ''
        # Get resolution if resolution was found.
        # Titles where resolution is 'HDTV' will not be found here.
        if 'resolution' in video_parse:
            resolution = ' [' + str(video_parse['resolution']) + ']'
        else:
            resolution = ''
        # Split to retrieve traits unique to TV shows.
        if is_television(video_parse):
            # Get season if season was found.
            if 'season' in video_parse:
                season = str(video_parse['season'])
            else:
                season = '0'
            # Get episode if episode was found.
            if 'episode' in video_parse:
                episode = str(video_parse['episode'])
            else:
                episode = '0'
            if len(season) > 1:
                if len(episode) > 1:
                    rename = title + ' S'+season + 'E'+episode + year + resolution
                else:
                    rename = title + ' S'+season + 'E0'+episode + year + resolution
            else:
                if len(episode) > 1:
                    rename = title + ' S0'+season + 'E'+episode + year + resolution
                else:
                    rename = title + ' S0'+season + 'E0'+episode + year + resolution
        else:
            # No unique traits to movies, simply rename with present traits.
            rename = title + year + resolution
        video_file_renamed = os.path.join(superdir, rename + ext)
        print('Renaming', video_file, '->', video_file_renamed)
        shutil.move(video_file, video_file_renamed)
        # Handle moving TV show file.
        if is_television(video_parse):
            # Get the folder for this TV show.
            telev_dir = os.path.join(dest_telev, title)
            # If the folder for this TV show doesn't exist, make it.
            if not os.path.exists(telev_dir):
                print('Creating directory', telev_dir)
                os.mkdir(telev_dir)
            # Get the folder for this season of this TV show.
            season_dir = os.path.join(telev_dir, 'Season ' + season)
            # If the folder for this season of this TV show doesn't exist yet, make it
            if not os.path.exists(season_dir):
                print('Creating directory', season_dir)
                os.mkdir(season_dir)
            # Move the TV show file into the folder of the season of the TV show.
            move_or_overwrite(video_file_renamed, season_dir, os.path.join(season_dir, rename + ext))
        else:
            # Move the movie file into the movies folder.
            move_or_overwrite(video_file_renamed, dest_movie, os.path.join(dest_movie, rename + ext))
    else:
        # If the parser found that this file is a sample file, skip it entirely.
        print('Sample video file, skipping.')
Example #39
0
def getSeason(filename): #Return the season of a Show
    try:
        return PTN.parse(filename)['season']
    except KeyError:
        return None
Example #40
0
	def get(self):
		self.response.headers['Content-type'] = 'application/json'
		self.response.out.write("> Initializing")
		osdb = opensubtitles.OpenSubtitles()
		osdb.login(username=OSORG_USERNAME, password=OSORG_PASSWORD)
		l = self.get_entity()
		logging.info(l.content)
		subreddit = r.get_subreddit('SubZorro')
		try:
			submissions = subreddit.get_new(limit=20)
		except praw.errors.HTTPException as h:
			self.response.out.write("> HTTP ERROR\n")

		# Comment Template
		ctitle = ""
		endmsg = """^This ^list ^of ^subtitles ^are ^taken ^from [^opensubtitles.org](http://www.opensubtitles.org) ^|"""
		shelp = " ^For ^feedback ^or ^suggestions ^contact [^/u/indigo6alpha](http://www.reddit.com/message/compose/?to=indigo6alpha)"
		endmsg = endmsg + shelp
		br = "\n\n---\n\n"

		for submission in submissions:
			visited = False
			summ = ""

			# Check all entities in the Datastore for this submission ID
			if(self.check_id(subid=submission.id)):
				try:
					
					_tag = re.search("""\[(Movie|MOVIE|movie|TV|tv|Tv)\]""", submission.title)

					l.content.append(submission.id)
					l.put()

					# Check if the submission has a movie or a tv tag
					if _tag is None or _tag.group(1).lower() not in ['movie','tv']:
						logging.info("No relevant tag found")
						continue

					comments_tree = submission.comments

					for comment in comments_tree:
						if str(comment.author) == 'SubZorro':
							visited = True

					if(visited == True):
						continue

					logging.info(submission.title)

					attrs = PTN.parse(re.sub("""\[(.*?)\]""","", submission.title).strip())
					subs = {}
					try:
						if(attrs.has_key('season') and attrs.has_key('episode')):
							ctitle = "#####Subtitles for this episode: "
							subs = filterByName(osdb.searchTVWithQuery(name=attrs['title'],season=str(attrs['season']),episode=str(attrs['episode'])), attrs['title'])
						elif(attrs.has_key('year')):
							ctitle = "#####Subtitles for this movie: "
							subs = filterByName(osdb.searchMoviesWithQuery(name=attrs['title'], year=str(attrs['year'])), attrs['title'])
						else:
							self.response.out.write("> Skipping "+submission.id+"\n")
							continue

					except Exception as ex:
						logging.warning("Exception: "+str(ex))
						continue

					if subs != [] and subs != None:
						try:
							for sub in subs:
								shash = hashlib.md5(sub['IDSubtitle']).hexdigest()[:8]
								summ += "> - **"+sub['MovieReleaseName'].strip()+"** - `"+sub['SubSumCD']+" CD` - [Download Subtitle](http://dl.opensubtitles.org/en/download/vrf-"+shash+"/sub/"+sub['IDSubtitle']+")\n\n"

							submission.add_comment(ctitle + br + summ.encode('ascii', 'ignore') + br + endmsg)
							self.response.out.write("> Posted subtitles for "+submission.id+"\n")
							continue

						except Exception as e:
							logging.warning("Subtitles Error: "+str(e))
							continue
					else:
						self.response.out.write("> No subtitles found for: "+submission.id+"\n")
						continue

				except Exception as e:
					logging.warning("Submission Error: "+str(e))
					continue

		self.response.write("> Done looping through submissions")