cron_task.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/usr/bin/env python2
  2. import signal
  3. import traceback
  4. from sys import stderr
  5. from datetime import datetime, timedelta
  6. from flask.ext.mail import Message
  7. from flask import url_for
  8. from ffdnispdb.crawler import TextValidator
  9. from ffdnispdb.models import ISP
  10. from ffdnispdb import app, db, mail
  11. MAX_RUNTIME=15*60
  12. class Timeout(Exception):
  13. pass
  14. class ScriptTimeout(Exception):
  15. """
  16. Script exceeded its allowed run time
  17. """
  18. strike=1
  19. last_isp=-1
  20. script_begin=datetime.now()
  21. def timeout_handler(signum, frame):
  22. global last_isp, strike
  23. if script_begin < datetime.now()-timedelta(seconds=MAX_RUNTIME):
  24. raise ScriptTimeout
  25. if last_isp == isp.id:
  26. strike += 1
  27. if strike > 2:
  28. signal.alarm(6)
  29. raise Timeout
  30. else:
  31. last_isp = isp.id
  32. strike = 1
  33. signal.alarm(6)
  34. signal.signal(signal.SIGALRM, timeout_handler)
  35. signal.alarm(6)
  36. def send_warning_email(isp, debug_msg):
  37. msg=Message(u"Problem while updating your ISP's data", sender=('FFDN DB <cron@db.ffdn.org>'))
  38. msg.body = """
  39. Hello,
  40. You are receiving this mail because your ISP, %s, is registered on the FFDN ISP Database.
  41. Our automatic update script could not access or process your ISP's data located at %s.
  42. Automatic updates of your ISP were disabled until you fix the problem.
  43. Here is some debug output to help you locate the issue:
  44. %s
  45. ---
  46. When the issue is resolved, please click on the link below to reactivate automatic updates on your ISP:
  47. %s
  48. Thanks,
  49. The FFDN ISP Database team
  50. """.strip()%(isp.complete_name, isp.json_url, debug_msg.strip(), url_for('home'))
  51. msg.add_recipient(isp.tech_email)
  52. mail.send(msg)
  53. app.config['SERVER_NAME'] = 'db.ffdn.org'
  54. app.app_context().push()
  55. try:
  56. for isp in ISP.query.filter(ISP.is_disabled == False,
  57. ISP.json_url != None,
  58. ISP.next_update < datetime.now(),
  59. ISP.update_error_strike < 3)\
  60. .order_by(ISP.last_update_success):
  61. try:
  62. print u'%s: Attempting to update %s'%(datetime.now(), isp)
  63. print u' last successful update=%s'%(isp.last_update_success)
  64. print u' last update attempt=%s'%(isp.last_update_attempt)
  65. print u' next update was scheduled %s ago'%(datetime.now()-isp.next_update)
  66. print u' strike=%d'%(isp.update_error_strike)
  67. isp.last_update_attempt=datetime.now()
  68. db.session.add(isp)
  69. db.session.commit()
  70. validator=TextValidator()
  71. log=''.join(validator(isp.json_url+'ab'))
  72. if not validator.success: # handle error
  73. isp.update_error_strike += 1
  74. #isp.next_update = bla
  75. db.session.add(isp)
  76. db.session.commit()
  77. print u'%s: Error while updating:'%(datetime.now())
  78. if isp.update_error_strike >= 3:
  79. send_warning_email(isp, log)
  80. print u' three strikes, you\'re out'
  81. print log.rstrip()+'\n'
  82. continue
  83. isp.json = validator.jdict
  84. isp.last_update_success = isp.last_update_attempt
  85. isp.update_error_strike = 0
  86. #isp.next_update = bla
  87. db.session.add(isp)
  88. db.session.commit()
  89. print u'%s: Update successful !'%(datetime.now())
  90. print u' next update is scheduled for %s\n'%(isp.next_update)
  91. except Timeout:
  92. print u'%s: Timeout while updating:'%(datetime.now())
  93. isp=ISP.query.get(isp.id)
  94. isp.update_error_strike += 1
  95. db.session.add(isp)
  96. db.session.commit()
  97. if isp.update_error_strike >= 3:
  98. send_warning_email(isp, 'Your ISP took more then 18 seconds to process. '
  99. 'Having problems with your webserver ?')
  100. print u' three strikes, you\'re out'
  101. print traceback.format_exc()
  102. except ScriptTimeout:
  103. pass
  104. except Timeout:
  105. pass