def search_housings(self, query, cities): self.update_header() data = {} data['rubrique'] = TYPES.get(query.type) data['prix_max'] = query.cost_max or None data['surface_min'] = query.area_min or None if len(cities) > 1: data['rayon'] = None else: data['rayon'] = 100 data['CategorieMode'] = None data['CategorieMaison'] = None data['Kilometrage'] = None data['top'] = 50 data['order_by'] = 5 data['sort_order'] = 1 data['lstNbPieces'] = [query.nb_rooms or 0] data['pageNumber'] = 1 for city in cities: data['localisation'] = {} data['localisation']['localisationid'] = city.id data['localisation']['label'] = city.name data['localisation']['localisationType'] = 5 data['localisationType'] = 5 data['lstLocalisationId'] = str(city.id) for house_type in query.house_types: data['lstTbien'] = RET.get(house_type) for house in self.search_house.go(data=json.dumps(data)).iter_houses(): if (empty(query.cost_min) or house.cost >= query.cost_min) and \ (empty(query.area_max) or house.area <= query.area_max): yield house
def check_housing_lists(self, query): results = list(itertools.islice( self.backend.search_housings(query), 20 )) self.assertGreater(len(results), 0) for field in self.FIELDS_ANY_HOUSINGS_LIST: self.assertTrue( any(not empty(getattr(x, field)) for x in results), 'Missing a "%s" field.' % field ) for x in results: if 'type' in self.FIELDS_ALL_HOUSINGS_LIST: self.assertEqual(x.type, query.type) if 'advert_type' in self.FIELDS_ALL_HOUSINGS_LIST: self.assertIn(x.advert_type, query.advert_types) if 'house_type' in self.FIELDS_ALL_HOUSINGS_LIST: self.assertIn(x.house_type, query.house_types) for field in self.FIELDS_ALL_HOUSINGS_LIST: self.assertNotEmpty(x, field) if not empty(x.cost): self.assertNotEmpty(x, 'price_per_meter') for photo in x.photos: self.assertRegexpMatches(photo.url, r'^http(s?)://') return results
def format_obj(self, obj, alias): result = u'%s%s - %s%s\n' % (self.BOLD, obj.category, obj.summary, self.NC) result += u'Date: %s\n' % obj.start_date.strftime('%A %d %B %Y') result += u'Hour: %s - %s\n' % (obj.start_date.strftime('%H:%M'), obj.end_date.strftime('%H:%M')) if hasattr(obj, 'location') and not empty(obj.location): result += u'Location: %s\n' % obj.location if hasattr(obj, 'city') and not empty(obj.city): result += u'City: %s\n' % obj.city if hasattr(obj, 'event_planner') and not empty(obj.event_planner): result += u'Event planner: %s\n' % obj.event_planner if hasattr(obj, 'booked_entries') and not empty(obj.booked_entries) and \ hasattr(obj, 'max_entries') and not empty(obj.max_entries): result += u'Entry: %s/%s \n' % (obj.booked_entries, obj.max_entries) elif hasattr(obj, 'booked_entries') and not empty(obj.booked_entries): result += u'Entry: %s \n' % (obj.booked_entries) elif hasattr(obj, 'max_entries') and not empty(obj.max_entries): result += u'Max entries: %s \n' % (obj.max_entries) if hasattr(obj, 'description') and not empty(obj.description): result += u'Description:\n %s\n\n' % obj.description if hasattr(obj, 'price') and not empty(obj.price): result += u'Price: %i\n' % obj.price if hasattr(obj, 'url') and not empty(obj.url): result += u'url: %s\n' % obj.url return result
def get_description(self, obj): result = u'' if not empty(obj.preparation_time): result += 'prep time: %smin' % obj.preparation_time if not empty(obj.short_description): result += 'description: %s\n' % obj.short_description return result.strip()
def __init__(self, weboob, backend, torrent, parent=None): super(MiniTorrent, self).__init__(parent) self.parent = parent self.ui = Ui_MiniTorrent() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.torrent = torrent self.ui.nameLabel.setText(torrent.name) if not empty(torrent.seeders) and not empty(torrent.leechers): self.ui.seedLeechLabel.setText('%s/%s' % (torrent.seeders, torrent.leechers)) if not empty(torrent.size): self.ui.sizeLabel.setText(u'%s' % sizeof_fmt(torrent.size)) self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed)
def format_obj(self, obj, alias): label = obj.label if not empty(obj.diff): diff = obj.diff else: diff = obj.valuation - (obj.quantity * obj.unitprice) self.tot_diff += diff self.tot_valuation += obj.valuation format_quantity = '%11.2f' if obj.quantity._isinteger(): format_quantity = '%11d' if empty(obj.code) and not empty(obj.description): code = obj.description else: code = obj.code return u' %s %s %s %s %s %s' % \ (self.colored('%-30s' % label[:30], 'red'), self.colored('%-12s' % code[:12], 'yellow') if not empty(code) else ' ' * 12, self.colored(format_quantity % obj.quantity, 'yellow'), self.colored('%11.2f' % obj.unitvalue, 'yellow'), self.colored('%11.2f' % obj.valuation, 'yellow'), self.colored('%8.2f' % diff, 'green' if diff >= 0 else 'red') )
def gotThumbnail(self): if empty(self.movie.thumbnail_url) and self.movie.thumbnail_url != NotAvailable: self.backend.fill_movie(self.movie, ('thumbnail_url')) if not empty(self.movie.thumbnail_url): data = requests.get(self.movie.thumbnail_url).content img = QImage.fromData(data) self.ui.imageLabel.setPixmap(QPixmap.fromImage(img).scaledToHeight(100,Qt.SmoothTransformation))
def gotThumbnail(self): if empty(self.person.thumbnail_url) and self.person.thumbnail_url != NotAvailable: self.backend.fill_person(self.person, ('thumbnail_url')) if not empty(self.person.thumbnail_url): data = urllib.urlopen(self.person.thumbnail_url).read() img = QImage.fromData(data) self.ui.imageLabel.setPixmap(QPixmap.fromImage(img).scaledToHeight(100,Qt.SmoothTransformation))
def get_accounts(self): """ Fetch accounts data from Weboob. :param backend: The Weboob built backend to fetch data from. :returns: A list of dicts representing the available accounts. """ results = [] with self.backend: for account in list(self.backend.iter_accounts()): # The minimum dict keys for an account are : # 'id', 'label', 'balance' and 'type' # Retrieve extra information for the account. account = self.backend.fillobj(account, ['iban', 'currency']) iban = None if not empty(account.iban): iban = account.iban currency = None if not empty(account.currency): currency = unicode(account.currency) results.append({ 'vendorAccountId': account.id, 'label': account.label, 'balance': account.balance, 'iban': iban, 'currency': currency, 'type': account.type, }) return results
def __init__(self, subtitle, backend, parent=None): QFrame.__init__(self, parent) self.parent = parent self.backend = backend self.ui = Ui_Subtitle() self.ui.setupUi(self) self.connect(self.ui.downloadButton, SIGNAL("clicked()"), self.download) self.subtitle = subtitle self.ui.idEdit.setText(u'%s@%s' % (subtitle.id, backend.name)) self.ui.nameLabel.setText(u'%s' % subtitle.name) if not empty(subtitle.nb_cd): self.ui.nbcdLabel.setText(u'%s' % subtitle.nb_cd) else: self.ui.nbcdLabel.parent().hide() if not empty(subtitle.language): self.ui.langLabel.setText(u'%s' % subtitle.language) else: self.ui.langLabel.parent().hide() if not empty(subtitle.description): self.ui.descriptionPlain.setPlainText(u'%s' % subtitle.description) else: self.ui.descriptionPlain.parent().hide() if not empty(subtitle.url): self.ui.urlEdit.setText(u'%s' % subtitle.url) else: self.ui.downloadButton.setDisabled(True) self.ui.downloadButton.setText('Impossible to download this subtitle') self.ui.verticalLayout.setAlignment(Qt.AlignTop)
def format_obj(self, obj, alias): bank = obj.backend phones = "" contacts = [] if not empty(obj.phone): phones += obj.phone if not empty(obj.mobile): if phones != "": phones += " or %s" % obj.mobile else: phones += obj.mobile if phones: contacts.append(phones) for attr in ('email', 'agency', 'address'): value = getattr(obj, attr) if not empty(value): contacts.append(value) if len(contacts) > 0: first_contact = contacts.pop(0) else: first_contact = "" result = u" %s %s %s " % (self.colored('%-15s' % bank, 'yellow'), self.colored('%-30s' % obj.name, 'red'), self.colored("%-30s" % first_contact, 'green')) for contact in contacts: result += "\n %s %s" % ((" ") * 47, self.colored("%-25s" % contact, 'green')) return result
def _set_video_attrs(self, video): new_video = video_info(YoutubeVideo.id2url(video.id)) if not new_video: return for k, v in new_video.iter_fields(): if not empty(v) and empty(getattr(video, k)): setattr(video, k, v)
def order(self): if not self.shouldSkip(): order = Order(id=self.order_number()) order.date = self.order_date() order.tax = Decimal(self.tax()) if not empty(self.tax()) else Decimal(0.00) order.discount = Decimal(self.discount()) if not empty(self.discount()) else Decimal(0.00) order.shipping = Decimal(self.shipping()) if not empty(self.shipping()) else Decimal(0.00) order.total = Decimal(self.grand_total()) if not empty(self.grand_total()) else Decimal(0.00) return order
def transfer_check_account_iban(self, old, new): # Skip origin account iban check and force origin account iban if empty(new) or empty(old): self.logger.warning( 'Origin account iban check (%s) is not possible because iban is currently not available', old, ) return True return old == new
def get_description(self, obj): result = u"" if not empty(obj.start_date): result += u"\tDate: %s\n" % obj.start_date.strftime("%A %d %B %Y") result += u"\tHour: %s" % obj.start_date.strftime("%H:%M") if not empty(obj.end_date): result += " - %s" % obj.end_date.strftime("%H:%M") result += "\n" return result.strip("\n\t")
def get_title(self, obj): s = obj.type if hasattr(obj, 'price') and not empty(obj.price): s += u' %s %s' % (self.colored(u'—', 'cyan'), self.colored('%6.2f %s' % (obj.price, Currency.currency2txt(obj.currency)), 'green')) if hasattr(obj, 'late') and not empty(obj.late) and obj.late > datetime.time(): s += u' %s %s' % (self.colored(u'—', 'cyan'), self.colored('Late: %s' % obj.late, 'red', 'bold')) if hasattr(obj, 'information') and not empty(obj.information) and obj.information.strip() != '': s += u' %s %s' % (self.colored(u'—', 'cyan'), self.colored(obj.information, 'red')) return s
def get_description(self, obj): result = u'' if not empty(obj.start_date): result += u'\tDate: %s\n' % obj.start_date.strftime('%A %d %B %Y') result += u'\tHour: %s' % obj.start_date.strftime('%H:%M') if not empty(obj.end_date): result += ' - %s' % obj.end_date.strftime('%H:%M') result += '\n' return result.strip('\n\t')
def format_obj(self, obj, alias): result = u'BEGIN:VEVENT\r\n' utc_zone = tz.gettz('UTC') event_timezone = tz.gettz(obj.timezone) start_date = obj.start_date if not empty(obj.start_date) else datetime.now() if isinstance(start_date, datetime): start_date = start_date.replace(tzinfo=event_timezone) utc_start_date = start_date.astimezone(utc_zone) result += u'DTSTART:%s\r\n' % utc_start_date.strftime("%Y%m%dT%H%M%SZ") else: result += u'DTSTART:%s\r\n' % start_date.strftime("%Y%m%d") end_date = obj.end_date if not empty(obj.end_date) else datetime.combine(start_date, time.max) if isinstance(end_date, datetime): end_date = end_date.replace(tzinfo=event_timezone) utc_end_date = end_date.astimezone(utc_zone) result += u'DTEND:%s\r\n' % utc_end_date.strftime("%Y%m%dT%H%M%SZ") else: result += u'DTEND:%s\r\n' % end_date.strftime("%Y%m%d") result += u'SUMMARY:%s\r\n' % obj.summary result += u'UID:%s\r\n' % obj.id result += u'STATUS:%s\r\n' % obj.status location = '' if hasattr(obj, 'location') and not empty(obj.location): location += obj.location + ' ' if hasattr(obj, 'city') and not empty(obj.city): location += obj.city + ' ' if not empty(location): result += u'LOCATION:%s\r\n' % location if hasattr(obj, 'categories') and not empty(obj.categories): result += u'CATEGORIES:%s\r\n' % obj.categories if hasattr(obj, 'description') and not empty(obj.description): result += u'DESCRIPTION:%s\r\n' % obj.description.strip(' \t\n\r')\ .replace('\r', '')\ .replace('\n', r'\n')\ .replace(',', '\,') if hasattr(obj, 'transp') and not empty(obj.transp): result += u'TRANSP:%s\r\n' % obj.transp if hasattr(obj, 'sequence') and not empty(obj.sequence): result += u'SEQUENCE:%s\r\n' % obj.sequence if hasattr(obj, 'url') and not empty(obj.url): result += u'URL:%s\r\n' % obj.url result += u'END:VEVENT\r\n' return result
def get_description(self, obj): if empty(obj.duration) and empty(obj.date): return None result = '%s' % (obj.duration or obj.date) if hasattr(obj, 'author') and not empty(obj.author): result += u' - %s' % obj.author if hasattr(obj, 'rating') and not empty(obj.rating): result += u' (%s/%s)' % (obj.rating, obj.rating_max) return result
def format_obj(self, obj, alias): result = u"%s%s%s\n" % (self.BOLD, obj.name, self.NC) result += "ID: %s\n" % obj.fullid result += "URL: %s\n" % obj.url if not empty(obj.language): result += "LANG: %s\n" % obj.language if not empty(obj.nb_cd): result += "NB CD: %s\n" % obj.nb_cd result += "\n%sDescription%s\n" % (self.BOLD, self.NC) result += "%s" % obj.description return result
def format_obj(self, obj, alias): result = u'%s%s%s\n' % (self.BOLD, obj.name, self.NC) result += 'ID: %s\n' % obj.fullid result += 'URL: %s\n' % obj.url if not empty(obj.language): result += 'LANG: %s\n' % obj.language if not empty(obj.nb_cd): result += 'NB CD: %s\n' % obj.nb_cd result += '\n%sDescription%s\n' % (self.BOLD, self.NC) result += '%s' % obj.description return result
def get_description(self, obj): result = '' if hasattr(obj, 'description') and not empty(obj.description): result += '%-30s' % obj.description if hasattr(obj, 'current') and not empty(obj.current): if obj.current.who: result += ' (Current: %s - %s)' % (obj.current.who, obj.current.what) else: result += ' (Current: %s)' % obj.current.what return result
def get_description(self, obj): result = u'' if not empty(obj.start_date): result += u'\tDate: %s\n' % obj.start_date.strftime('%A %d %B %Y') result += u'\tHour: %s' % obj.start_date.strftime('%H:%M') if not empty(obj.end_date): result += ' - %s' % obj.end_date.strftime('%H:%M') days_diff = (obj.end_date - obj.start_date).days if days_diff >= 1: result += ' (%i day(s) later)' % (days_diff) result += '\n' return result.strip('\n\t')
def format_obj(self, obj, alias): name = obj.name city = u"" if not empty(obj.city): city = obj.city if not obj.sensors or (len(obj.sensors) == 0): result = u' %s %s %s \n' %\ (self.colored('%-27s' % name[:27], 'red'), self.colored('%-10s' % obj.object[:10], 'yellow'), self.colored('%-10s' % city[:10], 'yellow') ) result += u' %s \n' % self.colored('%-47s' % obj.fullid[:47], 'blue') else: first = True firstaddress = obj.sensors[0].address for sensor in obj.sensors: sensorname = sensor.name # This is a int value, do not display it as a float if not empty(sensor.lastvalue.level): if int(sensor.lastvalue.level) == sensor.lastvalue.level: lastvalue = "%d " % sensor.lastvalue.level else: lastvalue = "%r " % sensor.lastvalue.level if not empty(sensor.unit): lastvalue += "%s" % sensor.unit else: lastvalue = u"? " if first: result = u' %s %s %s ' %\ (self.colored('%-27s' % name[:27], 'red'), self.colored('%-10s' % obj.object[:10], 'yellow'), self.colored('%-10s' % city[:10], 'yellow'), ) if not empty(firstaddress): result += u'%s' % self.colored('%-33s' % sensor.address[:33], 'yellow') result += u'\n' result += u' %s' % self.colored('%-47s' % obj.fullid[:47], 'blue') result += u' %s %s\n' %\ (self.colored('%-20s' % sensorname[:20], 'magenta'), self.colored('%-13s' % lastvalue[:13], 'red') ) first = False else: result += u' %s %s\n' %\ (self.colored('%-20s' % sensorname[:20], 'magenta'), self.colored('%-13s' % lastvalue[:13], 'red') ) if not empty(sensor.address) and sensor.address != firstaddress: result += u' %s \n' %\ self.colored('%-33s' % sensor.address[:33], 'yellow') return result
def format_obj(self, obj, alias): result = ( u'%s* %-15s%s (%s - %s)' % ( self.BOLD, '%s:' % obj.date, self.NC, self.temperature_display(obj.low) if not empty(obj.low) else '?', self.temperature_display(obj.high) if not empty(obj.high) else '?' ) ) if hasattr(obj, 'text') and obj.text: result += ' %s' % obj.text return result
def format_obj(self, obj, alias): result = u'%s%s%s\n' % (self.BOLD, obj.name, self.NC) result += 'ID: %s\n' % obj.fullid if not empty(obj.real_name): result += 'Real name: %s\n' % obj.real_name if not empty(obj.birth_place): result += 'Birth place: %s\n' % obj.birth_place if not empty(obj.birth_date): result += 'Birth date: %s\n' % obj.birth_date.strftime('%Y-%m-%d') if not empty(obj.death_date): age = num_years(obj.birth_date, obj.death_date) result += 'Death date: %s at %s years old\n' % (obj.death_date.strftime('%Y-%m-%d'), age) else: age = num_years(obj.birth_date) result += 'Age: %s\n' % age if not empty(obj.gender): result += 'Gender: %s\n' % obj.gender if not empty(obj.nationality): result += 'Nationality: %s\n' % obj.nationality if not empty(obj.roles): result += '\n%sRelated movies%s\n' % (self.BOLD, self.NC) for role, lmovies in obj.roles.items(): result += ' -- %s\n' % role for movie in lmovies: result += ' * %s\n' % movie[1] if not empty(obj.short_biography): result += '\n%sShort biography%s\n' % (self.BOLD, self.NC) result += '%s' % obj.short_biography return result
def format_obj(self, obj, alias): result = u"BEGIN:VEVENT\n" result += u"DTSTART:%s\n" % obj.start_date.strftime("%Y%m%dT%H%M%SZ") result += u"DTEND:%s\n" % obj.end_date.strftime("%Y%m%dT%H%M%SZ") result += u"SUMMARY:%s\n" % obj.summary result += u"UID:%s\n" % obj.id result += u"STATUS:%s\n" % obj.status location = "" if hasattr(obj, "location") and not empty(obj.location): location += obj.location + " " if hasattr(obj, "city") and not empty(obj.city): location += obj.city + " " if not empty(location): result += u"LOCATION:%s\n" % location if hasattr(obj, "categories") and not empty(obj.categories): result += u"CATEGORIES:%s\n" % obj.categories if hasattr(obj, "description") and not empty(obj.description): result += u"DESCRIPTION:%s\n" % obj.description.replace("\r\n", "\\n").replace(",", "\,") if hasattr(obj, "transp") and not empty(obj.transp): result += u"TRANSP:%s\n" % obj.transp if hasattr(obj, "sequence") and not empty(obj.sequence): result += u"SEQUENCE:%s\n" % obj.sequence if hasattr(obj, "url") and not empty(obj.url): result += u"URL:%s\n" % obj.url result += u"END:VEVENT\n" return result
def format_obj(self, obj, alias): result = u"%s%s%s\n" % (self.BOLD, obj.name, self.NC) result += "ID: %s\n" % obj.fullid if not empty(obj.real_name): result += "Real name: %s\n" % obj.real_name if not empty(obj.birth_place): result += "Birth place: %s\n" % obj.birth_place if not empty(obj.birth_date): result += "Birth date: %s\n" % obj.birth_date.strftime("%Y-%m-%d") if not empty(obj.death_date): age = num_years(obj.birth_date, obj.death_date) result += "Death date: %s at %s years old\n" % (obj.death_date.strftime("%Y-%m-%d"), age) else: age = num_years(obj.birth_date) result += "Age: %s\n" % age if not empty(obj.gender): result += "Gender: %s\n" % obj.gender if not empty(obj.nationality): result += "Nationality: %s\n" % obj.nationality if not empty(obj.roles): result += "\n%sRelated movies%s\n" % (self.BOLD, self.NC) for role, lmovies in obj.roles.items(): result += " -- %s\n" % role for movie in lmovies: result += " * %s\n" % movie if not empty(obj.short_biography): result += "\n%sShort biography%s\n" % (self.BOLD, self.NC) result += "%s" % obj.short_biography return result
def format_obj(self, obj, alias): result = u"BEGIN:VEVENT\r\n" utc_zone = tz.gettz("UTC") event_timezone = tz.gettz(obj.timezone) start_date = obj.start_date if not empty(obj.start_date) else datetime.now() start_date = start_date.replace(tzinfo=event_timezone) utc_start_date = start_date.astimezone(utc_zone) result += u"DTSTART:%s\r\n" % utc_start_date.strftime("%Y%m%dT%H%M%SZ") end_date = obj.end_date if not empty(obj.end_date) else datetime.combine(start_date, time.max) end_date = end_date.replace(tzinfo=event_timezone) utc_end_date = end_date.astimezone(utc_zone) result += u"DTEND:%s\r\n" % utc_end_date.strftime("%Y%m%dT%H%M%SZ") result += u"SUMMARY:%s\r\n" % obj.summary result += u"UID:%s\r\n" % obj.id result += u"STATUS:%s\r\n" % obj.status location = "" if hasattr(obj, "location") and not empty(obj.location): location += obj.location + " " if hasattr(obj, "city") and not empty(obj.city): location += obj.city + " " if not empty(location): result += u"LOCATION:%s\r\n" % location if hasattr(obj, "categories") and not empty(obj.categories): result += u"CATEGORIES:%s\r\n" % obj.categories if hasattr(obj, "description") and not empty(obj.description): result += u"DESCRIPTION:%s\r\n" % obj.description.strip(" \t\n\r").replace("\r", "").replace( "\n", r"\n" ).replace(",", "\,") if hasattr(obj, "transp") and not empty(obj.transp): result += u"TRANSP:%s\r\n" % obj.transp if hasattr(obj, "sequence") and not empty(obj.sequence): result += u"SEQUENCE:%s\r\n" % obj.sequence if hasattr(obj, "url") and not empty(obj.url): result += u"URL:%s\r\n" % obj.url result += u"END:VEVENT\r\n" return result
def __init__(self, weboob, backend, torrent, parent=None): QFrame.__init__(self, parent) self.parent = parent self.ui = Ui_MiniTorrent() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.torrent = torrent self.ui.nameLabel.setText(torrent.name) if not empty(torrent.seeders) and not empty(torrent.leechers): self.ui.seedLeechLabel.setText('%s/%s' % (torrent.seeders, torrent.leechers)) if not empty(torrent.size): self.ui.sizeLabel.setText(u'%s' % sizeof_fmt(torrent.size)) self.ui.backendLabel.setText(backend.name)
def format_obj(self, obj, alias): if obj.type != 0: result = u'<STMTTRN><TRNTYPE>%s\n' % self.TYPES_TRANS[obj.type] else: result = u'<STMTTRN><TRNTYPE>%s\n' % ('DEBIT' if obj.amount < 0 else 'CREDIT') result += u'<DTPOSTED>%s\n' % obj.date.strftime('%Y%m%d') result += u'<TRNAMT>%s\n' % obj.amount result += u'<FITID>%s\n' % obj.unique_id() if hasattr(obj, 'label') and not empty(obj.label): result += u'<NAME>%s</STMTTRN>' % obj.label.replace('&', '&') else: result += u'<NAME>%s</STMTTRN>' % obj.raw.replace('&', '&') return result
def obj_coming(self): comings = (CleanDecimal(TableCell('balance', default=None), replace_dots=True, default=None)(self), CleanDecimal(TableCell('_credit', default=None), replace_dots=True, default=None)(self), CleanDecimal(TableCell('_debit', default=None), replace_dots=True, default=None)(self)) for coming in comings: if not empty(coming): return coming else: # There should have at least 0.00 in debit column assert False
def __init__(self, torrent, backend, parent=None): super(Torrent, self).__init__(parent) self.parent = parent self.backend = backend self.ui = Ui_Torrent() self.ui.setupUi(self) self.ui.downloadButton.clicked.connect(self.download) self.torrent = torrent self.ui.idEdit.setText(u'%s@%s' % (torrent.id, backend.name)) self.ui.nameLabel.setText(u'%s' % torrent.name) if not empty(torrent.url): self.ui.urlEdit.setText(u'%s' % torrent.url) else: self.ui.urlFrame.hide() self.ui.downloadButton.setDisabled(True) if not empty(torrent.magnet): self.ui.downloadButton.setText( u'Download not available\nbut magnet link provided') self.ui.downloadButton.setToolTip(u'Use the magnet link') if not empty(torrent.description): self.ui.descriptionPlain.setText(u'%s' % torrent.description) else: self.ui.descriptionPlain.parent().hide() if not empty(torrent.files): files = u'' for f in torrent.files: files += '%s\n' % f self.ui.filesPlain.setText(u'%s' % files) else: self.ui.filesPlain.parent().hide() if not empty(torrent.magnet): self.ui.magnetEdit.setText(u'%s' % torrent.magnet) else: self.ui.magnetFrame.hide() if not empty(torrent.seeders) and not empty(torrent.leechers): self.ui.seedLeechLabel.setText(u'%s/%s' % (torrent.seeders, torrent.leechers)) if not empty(torrent.size): self.ui.sizeLabel.setText(u'%s' % sizeof_fmt(torrent.size)) self.ui.verticalLayout.setAlignment(Qt.AlignTop)
def populate(self, accounts): cards = [] for account in accounts: for li in self.doc.xpath('//li[@class="nav-category"]'): title = CleanText().filter(li.xpath('./h3')) for a in li.xpath('./ul/li//a'): label = CleanText().filter( a.xpath('.//span[@class="nav-category__name"]')) balance_el = a.xpath( './/span[@class="nav-category__value"]') balance = CleanDecimal( replace_dots=True, default=NotAvailable).filter(balance_el) if 'CARTE' in label and not empty(balance): acc = Account() acc.balance = balance acc.label = label acc.currency = FrenchTransaction.Currency().filter( balance_el) acc.url = urljoin(self.url, Link().filter(a.xpath('.'))) acc._history_page = acc.url try: acc.id = acc._webid = Regexp( pattern='carte/(.*)$').filter(Link().filter( a.xpath('.'))) except RegexpError: # Those are external cards, ie: amex cards continue acc.type = Account.TYPE_CARD if not acc in cards: cards.append(acc) elif account.label == label and account.balance == balance: if not account.type: account.type = AccountsPage.ACCOUNT_TYPES.get( title, Account.TYPE_UNKNOWN) account._webid = Attr( None, 'data-account-label').filter( a.xpath( './/span[@class="nav-category__name"]')) if cards: self.browser.go_cards_number(cards[0].url) if self.browser.cards.is_here(): self.browser.page.populate_cards_number(cards) accounts.extend(cards)
def filter(self, text): if empty(text): return self.default_or_raise(ParseError('Unable to parse %r' % text)) original_text = text = super(CleanDecimal, self).filter(text) if self.replace_dots: if type(self.replace_dots) is tuple: thousands_sep, decimal_sep = self.replace_dots else: thousands_sep, decimal_sep = '.', ',' text = text.replace(thousands_sep, '').replace(decimal_sep, '.') try: v = Decimal(re.sub(r'[^\d\-\.]', '', text)) if self.sign: v *= self.sign(original_text) return v except InvalidOperation as e: return self.default_or_raise(e)
def format_obj(self, obj, alias): if hasattr(obj, 'category') and obj.category: _type = obj.category else: try: _type = self.TYPES[obj.type] except (IndexError, AttributeError): _type = '' label = obj.label if not label and hasattr(obj, 'raw'): label = obj.raw date = obj.date.strftime('%Y-%m-%d') if not empty(obj.date) else '' amount = obj.amount or Decimal('0') return ' %s %s %s %s' % (self.colored('%-10s' % date, 'blue'), self.colored('%-12s' % _type[:12], 'magenta'), self.colored('%-50s' % label[:50], 'yellow'), self.colored('%10.2f' % amount, 'green' if amount >= 0 else 'red'))
def format_obj(self, obj, alias): if alias is not None: id = '%s (%s)' % (self.colored('%3s' % ('#' + alias), 'red', 'bold'), self.colored(obj.backend, 'blue', 'bold')) clean = '#%s (%s)' % (alias, obj.backend) if len(clean) < 15: id += (' ' * (15 - len(clean))) else: id = self.colored('%30s' % obj.fullid, 'red', 'bold') status, status_color = STATUS[obj.status] arrival = obj.arrival.strftime('%Y-%m-%d') if not empty(obj.arrival) else '' result = u'%s %s %s %s %s' % (id, self.colored(u'—', 'cyan'), self.colored('%-10s' % status, status_color), self.colored('%-10s' % arrival, 'blue'), self.colored('%-20s' % obj.info, 'yellow')) return result
def ownership_guesser(self): profile = self.get_profile() psu_names = profile.name.lower().split() for account in self.accounts_list: label = account.label.lower() # We try to find "M ou Mme" or "Mlle XXX ou M XXXX" for example (non-exhaustive exemple list) if re.search(r'.* ((m) ([\w].*|ou )?(m[ml]e)|(m[ml]e) ([\w].*|ou )(m) ).*', label): account.ownership = AccountOwnership.CO_OWNER # We check if the PSU firstname and lastname is in the account label elif all(name in label.split() for name in psu_names): account.ownership = AccountOwnership.OWNER # Card Accounts should be set with the same ownership of their parents for account in self.accounts_list: if account.type == Account.TYPE_CARD and not empty(account.parent): account.ownership = account.parent.ownership
def iter_accounts(self): ''' Each perimeter has 3 accounts pages: Regular, Wealth/Savings and Loans. We must handle two different perimeter cases: - Unique perimeter: we already are on the accounts page, simply return the unique perimeter accounts. - Multiple perimeters: visit all perimeters one by one and return all accounts. ''' accounts_list = [] # Sometimes the URL of the page after login has a session_value=None, # so we must set it correctly otherwise the next requests will crash. if not self.session_value: m = re.search(r'sessionSAG=([^&]+)', self.url) if m: self.session_value = m.group(1) if len(self.perimeters) == 1: self.accounts.stay_or_go() for account in self.iter_perimeter_accounts(iban=True, all_accounts=True): account._perimeter = 'main' accounts_list.append(account) else: for perimeter in self.perimeters: # Ignore perimeters with empty labels, they are unaccessible even on the website if perimeter: self.go_to_perimeter(perimeter) for account in self.iter_perimeter_accounts( iban=True, all_accounts=True): account._perimeter = perimeter accounts_list.append(account) # Do not return accounts with empty balances or invalid IDs valid_accounts = [] for account in accounts_list: if empty(account.balance): self.logger.warning( 'Account %s %s will be skipped because it has no balance.', account.label, account.id) else: valid_accounts.append(account) return valid_accounts
def get_account(self): json = self._auth() account = Account(id=Dict('id')(json)) account.number = account.id # weboob.capabilities.bank.BaseAccount account.bank_name = 'Lunchr' account.type = Account.TYPE_CHECKING # Check if account have a card balance = Dict('meal_voucher_info/balance/value', default=None)(json) if empty(balance): return account.balance = CleanDecimal.SI(balance)(json) account.label = Format('%s %s', CleanText(Dict('first_name')), CleanText(Dict('last_name')))(json) account.currency = Currency(Dict('meal_voucher_info/balance/currency/iso_3'))(json) account.cardlimit = CleanDecimal.SI(Dict('meal_voucher_info/daily_balance/value'))(json) yield account
def format_obj(self, obj, alias): # special case of coming operations with card ID if hasattr(obj, '_coming') and obj._coming and hasattr(obj, 'obj._cardid') and not empty(obj._cardid): result = u'<STMTTRN><TRNTYPE>%s\n' % obj._cardid elif obj.type != 0: result = u'<STMTTRN><TRNTYPE>%s\n' % self.TYPES_TRANS[obj.type] else: result = u'<STMTTRN><TRNTYPE>%s\n' % ('DEBIT' if obj.amount < 0 else 'CREDIT') result += u'<DTPOSTED>%s\n' % obj.date.strftime('%Y%m%d') result += u'<TRNAMT>%s\n' % obj.amount result += u'<FITID>%s\n' % obj.unique_id() if hasattr(obj, 'label') and not empty(obj.label): result += u'<NAME>%s</STMTTRN>' % obj.label.replace('&', '&') else: result += u'<NAME>%s</STMTTRN>' % obj.raw.replace('&', '&') return result
def do_show(self, arg): """ show MESSAGE Read a message """ message = None if len(arg) == 0: print('Please give a message ID.', file=self.stderr) return 2 try: message = self.messages[int(arg) - 1] except (IndexError, ValueError): # The message is not is the cache, we have now two cases: # 1) the user uses a number to get a thread in the cache # 2) the user gives a thread id try: thread = self.threads[int(arg) - 1] if not empty(thread.root): message = thread.root else: for thread in self.do('get_thread', thread.id, backends=thread.backend): if thread is not None: message = thread.root except (IndexError, ValueError): _id, backend_name = self.parse_id(arg) for thread in self.do('get_thread', _id, backends=backend_name): if thread is not None: message = thread.root if message is not None: self.start_format() self.format(message) self.weboob.do('set_message_read', message, backends=message.backend) return else: print('Message not found', file=self.stderr) return 3
def get_description(self, obj): if empty(obj.duration) and empty(obj.date): return None result = '%s' % (obj.duration or obj.date) if hasattr(obj, 'author') and not empty(obj.author): result += u' - %s' % obj.author if hasattr(obj, 'rating') and not empty(obj.rating): result += u' (%s/%s)' % (obj.rating, obj.rating_max) if hasattr(obj, 'thumbnail') and not empty(obj.thumbnail) and not empty(obj.thumbnail.data): result += u'\n' result += image2xterm(BytesIO(obj.thumbnail.data), newsize=get_term_size()) return result
def test_basic_search(self): q = Query() q.city = 'paris' event = None for n, event in enumerate(self.backend.search_events(q)): assert event.summary assert event.description assert event.start_date assert event.end_date assert event.start_date <= event.end_date assert event.city assert event.location assert not empty(event.price) assert event.category if n == 9: break else: assert False, 'not enough events'
def test_find_any_issues(self): projects = list(self.backend.iter_projects()) self.assertTrue(projects) q = Query() q.project = projects[0] issues = [ issue for issue, _ in zip(self.backend.iter_issues(q), range(30)) ] self.assertTrue(issues) for issue in issues: self.assertTrue(issue.project) self.assertEquals(issue.project.id, projects[0].id) self.assertTrue(issue.title) self.assertFalse(empty(issue.body)) self.assertTrue(issue.creation) self.assertTrue(issue.author, issue.title)
def check_single_housing_all(self, housing, type, house_types, advert_type): for field in self.FIELDS_ALL_SINGLE_HOUSING: self.assertNotEmpty(housing, field) if 'type' in self.FIELDS_ALL_SINGLE_HOUSING: if ( self.DO_NOT_DISTINGUISH_FURNISHED_RENT and type in [POSTS_TYPES.RENT, POSTS_TYPES.FURNISHED_RENT] ): self.assertIn(housing.type, [POSTS_TYPES.RENT, POSTS_TYPES.FURNISHED_RENT]) else: self.assertEqual(housing.type, type) if 'house_type' in self.FIELDS_ALL_SINGLE_HOUSING: if not empty(house_types): self.assertEqual(housing.house_type, house_types) else: self.assertNotEmpty(housing, 'house_type') if 'advert_type' in self.FIELDS_ALL_SINGLE_HOUSING: self.assertEqual(housing.advert_type, advert_type)
def filter(self, text): if type(text) in (float, int, long): text = str(text) if empty(text): return self.default_or_raise(FormatError('Unable to parse %r' % text)) original_text = text = super(CleanDecimal, self).filter(text) if self.legacy: if self.replace_dots: if type(self.replace_dots) is tuple: thousands_sep, decimal_sep = self.replace_dots else: thousands_sep, decimal_sep = '.', ',' text = text.replace(thousands_sep, '').replace(decimal_sep, '.') text = re.sub(r'[^\d\-\.]', '', text) else: thousands_sep, decimal_sep = self.replace_dots matches = self.matching.findall(text) if not matches: return self.default_or_raise(NumberFormatError('There is no number to parse')) elif len(matches) > 1: return self.default_or_raise(NumberFormatError('There should be exactly one number to parse')) text = '%s%s' % (matches[0][0], matches[0][1].strip()) if thousands_sep and thousands_sep in text and not self.thousand_check.match(text): return self.default_or_raise(NumberFormatError('Thousands separator is misplaced in %r' % text)) text = text.replace(thousands_sep, '').replace(decimal_sep, '.') try: v = Decimal(text) if self.sign: v *= self.sign(original_text) return v except InvalidOperation as e: return self.default_or_raise(NumberFormatError(e))
def iter_accounts(self): if self.accounts is None: owner_name = self.get_profile().name.upper().split(' ', 1)[1] self.home.go() accounts = list(self.page.iter_accounts(name=owner_name)) if self.page.RIB_AVAILABLE: self.rib.go().populate_rib(accounts) self.accounts = [] for account in accounts: self.accounts.append(account) if account.type == Account.TYPE_CHECKING: self.card_page.go(account=account.id) if self.page.has_no_card(): continue cards = self.page.get_cards(account.id) account._cards = cards if cards: self.location(account.url.replace('operations', 'encoursCarte') + '/0') indexes = dict(self.page.get_card_indexes()) for card in cards: # if there's a credit card (not debit), create a separate, virtual account card.url = account.url card.parent = account card.currency = account.currency card._checking_account = account card._index = indexes[card.number] self.location(account.url.replace('operations', 'encoursCarte') + '/%s' % card._index) if self.page.get_debit_date().month == (datetime.date.today() + relativedelta(months=1)).month: self.location(account.url.replace('operations', 'encoursCarte') + '/%s?month=1' % card._index) card.balance = 0 card.coming = self.page.get_balance() assert not empty(card.coming) # insert it near its companion checking account self.accounts.append(card) return iter(self.accounts)
def do_download(self, line): """ download ID [FILENAME] Get the subtitle or archive file. FILENAME is where to write the file. If FILENAME is '-', the file is written to stdout. """ id, dest = self.parse_command_args(line, 2, 1) subtitle = self.get_object(id, 'get_subtitle') if not subtitle: print('Subtitle not found: %s' % id, file=self.stderr) return 3 if dest is None: ext = subtitle.ext if empty(ext): ext = 'zip' dest = '%s.%s' % (subtitle.name, ext) for buf in self.do('get_subtitle_file', subtitle.id, backends=subtitle.backend): if buf: if dest == '-': if sys.version_info.major >= 3: self.stdout.buffer.write(buf) else: self.stdout.stream.write(buf) else: try: with open(dest, 'wb') as f: f.write(buf) except IOError as e: print('Unable to write file in "%s": %s' % (dest, e), file=self.stderr) return 1 else: print('Saved to %s' % dest) return
def __init__(self, weboob, backend, recipe, parent=None): QFrame.__init__(self, parent) self.parent = parent self.ui = Ui_MiniRecipe() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.recipe = recipe self.ui.titleLabel.setText(recipe.title) if not empty(recipe.short_description): if len(recipe.short_description) > 300: self.ui.shortDescLabel.setText('%s [...]' % recipe.short_description[:300]) else: self.ui.shortDescLabel.setText(recipe.short_description) else: self.ui.shortDescLabel.setText('') self.ui.backendLabel.setText(backend.name) self.gotThumbnail()
def format_obj(self, obj, alias): result = u'%s %s %s %s %s\n' % ( self.colored(obj.project.name, 'blue', 'bold'), self.colored(u'—', 'cyan', 'bold'), self.colored(obj.fullid, 'red', 'bold'), self.colored(u'—', 'cyan', 'bold'), self.colored(obj.title, 'yellow', 'bold')) result += '\n%s\n\n' % obj.body result += self.format_key('Author', '%s (%s)' % (obj.author.name, obj.creation)) result += self.format_attr(obj, 'status') result += self.format_attr(obj, 'priority') result += self.format_attr(obj, 'version') result += self.format_attr(obj, 'tracker') result += self.format_attr(obj, 'category') result += self.format_attr(obj, 'assignee') if hasattr(obj, 'fields') and not empty(obj.fields): for key, value in obj.fields.items(): result += self.format_key(key.capitalize(), value) if hasattr(obj, 'attachments') and obj.attachments: result += '\n%s\n' % self.colored('Attachments:', 'green') for a in obj.attachments: result += '* %s%s%s <%s>\n' % (self.BOLD, a.filename, self.NC, a.url) if hasattr(obj, 'history') and obj.history: result += '\n%s\n' % self.colored('History:', 'green') for u in obj.history: result += '%s %s %s %s\n' % ( self.colored('*', 'red', 'bold'), self.colored(u.date, 'yellow', 'bold'), self.colored(u'—', 'cyan', 'bold'), self.colored(u.author.name, 'blue', 'bold')) for change in u.changes: result += ' - %s %s %s %s\n' % ( self.colored(change.field, 'green'), change.last, self.colored('->', 'magenta'), change.new) if u.message: result += ' %s\n' % html2text( u.message).strip().replace('\n', '\n ') return result
def __init__(self, weboob, backend, person, parent=None): QFrame.__init__(self, parent) self.parent = parent self.ui = Ui_MiniPerson() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.person = person self.ui.nameLabel.setText('%s' % person.name) if not empty(person.short_description): if unicode(self.parent.ui.currentActionLabel.text()).startswith( 'Casting'): self.ui.shortDescTitleLabel.setText(u'Role') self.ui.shortDescLabel.setText('%s' % person.short_description) else: self.ui.shortDescTitleLabel.hide() self.ui.shortDescLabel.hide() self.ui.backendLabel.setText(backend.name) if self.parent.parent.ui.showTCheck.isChecked(): self.gotThumbnail()
def post_issue(self, issue): data = {} if issue.title: data['name'] = issue.title if issue.body: data['notes'] = issue.body if issue.due: data['due_at'] = issue.due.strftime('%Y-%m-%d') if issue.assignee: data['assignee'] = issue.assignee.id if issue.id and issue.id != '0': data['projects'] = issue._project self.browser.request('tasks', data=data) if issue.tags: self._set_tag_list(issue, True) else: self.browser.request('tasks/%s' % issue.id, data=data, method='PUT') if not empty(issue.tags): self._set_tag_list(issue)
def iter_history(self, account): if empty(account.url): # An account should always have a link to the details raise NotImplementedError() try: self.location(account.url) except BrowserHTTPError: self.logger.warning('Could not get the history for account %s', account.id) return history_link = self.page.get_history_link() if not history_link: # accounts don't always have an history_link raise NotImplementedError() self.location(history_link) assert self.history.is_here() result = [] result.extend(self.page.iter_versements()) result.extend(self.page.iter_arbitrages()) return sorted_transactions(result)
def iter_accounts(self): if self.accounts is None: self.home.stay_or_go() accounts = list(self.page.iter_accounts()) if self.page.RIB_AVAILABLE: self.rib.go().populate_rib(accounts) self.accounts = [] for account in accounts: self.accounts.append(account) if account.type == Account.TYPE_CHECKING: self.card_page.go(account=account.id) cards = self.page.get_cards(account.id) account._cards = cards if cards: self.location( account.url.replace('tableauDeBord', 'encoursCarte') + '/0') indexes = dict(self.page.get_card_indexes()) for card in cards: # if there's a credit card (not debit), create a separate, virtual account card.url = account.url card.currency = account.currency card._checking_account = account card._index = indexes[card.number] self.location( account.url.replace('tableauDeBord', 'encoursCarte') + '/%s' % card._index) card.balance = self.page.get_balance() assert not empty(card.balance) # insert it near its companion checking account self.accounts.append(card) return iter(self.accounts)
def format_obj(self, obj, alias): label = obj.label if not empty(obj.diff): diff = obj.diff elif not empty(obj.quantity) and not empty(obj.unitprice): diff = obj.valuation - (obj.quantity * obj.unitprice) else: diff = '---' format_diff = '%8s' if isinstance(diff, Decimal): format_diff = '%8.2f' self.tot_diff += diff if not empty(obj.quantity): quantity = obj.quantity format_quantity = '%11.2f' if obj.quantity == obj.quantity.to_integral(): format_quantity = '%11d' else: format_quantity = '%11s' quantity = '---' unitvalue, format_unitvalue = self.check_emptyness(obj.unitvalue) valuation, format_valuation = self.check_emptyness(obj.valuation) if isinstance(valuation, Decimal): self.tot_valuation += obj.valuation if empty(obj.code) and not empty(obj.description): code = obj.description else: code = obj.code return u' %s %s %s %s %s %s' % \ (self.colored('%-30s' % label[:30], 'red'), self.colored('%-12s' % code[:12], 'yellow') if not empty(code) else ' ' * 12, self.colored(format_quantity % quantity, 'yellow'), self.colored(format_unitvalue % unitvalue, 'yellow'), self.colored(format_valuation % valuation, 'yellow'), self.colored(format_diff % diff, 'green' if not isinstance(diff, str) and diff >= 0 else 'red') )
def filter(self, txt): if empty(txt) or txt == '': return self.default_or_raise( FormatError('Unable to parse %r' % txt)) try: if self.translations: for search, repl in self.translations: txt = search.sub(repl, txt) if self.strict: parse1 = self.parse_func(txt, default=self._default_date_1, **self.kwargs) parse2 = self.parse_func(txt, default=self._default_date_2, **self.kwargs) if parse1 != parse2: raise FilterError('Date is not complete') return parse1 else: return self.parse_func(txt, **self.kwargs) except (ValueError, TypeError) as e: return self.default_or_raise( FormatError('Unable to parse %r: %s' % (txt, e)))
def __init__(self, weboob, backend, subtitle, parent=None): super(MiniSubtitle, self).__init__(parent) self.parent = parent self.ui = Ui_MiniSubtitle() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.subtitle = subtitle self.ui.nameLabel.setText(subtitle.name) if not empty(subtitle.nb_cd): self.ui.nbcdLabel.setText(u'%s' % subtitle.nb_cd) self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed)
def do_releases(self, line): """ releases movie_ID [COUNTRY] Get releases dates of a movie. If COUNTRY is given, show release in this country. """ id, country = self.parse_command_args(line, 2, 1) movie = self.get_object(id, 'get_movie', ('original_title'), caps=CapCinema) if not movie: print('Movie not found: %s' % id, file=self.stderr) return 3 # i would like to clarify with fillobj but how could i fill the movie AND choose the country ? for release in self.do('get_movie_releases', movie.id, country, caps=CapCinema, backends=movie.backend): if not empty(release): movie.all_release_dates = u'%s' % (release) else: print('Movie releases not found for %s' % movie.original_title, file=self.stderr) return 3 self.start_format() self.format(movie)
def iter_accounts(self): ''' Each perimeter has 3 accounts pages: Regular, Wealth/Savings and Loans. We must handle two different perimeter cases: - Unique perimeter: we already are on the accounts page, simply return the unique perimeter accounts. - Multiple perimeters: visit all perimeters one by one and return all accounts. ''' accounts_list = [] if len(self.perimeters) == 1: self.accounts.stay_or_go(session_value=self.session_value) for account in self.iter_perimeter_accounts(iban=True, all_accounts=True): account._perimeter = 'main' accounts_list.append(account) else: for perimeter in self.perimeters: # Ignore perimeters with empty labels, they are unaccessible even on the website if perimeter: self.go_to_perimeter(perimeter) for account in self.iter_perimeter_accounts( iban=True, all_accounts=True): account._perimeter = perimeter accounts_list.append(account) # Do not return accounts with empty balances or invalid IDs valid_accounts = [] for account in accounts_list: if empty(account.balance): self.logger.warning( 'Account %s %s will be skipped because it has no balance.', account.label, account.id) else: valid_accounts.append(account) return valid_accounts