'Downloads and parses a feed.'

def process(self):

    start = time.time()
    self.refresh_feed()
    ret_values = dict(new=0, updated=0, same=0, error=0)
    if hasattr(self.fpf, 'status'):
        if self.options['verbose']:
            if (self.fpf.bozo and (self.fpf.status != 304)):
                logging.debug((u'            --->    [%-30s]    ~FRBOZO    exception:    %s    ~SB(%s    entries)' % (self.feed.log_title[:30], self.fpf.bozo_exception, len(self.fpf.entries))))
        if (self.fpf.status == 304):
            self.feed = self.feed.save()
            self.feed.save_feed_history(304, 'Not    modified')
            return (FEED_SAME, ret_values)
        if (self.fpf.status == 301):
            if self.fpf.href.endswith('feedburner.com/atom.xml'):
                return (FEED_ERRHTTP, ret_values)
            (redirects, non_redirects) = self.feed.count_redirects_in_history('feed')
            self.feed.save_feed_history(self.fpf.status, ('HTTP    Redirect    (%d    to    go)' % (10 - len(redirects))))
            if ((len(redirects) >= 10) or (len(non_redirects) == 0)):
                address = self.fpf.href
                if (self.options['force'] and address):
                    address = qurl(address, remove=['_'])
                self.feed.feed_address = address
            if (not self.feed.known_good):
                self.feed.fetched_once = True
                logging.debug(("            --->    [%-30s]    ~SB~SK~FRFeed    is    %s'ing.    Refetching..." % (self.feed.log_title[:30], self.fpf.status)))
                self.feed = self.feed.schedule_feed_fetch_immediately()
            if (not self.fpf.entries):
                self.feed = self.feed.save()
                self.feed.save_feed_history(self.fpf.status, 'HTTP    Redirect')
                return (FEED_ERRHTTP, ret_values)
        if (self.fpf.status >= 400):
            logging.debug(('            --->    [%-30s]    ~SB~FRHTTP    Status    code:    %s.    Checking    address...' % (self.feed.log_title[:30], self.fpf.status)))
            fixed_feed = None
            if (not self.feed.known_good):
                (fixed_feed, feed) = self.feed.check_feed_link_for_feed_address()
            if (not fixed_feed):
                self.feed.save_feed_history(self.fpf.status, 'HTTP    Error')
            else:
                self.feed = feed
            self.feed = self.feed.save()
            return (FEED_ERRHTTP, ret_values)
    if (not self.fpf):
        logging.debug(('            --->    [%-30s]    ~SB~FRFeed    is    Non-XML.    No    feedparser    feed    either!' % self.feed.log_title[:30]))
        self.feed.save_feed_history(551, 'Broken    feed')
        return (FEED_ERRHTTP, ret_values)
    if (self.fpf and (not self.fpf.entries)):
        if (self.fpf.bozo and isinstance(self.fpf.bozo_exception, feedparser.NonXMLContentType)):
            logging.debug(('            --->    [%-30s]    ~SB~FRFeed    is    Non-XML.    %s    entries.    Checking    address...' % (self.feed.log_title[:30], len(self.fpf.entries))))
            fixed_feed = None
            if (not self.feed.known_good):
                (fixed_feed, feed) = self.feed.check_feed_link_for_feed_address()
            if (not fixed_feed):
                self.feed.save_feed_history(552, 'Non-xml    feed', self.fpf.bozo_exception)
            else:
                self.feed = feed
            self.feed = self.feed.save()
            return (FEED_ERRPARSE, ret_values)
        elif (self.fpf.bozo and isinstance(self.fpf.bozo_exception, xml.sax._exceptions.SAXException)):
            logging.debug(('            --->    [%-30s]    ~SB~FRFeed    has    SAX/XML    parsing    issues.    %s    entries.    Checking    address...' % (self.feed.log_title[:30], len(self.fpf.entries))))
            fixed_feed = None
            if (not self.feed.known_good):
                (fixed_feed, feed) = self.feed.check_feed_link_for_feed_address()
            if (not fixed_feed):
                self.feed.save_feed_history(553, 'Not    an    RSS    feed', self.fpf.bozo_exception)
            else:
                self.feed = feed
            self.feed = self.feed.save()
            return (FEED_ERRPARSE, ret_values)
    original_etag = self.feed.etag
    self.feed.etag = self.fpf.get('etag')
    if self.feed.etag:
        self.feed.etag = self.feed.etag[:255]
    if (self.feed.etag is None):
        self.feed.etag = ''
    if (self.feed.etag != original_etag):
        self.feed.save(update_fields=['etag'])
    original_last_modified = self.feed.last_modified
    if (hasattr(self.fpf, 'modified') and self.fpf.modified):
        try:
            self.feed.last_modified = datetime.datetime.strptime(self.fpf.modified, '%a,    %d    %b    %Y    %H:%M:%S    %Z')
        except Exception as e:
            self.feed.last_modified = None
            logging.debug(('Broken    mtime    %s:    %s' % (self.feed.last_modified, e)))
            pass
    if (self.feed.last_modified != original_last_modified):
        self.feed.save(update_fields=['last_modified'])
    self.fpf.entries = self.fpf.entries[:100]
    original_title = self.feed.feed_title
    if self.fpf.feed.get('title'):
        self.feed.feed_title = strip_tags(self.fpf.feed.get('title'))
    if (self.feed.feed_title != original_title):
        self.feed.save(update_fields=['feed_title'])
    tagline = self.fpf.feed.get('tagline', self.feed.data.feed_tagline)
    if tagline:
        original_tagline = self.feed.data.feed_tagline
        self.feed.data.feed_tagline = smart_unicode(tagline)
        if (self.feed.data.feed_tagline != original_tagline):
            self.feed.data.save(update_fields=['feed_tagline'])
    if (not self.feed.feed_link_locked):
        new_feed_link = (self.fpf.feed.get('link') or self.fpf.feed.get('id') or self.feed.feed_link)
        if (self.options['force'] and new_feed_link):
            new_feed_link = qurl(new_feed_link, remove=['_'])
        if (new_feed_link != self.feed.feed_link):
            logging.debug(("            --->    [%-30s]    ~SB~FRFeed's    page    is    different:    %s    to    %s" % (self.feed.log_title[:30], self.feed.feed_link, new_feed_link)))
            (redirects, non_redirects) = self.feed.count_redirects_in_history('page')
            self.feed.save_page_history(301, ('HTTP    Redirect    (%s    to    go)' % (10 - len(redirects))))
            if ((len(redirects) >= 10) or (len(non_redirects) == 0)):
                self.feed.feed_link = new_feed_link
                self.feed.save(update_fields=['feed_link'])
    guids_seen = set()
    permalinks_seen = set()
    for entry in self.fpf.entries:
        guids_seen.add(entry.get('guid'))
        permalinks_seen.add(Feed.get_permalink(entry))
    guid_difference = (len(guids_seen) != len(self.fpf.entries))
    single_guid = (len(guids_seen) == 1)
    replace_guids = (single_guid and guid_difference)
    permalink_difference = (len(permalinks_seen) != len(self.fpf.entries))
    single_permalink = (len(permalinks_seen) == 1)
    replace_permalinks = (single_permalink and permalink_difference)
    start_date = datetime.datetime.utcnow()
    story_hashes = []
    stories = []
    for entry in self.fpf.entries:
        story = pre_process_story(entry, self.fpf.encoding)
        if (story.get('published') < start_date):
            start_date = story.get('published')
        if replace_guids:
            if replace_permalinks:
                new_story_guid = unicode(story.get('published'))
                if self.options['verbose']:
                    logging.debug((u'            --->    [%-30s]    ~FBReplacing    guid    (%s)    with    timestamp:    %s' % (self.feed.log_title[:30], story.get('guid'), new_story_guid)))
                story['guid'] = new_story_guid
            else:
                new_story_guid = Feed.get_permalink(story)
                if self.options['verbose']:
                    logging.debug((u'            --->    [%-30s]    ~FBReplacing    guid    (%s)    with    permalink:    %s' % (self.feed.log_title[:30], story.get('guid'), new_story_guid)))
                story['guid'] = new_story_guid
        story['story_hash'] = MStory.feed_guid_hash_unsaved(self.feed.pk, story.get('guid'))
        stories.append(story)
        story_hashes.append(story.get('story_hash'))
    original_story_hash_count = len(story_hashes)
    story_hashes_in_unread_cutoff = self.feed.story_hashes_in_unread_cutoff[:original_story_hash_count]
    story_hashes.extend(story_hashes_in_unread_cutoff)
    story_hashes = list(set(story_hashes))
    if (self.options['verbose'] or settings.DEBUG):
        logging.debug((u'            --->    [%-30s]    ~FBFound    ~SB%s~SN    guids,    adding    ~SB%s~SN/%s    guids    from    db' % (self.feed.log_title[:30], original_story_hash_count, (len(story_hashes) - original_story_hash_count), len(story_hashes_in_unread_cutoff))))
    existing_stories = dict(((s.story_hash, s) for s in MStory.objects(story_hash__in=story_hashes)))
    ret_values = self.feed.add_update_stories(stories, existing_stories, verbose=self.options['verbose'], updates_off=self.options['updates_off'])
    if (hasattr(self.fpf, 'feed') and hasattr(self.fpf.feed, 'links') and self.fpf.feed.links):
        hub_url = None
        self_url = self.feed.feed_address
        for link in self.fpf.feed.links:
            if ((link['rel'] == 'hub') and (not hub_url)):
                hub_url = link['href']
            elif (link['rel'] == 'self'):
                self_url = link['href']
        push_expired = False
        if self.feed.is_push:
            try:
                push_expired = (self.feed.push.lease_expires < datetime.datetime.now())
            except PushSubscription.DoesNotExist:
                self.feed.is_push = False
        if (hub_url and self_url and (not settings.DEBUG) and (self.feed.active_subscribers > 0) and (push_expired or (not self.feed.is_push) or self.options.get('force'))):
            logging.debug((u'            --->    [%-30s]    ~BB~FW%sSubscribing    to    PuSH    hub:    %s' % (self.feed.log_title[:30], ('~SKRe-~SN' if push_expired else ''), hub_url)))
            try:
                PushSubscription.objects.subscribe(self_url, feed=self.feed, hub=hub_url)
            except TimeoutError:
                logging.debug((u'            --->    [%-30s]    ~BB~FW~FRTimed    out~FW    subscribing    to    PuSH    hub:    %s' % (self.feed.log_title[:30], hub_url)))
        elif (self.feed.is_push and ((self.feed.active_subscribers <= 0) or (not hub_url))):
            logging.debug((u'            --->    [%-30s]    ~BB~FWTurning    off    PuSH,    no    hub    found' % self.feed.log_title[:30]))
            self.feed.is_push = False
            self.feed = self.feed.save()
    if ((ret_values['new'] > 0) and (MUserFeedNotification.feed_has_users(self.feed.pk) > 0)):
        QueueNotifications.delay(self.feed.pk, ret_values['new'])
    logging.debug((u'            --->    [%-30s]    ~FYParsed    Feed:    %snew=%s~SN~FY    %sup=%s~SN    same=%s%s~SN    %serr=%s~SN~FY    total=~SB%s' % (self.feed.log_title[:30], ('~FG~SB' if ret_values['new'] else ''), ret_values['new'], ('~FY~SB' if ret_values['updated'] else ''), ret_values['updated'], ('~SB' if ret_values['same'] else ''), ret_values['same'], ('~FR~SB' if ret_values['error'] else ''), ret_values['error'], len(self.fpf.entries))))
    self.feed.update_all_statistics(has_new_stories=bool(ret_values['new']), force=self.options['force'])
    fetch_date = datetime.datetime.now()
    if ret_values['new']:
        if (not getattr(settings, 'TEST_DEBUG', False)):
            self.feed.trim_feed()
            self.feed.expire_redis()
        if (MStatistics.get('raw_feed', None) == self.feed.pk):
            self.feed.save_raw_feed(self.raw_feed, fetch_date)
    self.feed.save_feed_history(200, 'OK', date=fetch_date)
    if self.options['verbose']:
        logging.debug((u'            --->    [%-30s]    ~FBTIME:    feed    parse    in    ~FM%.4ss' % (self.feed.log_title[:30], (time.time() - start))))
    return (FEED_OK, ret_values)
