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 elif u"en cours d'acheminement" in p.history[0].activity or \ u"en cours de livraison" in p.history[0].activity or \ u"Envoi entré dans le pays de destination" in p.history[0].activity: p.status = p.STATUS_IN_TRANSIT 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): 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.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 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_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_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): 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): """ 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