Example #1
0
File: nfos.py Project: shpd/pynab
def process(limit=5, category=0):
    """Process releases for NFO parts and download them."""
    log.info('Checking for NFO segments...')

    with Server() as server:
        query = {'nfo': None}
        if category:
            query['category._id'] = int(category)

        for release in db.releases.find(query).limit(limit).sort('posted', pymongo.DESCENDING).batch_size(50):
            log.debug('Checking for NFO in {}...'.format(release['search_name']))
            nzb = pynab.nzbs.get_nzb_dict(release['nzb'])

            if nzb:
                nfos = []
                if nzb['nfos']:
                    for nfo in nzb['nfos']:
                        if not isinstance(nfo['segments']['segment'], list):
                            nfo['segments']['segment'] = [nfo['segments']['segment'], ]
                        for part in nfo['segments']['segment']:
                            if int(part['@bytes']) > NFO_MAX_FILESIZE:
                                continue
                            nfos.append(part)

                if nfos:
                    for nfo in nfos:
                        try:
                            article = server.get(release['group']['name'], [nfo['#text'], ])
                        except:
                            article = None

                        if article:
                            data = gzip.compress(article.encode('utf-8'))
                            nfo_file = fs.put(data, filename='.'.join([release['name'], 'nfo', 'gz']))

                            if nfo_file:
                                db.releases.update({'_id': release['_id']}, {
                                    '$set': {
                                        'nfo': nfo_file
                                    }
                                })
                                log.info('Grabbed and saved NFO for: {}'.format(release['name']))
                                break
                        else:
                            log.debug('Error retrieving NFO.')
                            continue
                else:
                    log.debug('No NFOs found in this release.')
                    db.releases.update({'_id': release['_id']}, {
                        '$set': {
                            'nfo': False
                        }
                    })
Example #2
0
def create(gid, name, binary):
    """Create the NZB, store it in GridFS and return the ID
    to be linked to the release."""
    if binary['category_id']:
        category = db.categories.find_one({'id': binary['category_id']})
    else:
        category = None

    xml = ''
    try:
        tpl = Template(filename=os.path.join(root_dir, 'templates/nzb.mako'))
        xml = tpl.render(version=pynab.__version__, name=name, category=category, binary=binary)
    except:
        log.error('nzb: failed to create NZB: {0}'.format(exceptions.text_error_template().render()))
        return None

    data = gzip.compress(xml.encode('utf-8'))
    return fs.put(data, filename='.'.join([gid, 'nzb', 'gz'])), sys.getsizeof(data, 0)
Example #3
0
def import_nzb(filepath, quick=True):
    """Import an NZB and directly load it into releases."""
    file, ext = os.path.splitext(filepath)

    if ext == '.gz':
        f = gzip.open(filepath, 'rt', encoding='utf-8', errors='ignore')
    else:
        f = open(filepath, 'r', encoding='utf-8', errors='ignore')

    if quick:
        release = {'added': pytz.utc.localize(datetime.datetime.now()), 'size': None, 'spotnab_id': None,
                   'completion': None, 'grabs': 0, 'passworded': None, 'file_count': None, 'tvrage': None,
                   'tvdb': None, 'imdb': None, 'nfo': None, 'tv': None, 'total_parts': 0}

        try:
            for event, elem in cet.iterparse(f):
                if 'meta' in elem.tag:
                    release[elem.attrib['type']] = elem.text
                if 'file' in elem.tag:
                    release['total_parts'] += 1
                    release['posted'] = elem.get('date')
                    release['posted_by'] = elem.get('poster')
                if 'group' in elem.tag and 'groups' not in elem.tag:
                    release['group_name'] = elem.text
        except:
            log.error('Error parsing NZB files: file appears to be corrupt.')
            return False

        if 'name' not in release:
            log.error('Failed to import nzb: {0}'.format(filepath))
            return False

        # check that it doesn't exist first
        r = db.releases.find_one({'name': release['name']})
        if not r:
            release['id'] = hashlib.md5(uuid.uuid1().bytes).hexdigest()
            release['search_name'] = release['name']

            release['status'] = 2

            if 'posted' in release:
                release['posted'] = datetime.datetime.fromtimestamp(int(release['posted']), pytz.utc)
            else:
                release['posted'] = None

            if 'category' in release:
                parent, child = release['category'].split(' > ')

                parent_category = db.categories.find_one({'name': parent})
                if parent_category:
                    child_category = db.categories.find_one({'name': child, 'parent_id': parent_category['_id']})

                    if child_category:
                        release['category'] = child_category
                        release['category']['parent'] = parent_category
                    else:
                        release['category'] = None
                else:
                    release['category'] = None
            else:
                release['category'] = None

            # make sure the release belongs to a group we have in our db
            if 'group_name' in release:
                group = db.groups.find_one({'name': release['group_name']}, {'name': 1})
                if not group:
                    log.error('Could not add release - group {0} doesn\'t exist.'.format(release['group_name']))
                    return False
                release['group'] = group
                del release['group_name']

            # rebuild the nzb, gzipped
            f.seek(0)
            data = gzip.compress(f.read().encode('utf-8'))
            release['nzb'] = fs.put(data, filename='.'.join([release['id'], 'nzb', 'gz']))
            release['nzb_size'] = sys.getsizeof(data, 0)

            try:
                db.releases.insert(release)
            except:
                log.error('Problem saving release: {0}'.format(release))
                return False
            f.close()

            return True
        else:
            log.error('Release already exists: {0}'.format(release['name']))
            return False