PageRenderTime 42ms CodeModel.GetById 17ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/blogmaker/blog/trackback_update.py

http://blogmaker.googlecode.com/
Python | 116 lines | 88 code | 13 blank | 15 comment | 12 complexity | 30954b3536128e85bb3bfb26b7d88508 MD5 | raw file
  1''' Utility to attempt current trackbacks logging the results.
  2
  3Copyright (c) 2006-2007, PreFab Software Inc.
  4
  5'''
  6
  7from __future__ import with_statement
  8
  9import datetime, logging, sys
 10from cStringIO import StringIO
 11from itertools import chain, imap, islice
 12
 13from django.conf import settings
 14import blogcosm.django_setup
 15from django.core.mail import send_mail
 16
 17from blogmaker.blog.models import Entry
 18from blogmaker.util import logToData
 19from blogmaker.util.trap_errors import error_trapping
 20
 21
 22def main():
 23    ''' Attempt all current trackbacks. 
 24        Email the results to settings.MANAGERS.
 25    '''
 26    logToData('trackback.log')
 27    
 28    # Set up to capture logging info for email
 29    log = getLogger()
 30    buf = StringIO()
 31    handler = logging.StreamHandler(buf)
 32    formatter = logging.Formatter('%(message)s')
 33    handler.setFormatter(formatter)
 34    log.addHandler(handler)
 35    
 36    # The actual attempt
 37    log.info('--------------------- Start Trackback Attempt for %s ------------------' % settings.DATABASE_NAME)
 38    attempts = attempt_all_current()
 39    
 40    # Email the results if any
 41    log.removeHandler(handler)
 42    if attempts:
 43        results = buf.getvalue()
 44        toaddrs  = [manager_tuple[1] for manager_tuple in settings.MANAGERS]
 45
 46        with error_trapping('sending email'):
 47            send_mail('Trackback Results %s' % datetime.date.today(), results, 
 48                settings.DEFAULT_FROM_EMAIL, toaddrs, fail_silently=False)
 49    
 50
 51def attempt_all_current():
 52    ''' Find all current entries.
 53        Update their trackback list to reflect their current links.
 54        Attempt all eligible trackbacks for the entries.
 55        Returns a count of the number of trackbacks attempted. '''
 56    log = getLogger()
 57    now = datetime.datetime.now()
 58    startDate = now - datetime.timedelta(days=7)
 59    attempts = 0
 60    
 61    for entry in Entry.objects.exclude(pub_date__gt=now).exclude(pub_date__lt=startDate):
 62        entry.update_trackbacks()
 63        for tb in entry.trackbacks.all():
 64            if tb.eligible:
 65                with error_trapping():
 66                    attempts += 1
 67                    log.info('Attempting trackback for "%s" (%s)' % (tb.entry.headline, tb.link))
 68                    tb.attempt()
 69                    if tb.message:
 70                        log.info('Result: %s: %s', tb.get_status_display(), tb.message)
 71                    else:
 72                        log.info('Result: %s', tb.get_status_display())
 73                    if tb.status=='NoLink' and hasattr(tb, 'page_data'):
 74                        count = logPossibles(log, tb.page_data)
 75                        if count:
 76                            tb.appendMessage("%s candidate(s) found; see email for details" % count)
 77                        else:
 78                            tb.appendMessage("No candidates found")
 79                        tb.save()
 80                    log.info('')
 81    return attempts
 82    
 83
 84def logPossibles(log, data):
 85    ''' Log possible trackbacks and return a count of how many were found. '''
 86    log.info('Possible trackbacks:')
 87    found = False
 88    count = 0
 89    for prev, curr, next in triples(data.splitlines()):
 90        if 'trackback' in curr.lower():
 91            log.info('    ' + prev)
 92            log.info('    ' + curr)
 93            log.info('    ' + next)
 94            found = True
 95            count += 1
 96    if not found:
 97        log.info('    None')
 98    return count
 99
100def triples(seq, fill=''):
101    ''' Yield walking triples of items in seq.
102        Each item in seq appears once as the middle item.
103        End triples are filled with fill.
104    '''
105    iters = [ chain([fill], iter(seq)), 
106              iter(seq), 
107              chain(islice(seq, 1, sys.maxint), [fill]) ]
108    return imap(None, *iters)
109        
110        
111def getLogger():
112    return logging.getLogger('blogmaker.blog.trackback_update')
113    
114    
115if __name__ == '__main__':
116    main()