summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-09-28 18:48:25 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2010-09-28 18:48:25 +0200
commit3fbe90f8fdc67d484dc47a44e4f1e192304d7f51 (patch)
tree363351f813ac42a9f9ca1a0314d488b994a088f6 /modules
parent971f041b74867eae2cefd25c203e3a61e4125f44 (diff)
Check package status when adding (start) and checking (status) your own trackings.
Diffstat (limited to 'modules')
-rw-r--r--modules/tracking.py100
1 files changed, 63 insertions, 37 deletions
diff --git a/modules/tracking.py b/modules/tracking.py
index 405514e..9d1ee9d 100644
--- a/modules/tracking.py
+++ b/modules/tracking.py
@@ -8,6 +8,7 @@ cfg_section = 'module/tracking'
import urllib2, datetime, re
from lxml import etree
+from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
@@ -28,6 +29,7 @@ class Consignment(Base):
code = Column(String, nullable = False, unique = True)
label = Column(String)
added = Column(DateTime, nullable = False)
+ last = Column(DateTime)
packages = relation('Package', backref = 'consignment', primaryjoin = 'Package.consignment_id == Consignment.id')
@@ -51,6 +53,8 @@ class Package(Base):
self.consignment_id = consignment_id
self.code = code
+class NoPackageFound(Exception): pass
+
class Module:
url = 'http://sporing.posten.no/sporing.xml?q=%s'
@@ -60,7 +64,7 @@ class Module:
self.tracking = []
self.lc = LoopingCall(self.lc_callback)
if bot:
- self.lc.start(config.getfloat(cfg_section, 'interval'), False)
+ #self.lc.start(config.getfloat(cfg_section, 'interval'), False)
self.irc.register_keyword('!track', self)
def stop(self):
@@ -99,7 +103,7 @@ class Module:
ns = 'http://www.bring.no/sporing/1.0'
packages = xml.find('//{%s}PackageSet' % (ns,))
if packages is None:
- raise Exception('No packages found for \002%s\002.' % code)
+ raise NoPackageFound('No packages found for \002%s\002.' % code)
results = []
for package in packages:
@@ -127,6 +131,7 @@ class Module:
session.add(consignment)
session.commit()
msg = 'Now tracking \002%s\002.' % code
+ reactor.callLater(1, self.track_update, code, True)
except IntegrityError as e:
msg = 'Already tracking \002%s\002.' % code
finally:
@@ -160,6 +165,7 @@ class Module:
consignments = consignments.filter(Consignment.nick == nick)
results = []
for row in consignments:
+ self.track_update(row.code)
i = 0
if row.label:
label = ' (%s)' % row.label
@@ -193,7 +199,7 @@ class Module:
msg = 'Failed to fetch tracking data for \002%s\002.' % code.decode('utf8')
else:
msg = 'No tracking number given or registered.'
- except Exception as e:
+ except NoPackageFound as e:
msg = str(e)
finally:
session.close()
@@ -280,51 +286,71 @@ class Module:
else:
self.irc.msg(channel if not channel == self.irc.nickname else nick.split('!')[0], 'No data returned (this is a bug).')
+ # called by start and status
+ def track_update(self, code, announce = False):
+ try:
+ session = Session()
+ consignment = session.query(Consignment).filter(Consignment.code == code).one()
+ self.update_consignment(session, consignment, announce)
+ session.commit()
+ finally:
+ session.close()
+
+ def update_consignment(self, session, consignment, announce = True):
+ now = datetime.datetime.utcnow()
+ td = datetime.timedelta(seconds = config.getint(cfg_section, 'cache_time'))
+ # return if consignment was cached within cache_time seconds
+ if consignment.last and consignment.last > now - td:
+ return
+ consignment.last = now
+ label = (' (%s)' % consignment.label if consignment.label else '')
+ target = consignment.channel or consignment.nick
+ target = target.encode('utf-8')
+ removed = False
+ data_ = self.track(consignment.code)
+ if not data_:
+ return
+ for data in data_:
+ try:
+ package = session.query(Package).filter_by(code = data[0]).one()
+ except NoResultFound:
+ package = Package(consignment.id, data[0])
+ session.add(package)
+ package = session.query(Package).filter_by(code = data[0]).one()
+
+ if package.last == None or data[1] > package.last:
+ code = data[0]
+ last = data[1]
+ desc = data[2]
+ msg = '%s: \002%s\002%s %s - %s' % (consignment.nick.encode('utf-8'), package.code.encode('utf-8'), label.encode('utf-8'), last, desc)
+ if desc.startswith('Sendingen er utlevert'):
+ session.delete(package)
+ msg += ' (Package delivered - tracking stopped)'
+ removed = True
+ else:
+ package.last = last
+ package.status = desc
+ session.add(package)
+ if announce:
+ self.irc.msg(target, msg)
+ if removed and len(consignment.packages) == 0:
+ msg = '%s: \002%s\002%s is no longer being tracked' % (consignment.nick, consignment.code, label)
+ if announce:
+ self.irc.msg(target, msg.encode('utf-8'))
+ session.delete(consignment)
+
def lc_callback(self):
try:
session = Session()
consignments = session.query(Consignment).filter(Consignment.channel.in_(config.get(self.irc.factory.server, 'channels').split()))
for row in consignments:
- label = (' (%s)' % row.label if row.label else '')
- target = row.channel or row.nick
- target = target.encode('utf-8')
- removed = False
- data_ = self.track(row.code)
- if not data_:
- continue
- for data in data_:
- try:
- package = session.query(Package).filter_by(code = data[0]).one()
- except:
- package = Package(row.id, data[0])
- session.add(package)
- package = session.query(Package).filter_by(code = data[0]).one()
-
- if package.last == None or data[1] > package.last:
- code = data[0]
- last = data[1]
- desc = data[2]
- msg = '%s: \002%s\002%s %s - %s' % (row.nick.encode('utf-8'), package.code.encode('utf-8'), label.encode('utf-8'), last, desc)
- if desc.startswith('Sendingen er utlevert'):
- session.delete(package)
- msg += ' (Package delivered - tracking stopped)'
- removed = True
- else:
- package.last = last
- package.status = desc
- session.add(package)
- self.irc.msg(target, msg)
- if removed and len(row.packages) == 0:
- msg = '%s: \002%s\002%s is no longer being tracked' % (row.nick, row.code, label)
- self.irc.msg(target, msg.encode('utf-8'))
- session.delete(row)
+ update_consignment(session, row)
session.commit()
finally:
session.close()
if __name__ == '__main__':
import sys, ConfigParser, os
- from twisted.internet import reactor
config = ConfigParser.ConfigParser()
config.read([os.path.expanduser('~/.fot')])
m = Module(None)