def get_info(self, id): if len(self.document.xpath('//libelle[@nom="MSG_AUCUN_EVT"]')) > 0: return None p = Parcel(id) p.arrival = NotAvailable p.history = [] for i, tr in enumerate( self.document.xpath('//table[@class="tabListeEnvois"]//tr')): tds = tr.findall('td') if len(tds) < 3: continue ev = Event(i) ev.location = unicode(tds[1].text) if tds[1].text else None ev.activity = unicode(tds[1].find('br').tail) if tds[-1].text is not None: ev.activity += ', ' + self.parser.tocleanstring(tds[-1]) date = re.sub('[a-z]+', '', self.parser.tocleanstring(tds[0])).strip() date = re.sub('(\d+)/(\d+)/(\d+)', r'\3-\2-\1', date) ev.date = parse_date(date) p.history.append(ev) p.info = ' '.join([ t.strip() for t in self.document.xpath( '//div[@class="numeroColi2"]')[0].itertext() ][1:]) if u'Livraison effectuée' in p.history[0].activity: p.status = p.STATUS_ARRIVED return p
def get_parcel_tracking(self, _id): # 13 is the magic length of colissimo tracking ids if len(_id) != 13: raise ParcelNotFound( u"Colissimo ID's must have 13 print character") data = self.browser.get_tracking_info(_id) p = Parcel(_id) label = data['message'] if data['error']: raise ParcelNotFound(label + u" (id = %s@%s)" % (_id, self.name)) p.info = label # TODO, need to know the delivery message if u"remis au gardien ou" in label or u"Votre colis est livré" in label: p.status = p.STATUS_ARRIVED elif u"pas encore pris en charge par La Poste" in label: p.status = p.STATUS_PLANNED else: p.status = p.STATUS_IN_TRANSIT ev = Event(0) ev.activity = label ev.date = date(*reversed([int(x) for x in data['date'].split("/")])) p.history = [ev] return p
def get_info(self, _id): p = Parcel(_id) events = self.doc["tuStatus"][0]["history"] p.history = [self.build_event(i, tr) for i, tr in enumerate(events)] p.status = self.guess_status(self.doc["tuStatus"][0]["progressBar"]["statusInfo"]) p.info = self.doc["tuStatus"][0]["progressBar"]["statusText"] return p
def get_info(self, id): if len(self.document.xpath('//libelle[@nom="MSG_AUCUN_EVT"]')) > 0: return None p = Parcel(id) p.arrival = NotAvailable p.history = [] for i, tr in enumerate(self.document.xpath('//table[@class="tabListeEnvois"]//tr')): tds = tr.findall('td') if len(tds) < 3: continue ev = Event(i) ev.location = unicode(tds[1].text) if tds[1].text else None ev.activity = unicode(tds[1].find('br').tail) if tds[-1].text is not None: ev.activity += ', ' + self.parser.tocleanstring(tds[-1]) date = re.sub('[a-z]+', '', self.parser.tocleanstring(tds[0])).strip() date = re.sub('(\d+)/(\d+)/(\d+)', r'\3-\2-\1', date) ev.date = parse_date(date) p.history.append(ev) p.info = ' '.join([t.strip() for t in self.document.xpath('//div[@class="numeroColi2"]')[0].itertext()][1:]) if u'Livraison effectuée' in p.history[0].activity: p.status = p.STATUS_ARRIVED return p
def get_info(self, _id): if u'errors' in self.doc: raise ParcelNotFound("No such ID: %s" % _id) elif u'results' in self.doc: result = self.doc[u'results'][0] p = Parcel(_id) p.history = [self.build_event(e) for e in result[u'checkpoints']] p.status = self.STATUSES.get(result[u'delivery'][u'code'], Parcel.STATUS_UNKNOWN) p.info = p.history[0].activity return p else: raise ParcelNotFound("Unexpected reply from server")
def get_info(self, _id): result_id = self.doc.xpath('//th[@class="mm_sendungsnummer"]') if not result_id: raise ParcelNotFound("No such ID: %s" % _id) result_id = result_id[0].text if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) events = self.doc.xpath('//div[@class="accordion-inner"]/table/tbody/tr') p.history = [self.build_event(i, tr) for i, tr in enumerate(events)] p.status, p.info = self.guess_status(p.history[-1]) return p
def get_info(self, _id): result_id = self.doc.xpath('//th[@class="mm_sendungsnummer"]') if not result_id: raise ParcelNotFound("No such ID: %s" % _id) result_id = result_id[0].text if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) events = self.doc.xpath( '//div[@class="accordion-inner"]/table/tbody/tr') p.history = [self.build_event(i, tr) for i, tr in enumerate(events)] p.status, p.info = self.guess_status(p.history[-1]) return p
def get_info(self, _id): result_id = self.doc.xpath('//table[@id="shipment-details-table"]//tr[position()=1]/td[@id="td-bold"]') if not result_id: raise ParcelNotFound("No such ID: %s" % _id) result_id = result_id[0].text if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) events = self.doc.xpath('//div[@id="shipment-event-table-cell"]') p.history = [self.build_event(i, div) for i, div in enumerate(events)] most_recent = p.history[0] p.status, p.info = self.guess_status(p.history) p.info = most_recent.activity return p
def get_info(self, _id): result_id = self.doc.get("TrackingStatusJSON", {}).get("shipmentInfo", {}).get("parcelNumber", None) if not result_id: raise ParcelNotFound("No such ID: %s" % _id) if not _id.startswith(result_id): raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) events = self.doc.get("TrackingStatusJSON", {}).get("statusInfos", []) p.history = [self.build_event(i, data) for i, data in enumerate(events)] p.status = self.guess_status( self.doc.get("TrackingStatusJSON", {}). get("shipmentInfo", {}). get("deliveryStatus")) p.info = p.history[-1].activity return p
def get_info(self, _id): result_id = self.doc.xpath( '//table[@id="shipment-details-table"]//tr[position()=1]/td[@id="td-bold"]' ) if not result_id: raise ParcelNotFound("No such ID: %s" % _id) result_id = result_id[0].text if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) events = self.doc.xpath('//div[@id="shipment-event-table-cell"]') p.history = [self.build_event(i, div) for i, div in enumerate(events)] most_recent = p.history[0] p.status, p.info = self.guess_status(p.history) p.info = most_recent.activity return p
def get_info(self, _id): shipments = self.doc["shipments"] if not shipments: raise ParcelNotFound("No such ID: %s" % _id) shipment = shipments[0] result_id = shipment["trackingCode"] if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) if shipment["estimatedDeliveryTime"]: p.arrival = parse_date(shipment["estimatedDeliveryTime"], ignoretz=True) events = shipment["events"] p.history = [self.build_event(i, data) for i, data in enumerate(events)] most_recent = p.history[0] p.status, p.info = self.guess_status(p.history) p.info = most_recent.activity return p
def get_info(self, _id): result_id = self.doc.xpath('//th[@class="mm_sendungsnummer"]') if not result_id: raise ParcelNotFound("No such ID: %s" % _id) result_id = result_id[0].text if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) events = self.doc.xpath('//div[@class="accordion-inner"]/table/tbody/tr') p.history = [self.build_event(i, tr) for i, tr in enumerate(events)] status_msgs = self.doc.xpath('//tr[@class="mm_mailing_process "]//img[contains(@src, "ACTIVE")]/@alt') if len(status_msgs) > 0: p.status = self.STATUSES.get(status_msgs[-1], Parcel.STATUS_UNKNOWN) else: p.status = Parcel.STATUS_UNKNOWN p.info = p.history[-1].activity return p
def get_info(self, _id): p = Parcel(_id) statustr = self.document.xpath('//tr[@class="bandeauText"]')[0] status = self.parser.tocleanstring(statustr.xpath('td')[1]) p.info = status p.status = p.STATUS_UNKNOWN p.history = [] for i, tr in enumerate(self.document.xpath('//div[@class="mainbloc4Evt"]//tr')): tds = tr.findall('td') try: if tds[0].attrib['class'] != "titrestatutdate2": continue except: continue ev = Event(i) ev.location = None ev.activity = self.parser.tocleanstring(tds[1]) if u"Votre colis a été expédié par votre webmarchand" in ev.activity: update_status(p, p.STATUS_PLANNED) elif ( u"Votre colis est pris en charge par Colis Privé" in ev.activity or u"Votre colis est arrivé sur notre agence régionale" in ev.activity or u"Votre colis est en cours de livraison" in ev.activity ): update_status(p, p.STATUS_IN_TRANSIT) elif u"Votre colis a été livré" in ev.activity: update_status(p, p.STATUS_ARRIVED) ev.date = date(*reversed([int(x) for x in self.parser.tocleanstring(tds[0]).split('/')])) p.history.append(ev) try: datelivre = self.document.xpath('//div[@class="NoInstNoRecla"]') clean = self.parser.tocleanstring(datelivre[0]) if "Votre colis a déja été livré" in clean: p.status = p.STATUS_ARRIVED except: pass return p
def get_info(self, _id): p = Parcel(_id) statustr = self.doc.xpath('//tr[@class="bandeauText"]')[0] status = statustr.xpath('td')[1].text p.info = status p.status = p.STATUS_UNKNOWN p.history = [] for i, tr in enumerate(self.doc.xpath('//table[@class="tableHistoriqueColis"]//tr[@class="bandeauText"]')): tds = tr.findall('td') try: if tds[0].attrib['class'] != "tdText": continue except: continue ev = Event(i) ev.location = None ev.activity = tds[1].text if u"Votre colis a été expédié par votre webmarchand" in ev.activity: update_status(p, p.STATUS_PLANNED) elif u"Votre colis est pris en charge par Colis Privé" in ev.activity: update_status(p, p.STATUS_IN_TRANSIT) elif u"Votre colis est arrivé sur notre agence régionale" in ev.activity: update_status(p, p.STATUS_IN_TRANSIT) elif u"Votre colis est en cours de livraison" in ev.activity: update_status(p, p.STATUS_IN_TRANSIT) elif u"Votre colis a été livré" in ev.activity: update_status(p, p.STATUS_ARRIVED) ev.date = date(*reversed([int(x) for x in tds[0].text.split('/')])) p.history.append(ev) try: datelivre = self.doc.xpath('//div[@class="NoInstNoRecla"]') clean = datelivre[0].text if "Votre colis a déja été livré" in clean: p.status = p.STATUS_ARRIVED except: pass return p
def get_parcel_tracking(self, _id): # 13 is the magic length of colissimo tracking ids if len(_id) != 13: raise ParcelNotFound(u"Colissimo ID's must have 13 print character") events = self.browser.get_tracking_info(_id) p = Parcel(_id) p.history = events first = events[0] p.info = first.activity if u"remis au gardien ou" in p.info or u"Votre colis est livré" in p.info: p.status = p.STATUS_ARRIVED elif u"pas encore pris en charge par La Poste" in p.info: p.status = p.STATUS_PLANNED else: p.status = p.STATUS_IN_TRANSIT return p
def get_info(self, id): if len( self.parser.tocleanstring( self.document.xpath('//p[@class="error"]')[0])) > 0: return None p = Parcel(id) for dl in self.document.xpath('//dl'): dt = dl.find('dt') dd = dl.find('dd') if dt is None or dd is None: continue label = self.parser.tocleanstring(dt) if label == 'Scheduled Delivery:': p.status = p.STATUS_IN_TRANSIT elif label == u'Delivered On:': p.status = p.STATUS_ARRIVED else: continue m = re.search('(\d+/\d+/\d+)', dd.text) if m: p.arrival = parse_date(m.group(1)) p.history = [] for i, tr in enumerate( self.document.xpath('//table[@class="dataTable"]//tr')): tds = tr.findall('td') if len(tds) < 4: continue ev = Event(i) ev.location = self.parser.tocleanstring(tds[0]) ev.activity = self.parser.tocleanstring(tds[-1]) ev.date = parse_date('%s %s' % (tds[1].text, tds[2].text)) p.history.append(ev) p.info = self.document.xpath('//a[@id="tt_spStatus"]')[0].text.strip() return p
def get_info(self, _id): shipments = self.doc["shipments"] if not shipments: raise ParcelNotFound("No such ID: %s" % _id) shipment = shipments[0] result_id = shipment["trackingCode"] if result_id != _id: raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id)) p = Parcel(_id) if shipment["estimatedDeliveryTime"]: p.arrival = parse_date(shipment["estimatedDeliveryTime"], ignoretz=True) events = shipment["events"] p.history = [ self.build_event(i, data) for i, data in enumerate(events) ] most_recent = p.history[0] p.status, p.info = self.guess_status(p.history) p.info = most_recent.activity return p
def get_parcel_tracking(self, _id): data = self.browser.get_tracking_info(_id) p = Parcel(_id) label = data['message'] if data['error']: p.info = label return p p.info = label # TODO, need to know the delivery message if u"remis au gardien ou" in label or u"Votre colis est livré" in label: p.status = p.STATUS_ARRIVED elif u"pas encore pris en charge par La Poste" in label: p.status = p.STATUS_PLANNED else: p.status = p.STATUS_IN_TRANSIT ev = Event(0) ev.activity = label ev.date = date(*reversed([int(x) for x in data['date'].split("/")])) p.history = [ev] return p
def get_info(self, id): if len(self.parser.tocleanstring(self.document.xpath('//p[@class="error"]')[0])) > 0: return None p = Parcel(id) for dl in self.document.xpath('//dl'): dt = dl.find('dt') dd = dl.find('dd') if dt is None or dd is None: continue label = self.parser.tocleanstring(dt) if label == 'Scheduled Delivery:': p.status = p.STATUS_IN_TRANSIT elif label == u'Delivered On:': p.status = p.STATUS_ARRIVED else: continue m = re.search('(\d+/\d+/\d+)', dd.text) if m: p.arrival = parse_date(m.group(1)) p.history = [] for i, tr in enumerate(self.document.xpath('//table[@class="dataTable"]//tr')): tds = tr.findall('td') if len(tds) < 4: continue ev = Event(i) ev.location = self.parser.tocleanstring(tds[0]) ev.activity = self.parser.tocleanstring(tds[-1]) ev.date = parse_date('%s %s' % (tds[1].text, tds[2].text)) p.history.append(ev) p.info = self.document.xpath('//a[@id="tt_spStatus"]')[0].text.strip() return p
def get_parcel_tracking(self, _id): # 13 is the magic length of colissimo tracking ids if len(_id) != 13: raise ParcelNotFound(u"Colissimo ID's must have 13 print character") data = self.browser.get_tracking_info(_id) p = Parcel(_id) label = data["message"] if data["error"]: raise ParcelNotFound(label + u" (id = %s@%s)" % (_id, self.name)) p.info = label # TODO, need to know the delivery message if u"remis au gardien ou" in label or u"Votre colis est livré" in label: p.status = p.STATUS_ARRIVED elif u"pas encore pris en charge par La Poste" in label: p.status = p.STATUS_PLANNED else: p.status = p.STATUS_IN_TRANSIT ev = Event(0) ev.activity = label ev.date = date(*reversed([int(x) for x in data["date"].split("/")])) p.history = [ev] return p
def get_parcel_tracking(self, _id): """ Get information about a parcel. :param _id: _id of the parcel :type _id: :class:`str` :rtype: :class:`Parcel` :raises: :class:`ParcelNotFound` """ # Tracking number format: # - 2 chars: optional merchant identifier (eg, AM for Amazon, 85 for cdiscount, ...) # - 10 digits: shipment tracking number # - 2 digits: optional suffix, seems to always be "01" when present but is never sent to the API # # Many merchants seem to give only the 10 digits tracking number so the user needs to # manually select the merchant from a list in that case. merchant = None code = None _id = _id.strip().upper() if len(_id) == 10: code = _id elif len(_id) in (12, 14): merchant = _id[:2] code = _id[2:12] else: raise ParcelNotFound( "Tracking number must be 10, 12 or 14 characters long." ) merchant = merchant or self.config['merchant'].get() if not merchant: # No merchant info in the tracking number # we have to ask the user to select it merchants = self.browser.get_merchants() raise BrowserQuestion(Value( 'merchant', label='Merchant prefix (prepend to tracking number): ', tiny=False, choices=merchants, )) self.config['merchant'].set(None) name = self.config['last_name'].get()[:4].ljust(4).upper() events = list(self.browser.iter_events(merchant, code, name)) parcel = Parcel(merchant + code) parcel.arrival = NotAvailable # This is what the legacy tracking website used to show # when there are no events yet parcel.info = "Votre commande est en cours d'acheminement dans notre réseau." parcel.history = events parcel.status = Parcel.STATUS_IN_TRANSIT if not events: parcel.status = Parcel.STATUS_PLANNED return parcel parcel.info = events[0].activity arrived_event = next((event for event in events if "Votre colis est disponible" in event.activity), None) if arrived_event: parcel.status = Parcel.STATUS_ARRIVED parcel.arrival = arrived_event.date return parcel
def get_parcel_tracking(self, _id): """ Get information about a parcel. :param _id: _id of the parcel :type _id: :class:`str` :rtype: :class:`Parcel` :raises: :class:`ParcelNotFound` """ # Tracking number format: # - 2 chars: optional merchant identifier (eg, AM for Amazon, 85 for cdiscount, ...) # - 10 digits: shipment tracking number # - 2 digits: optional suffix, seems to always be "01" when present but is never sent to the API # # Many merchants seem to give only the 10 digits tracking number so the user needs to # manually select the merchant from a list in that case. merchant = None code = None _id = _id.strip().upper() if len(_id) == 10: code = _id elif len(_id) in (12, 14): merchant = _id[:2] code = _id[2:12] else: raise ParcelNotFound( "Tracking number must be 10, 12 or 14 characters long.") merchant = merchant or self.config['merchant'].get() if not merchant: # No merchant info in the tracking number # we have to ask the user to select it merchants = self.browser.get_merchants() raise BrowserQuestion( Value( 'merchant', label='Merchant prefix (prepend to tracking number): ', tiny=False, choices=merchants, )) self.config['merchant'].set(None) name = self.config['last_name'].get()[:4].ljust(4).upper() events = list(self.browser.iter_events(merchant, code, name)) parcel = Parcel(merchant + code) parcel.arrival = NotAvailable # This is what the legacy tracking website used to show # when there are no events yet parcel.info = "Votre commande est en cours d'acheminement dans notre réseau." parcel.history = events parcel.status = Parcel.STATUS_IN_TRANSIT if not events: parcel.status = Parcel.STATUS_PLANNED return parcel parcel.info = events[0].activity arrived_event = next( (event for event in events if "Votre colis est disponible" in event.activity), None) if arrived_event: parcel.status = Parcel.STATUS_ARRIVED parcel.arrival = arrived_event.date return parcel