def image256_to_ansi(im, halfblocks): """Print PIL image `im` to `fd` using XTerm escape codes. 1 pixel corresponds to exactly 1 character on the terminal. 1 row of pixels is terminated by a newline. `im` has to be a 256 colors image (ideally in the XTerm palette if you want it to make sense). `im` should be resized appropriately to fit terminal size and character aspect (characters are never square). """ buf = [] pix = im.load() w, h = im.size if halfblocks: yrange = range(0, h, 2) else: yrange = range(h) for y in yrange: for x in range(w): if halfblocks: if y + 1 >= h: buf.append(u'\x1b[38;5;%dm\u2580' % pix[x, y]) else: buf.append(u'\x1b[38;5;%dm\x1b[48;5;%dm\u2580' % (pix[x, y], pix[x, y + 1])) else: buf.append(u'\x1b[48;5;%dm ' % pix[x, y]) buf.append(u'\x1b[0m%s' % os.linesep) return ''.join(buf)
def toggleChecks(self): allck = all( self.mdl.index(n, 0, QModelIndex()).data(Qt.CheckStateRole) == Qt.Checked for n in range(self.mdl.rowCount(QModelIndex()))) new = Qt.Unchecked if allck else Qt.Checked for n in range(self.mdl.rowCount(QModelIndex())): self.mdl.setData(self.mdl.index(n, 0, QModelIndex()), new, Qt.CheckStateRole)
def get_formatted_table(self): if len(self.queue) == 0: return if self.interactive: # Insert indices at the beginning of each line self.keys.insert(0, '#') for i in range(len(self.queue)): self.queue[i].insert(0, i + 1) queue = [() for i in range(len(self.queue))] column_headers = [] # Do not display columns when all values are NotLoaded or NotAvailable maxrow = 0 for i in range(len(self.keys)): available = False for line in self.queue: if len(line) > i and not empty(line[i]): maxrow += 1 available = True break if available: column_headers.append(self.keys[i].capitalize().replace( '_', ' ')) for j in range(len(self.queue)): if len(self.queue[j]) > i: queue[j] += (self.queue[j][i], ) s = '' if self.display_header and self.header: if self.HTML: s += '<p>%s</p>' % self.header else: s += self.header s += "\n" table = PrettyTable(list(column_headers)) for column_header in column_headers: # API changed in python-prettytable. The try/except is a bad hack to support both versions # Note: two versions are not exactly the same... # (first one: header in center. Second one: left align for header too) try: table.set_field_align(column_header, 'l') except: table.align[column_header] = 'l' for line in queue: for _ in range(maxrow - len(line)): line += ('', ) table.add_row([self.format_cell(cell) for cell in line]) if self.HTML: s += table.get_html_string() else: s += table.get_string() self.queue = [] return s
def get_formatted_table(self): if len(self.queue) == 0: return queue = [() for i in range(len(self.queue))] column_headers = [] # Do not display columns when all values are NotLoaded or NotAvailable maxrow = 0 for i in range(len(self.keys)): available = False for line in self.queue: if len(line)> i and not empty(line[i]): maxrow += 1 available = True break if available: column_headers.append(self.keys[i].capitalize().replace('_', ' ')) for j in range(len(self.queue)): if len(self.queue[j]) > i: queue[j] += (self.queue[j][i],) s = '' if self.display_header and self.header: if self.HTML: s += '<p>%s</p>' % self.header else: s += self.header s += "\n" table = PrettyTable(list(column_headers)) for column_header in column_headers: # API changed in python-prettytable. The try/except is a bad hack to support both versions # Note: two versions are not exactly the same... # (first one: header in center. Second one: left align for header too) try: table.set_field_align(column_header, 'l') except: table.align[column_header] = 'l' for line in queue: for _ in range(maxrow - len(line)): line += ('',) table.add_row(line) if self.HTML: s += table.get_html_string() else: s += table.get_string() self.queue = [] return s
def make256xterm(): """Return a [r, g, b, r, g, b, ...] table with the colors of the 256 xterm colors. The table is indexed: [0:3] corresponds to color 0. """ color256 = [] # standard 16 colors color256 += list( sum((PILColor.getrgb(c) for c in '''black maroon green olive navy purple teal silver gray red lime yellow blue fuchsia aqua white'''.split()), ())) steps = (0, 95, 135, 175, 215, 255) for r in steps: for g in steps: for b in steps: color256 += [r, g, b] # grays for v in range(8, 248, 10): color256 += [v, v, v] assert len(color256) == 256 * 3 return color256
def iter_images(self, gallery): page = 0 index = 0 empty = 0 for page in range(1000): if page == 1: continue # page 1 doesn't exist, don't ask why self.main.go(page=page) empty += 1 for url in self.page.get_content(): img = BaseImage(url, index=index, gallery=gallery) img.url = url yield img index += 1 empty = 0 if empty > 10: self.logger.warning("10 empty pages, considering it's the end") break else: assert False, "that's a lot of pages, misdetected end?"
def gotEvent(self, event): found = False for i in range(self.ui.typeBox.count()): s = self.ui.typeBox.itemData(i) if s == event.type: found = True if not found: print(event.type) self.ui.typeBox.addItem(event.type.capitalize(), event.type) if event.type == self.event_filter: self.ui.typeBox.setCurrentIndex(self.ui.typeBox.count()-1) if self.event_filter and self.event_filter != event.type: return if not event.contact: return contact = event.contact contact.backend = event.backend status = '' if contact.status == contact.STATUS_ONLINE: status = u'Online' status_color = 0x00aa00 elif contact.status == contact.STATUS_OFFLINE: status = u'Offline' status_color = 0xff0000 elif contact.status == contact.STATUS_AWAY: status = u'Away' status_color = 0xffad16 else: status = u'Unknown' status_color = 0xaaaaaa if contact.status_msg: status += u' — %s' % contact.status_msg name = '<h2>%s</h2><font color="#%06X">%s</font><br /><i>%s</i>' % (contact.name, status_color, status, event.backend) date = event.date.strftime('%Y-%m-%d %H:%M') type = event.type message = event.message item = QTreeWidgetItem(None, [name, date, type, message]) item.setData(0, Qt.UserRole, event) if contact.photos is NotLoaded: process = QtDo(self.weboob, lambda c: self.setPhoto(c, item)) process.do('fillobj', contact, ['photos'], backends=contact.backend) self.photo_processes[contact.id] = process elif len(contact.photos) > 0: if not self.setPhoto(contact, item): photo = list(contact.photos.values())[0] process = QtDo(self.weboob, lambda p: self.setPhoto(contact, item)) process.do('fillobj', photo, ['thumbnail_data'], backends=contact.backend) self.photo_processes[contact.id] = process self.ui.eventsList.addTopLevelItem(item) self.ui.eventsList.resizeColumnToContents(0) self.ui.eventsList.resizeColumnToContents(1)
def __init__(self, config, storage, weboob, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.mdl = FavDemandFetcher(weboob) self.mdl.setColumnFields([['name', 'title'],['url']]) self.mdl.jobAdded.connect(self._jobAdded) self.mdl.jobFinished.connect(self._jobFinished) self.proxy_mdl = FilterTypeModel() self.proxy_mdl.setAcceptedTypes([BaseCollection, BaseGallery]) self.proxy_mdl.setSourceModel(self.mdl) self.ui.collectionTree.setModel(self.proxy_mdl) self.ui.collectionTree.selectionModel().currentChanged.connect(self.showCollection) n = self.mdl.columnCount(QModelIndex()) for i in range(n): self.ui.collectionTree.setColumnWidth(i, self.ui.collectionTree.width() // n) self.config = config self.storage = storage self.weboob = weboob self.ui.browseButton.clicked.connect(self.startBrowse) self.ui.searchGallEdit.returnPressed.connect(self.startGallSearch) self.ui.searchGallButton.clicked.connect(self.startGallSearch) self.ui.searchImgEdit.returnPressed.connect(self.startImgSearch) self.ui.searchImgButton.clicked.connect(self.startImgSearch) self.ui.imageList.setModel(self.mdl) self.ui.imageList.selectionModel().currentChanged.connect(self.showImageInfo) self.ui.imageList.activated.connect(self.openImage) self.fillBackends() if self.weboob.count_backends() == 0: self.backendsConfig() self.ui.actionBackends.triggered.connect(self.backendsConfig) self.ui.limitResults.valueChanged.connect(self._limitResultsChanged) self.mdl.setLimit(self.ui.limitResults.value()) self.lastSaveDir = os.path.expanduser('~') app = QApplication.instance() self.ui.fetchMore.clicked.connect(app.fetchMore) self.ui.fetchStop.clicked.connect(app.fetchStop) self.ui.fetchStop.clicked.connect(self.disableNext) self.ui.ignUnchecked.clicked.connect(self.ignoreUnchecked) self.mdl.endHit.connect(self.disableNext) self.ui.toggleChecks.clicked.connect(self.toggleChecks) self.mdl.rowsInserted.connect(self.inserted) self.ui.helpLink.linkActivated.connect(self.showHelp)
def parse_command_args(self, line, nb, req_n=None): if line.strip() == '': # because ''.split() = [''] args = [] else: args = line.strip().split(' ', nb - 1) if req_n is not None and (len(args) < req_n): raise NotEnoughArguments('Command needs %d arguments' % req_n) if len(args) < nb: args += tuple(None for i in range(nb - len(args))) return args
def addContact(self, contact): if not contact: self.ui.refreshButton.setEnabled(True) return status = '' if contact.status == Contact.STATUS_ONLINE: status = u'Online' status_color = 0x00aa00 elif contact.status == Contact.STATUS_OFFLINE: status = u'Offline' status_color = 0xff0000 elif contact.status == Contact.STATUS_AWAY: status = u'Away' status_color = 0xffad16 else: status = u'Unknown' status_color = 0xaaaaaa if contact.status_msg: status += u' — %s' % contact.status_msg item = QListWidgetItem() item.setText( '<h2>%s</h2><font color="#%06X">%s</font><br /><i>%s</i>' % (contact.name, status_color, status, contact.backend)) item.setData(Qt.UserRole, contact) if contact.photos is NotLoaded: process = QtDo(self.weboob, lambda c: self.setPhoto(c, item)) process.do('fillobj', contact, ['photos'], backends=contact.backend) self.photo_processes[contact.id] = process elif len(contact.photos) > 0: if not self.setPhoto(contact, item): photo = list(contact.photos.values())[0] process = QtDo(self.weboob, lambda p: self.setPhoto(contact, item)) process.do('fillobj', photo, ['thumbnail_data'], backends=contact.backend) self.photo_processes[contact.id] = process for i in range(self.ui.contactList.count()): if self.ui.contactList.item(i).data( Qt.UserRole).status > contact.status: self.ui.contactList.insertItem(i, item) return self.ui.contactList.addItem(item)
def __init__(self, config, storage, weboob, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.mdl = ResultModel(weboob) self.mdl.setColumnFields([['name', 'title'], ['url']]) self.mdl.jobAdded.connect(self._jobAdded) self.mdl.jobFinished.connect(self._jobFinished) self.proxy_mdl = FilterTypeModel() self.proxy_mdl.setAcceptedTypes([BaseCollection, BaseGallery]) self.proxy_mdl.setSourceModel(self.mdl) self.ui.collectionTree.setModel(self.proxy_mdl) self.ui.collectionTree.selectionModel().currentChanged.connect( self.showCollection) n = self.mdl.columnCount(QModelIndex()) for i in range(n): self.ui.collectionTree.setColumnWidth( i, self.ui.collectionTree.width() // n) self.config = config self.storage = storage self.weboob = weboob self.ui.browseButton.clicked.connect(self.startBrowse) self.ui.searchGallEdit.returnPressed.connect(self.startGallSearch) self.ui.searchGallButton.clicked.connect(self.startGallSearch) self.ui.searchImgEdit.returnPressed.connect(self.startImgSearch) self.ui.searchImgButton.clicked.connect(self.startImgSearch) self.ui.imageList.setModel(self.mdl) self.ui.imageList.selectionModel().currentChanged.connect( self.showImageInfo) self.ui.imageList.activated.connect(self.openImage) self.fillBackends() if self.weboob.count_backends() == 0: self.backendsConfig() self.ui.actionBackends.triggered.connect(self.backendsConfig) self.ui.limitResults.valueChanged.connect(self._limitResultsChanged) self.mdl.setLimit(self.ui.limitResults.value()) self.lastSaveDir = os.path.expanduser('~')
def addQuery(self, name=None): querydlg = QueryDialog(self.weboob, self) if name is not None: query = self.config.get('queries', name) querydlg.ui.nameEdit.setText(name) querydlg.ui.nameEdit.setEnabled(False) for c in query['cities']: city = City(c['id']) city.backend = c['backend'] city.name = c['name'] item = querydlg.buildCityItem(city) querydlg.ui.citiesList.addItem(item) querydlg.ui.typeBox.setCurrentIndex(int(query.get('type', 0))) querydlg.ui.areaMin.setValue(query['area_min']) querydlg.ui.areaMax.setValue(query['area_max']) querydlg.ui.costMin.setValue(query['cost_min']) querydlg.ui.costMax.setValue(query['cost_max']) querydlg.selectComboValue(querydlg.ui.nbRooms, query['nb_rooms']) if querydlg.exec_(): name = querydlg.ui.nameEdit.text() query = {} query['type'] = querydlg.ui.typeBox.currentIndex() query['cities'] = [] for i in range(len(querydlg.ui.citiesList)): item = querydlg.ui.citiesList.item(i) city = item.data(Qt.UserRole) query['cities'].append({ 'id': city.id, 'backend': city.backend, 'name': city.name }) query['area_min'] = querydlg.ui.areaMin.value() query['area_max'] = querydlg.ui.areaMax.value() query['cost_min'] = querydlg.ui.costMin.value() query['cost_max'] = querydlg.ui.costMax.value() try: query['nb_rooms'] = int( querydlg.ui.nbRooms.itemText( querydlg.ui.nbRooms.currentIndex())) except ValueError: query['nb_rooms'] = 0 self.config.set('queries', name, query) self.config.save() self.reloadQueriesList(name)
def parse_command_args(self, line, nb, req_n=None): try: if sys.version_info.major >= 3: args = shlex.split(line) else: args = [arg.decode('utf-8') for arg in shlex.split(line.encode('utf-8'))] except ValueError as e: raise ArgSyntaxError(str(e)) if nb < len(args): raise TooManyArguments('Command takes at most %d arguments' % nb) if req_n is not None and (len(args) < req_n): raise NotEnoughArguments('Command needs %d arguments' % req_n) if len(args) < nb: args += tuple(None for i in range(nb - len(args))) return args
def parse_command_args(self, line, nb, req_n=None): try: if sys.version_info.major >= 3: args = shlex.split(line) else: args = [ arg.decode('utf-8') for arg in shlex.split(line.encode('utf-8')) ] except ValueError as e: raise ArgSyntaxError(str(e)) if nb < len(args): raise TooManyArguments('Command takes at most %d arguments' % nb) if req_n is not None and (len(args) < req_n): raise NotEnoughArguments('Command needs %d arguments' % req_n) if len(args) < nb: args += tuple(None for i in range(nb - len(args))) return args
def addQuery(self, name=None): querydlg = QueryDialog(self.weboob, self) if name is not None: query = self.config.get('queries', name) querydlg.ui.nameEdit.setText(name) querydlg.ui.nameEdit.setEnabled(False) for c in query['cities']: city = City(c['id']) city.backend = c['backend'] city.name = c['name'] item = querydlg.buildCityItem(city) querydlg.ui.citiesList.addItem(item) querydlg.ui.typeBox.setCurrentIndex(int(query.get('type', 0))) querydlg.ui.areaMin.setValue(query['area_min']) querydlg.ui.areaMax.setValue(query['area_max']) querydlg.ui.costMin.setValue(query['cost_min']) querydlg.ui.costMax.setValue(query['cost_max']) querydlg.selectComboValue(querydlg.ui.nbRooms, query['nb_rooms']) if querydlg.exec_(): name = querydlg.ui.nameEdit.text() query = {} query['type'] = querydlg.ui.typeBox.currentIndex() query['cities'] = [] for i in range(len(querydlg.ui.citiesList)): item = querydlg.ui.citiesList.item(i) city = item.data(Qt.UserRole) query['cities'].append({'id': city.id, 'backend': city.backend, 'name': city.name}) query['area_min'] = querydlg.ui.areaMin.value() query['area_max'] = querydlg.ui.areaMax.value() query['cost_min'] = querydlg.ui.costMin.value() query['cost_max'] = querydlg.ui.costMax.value() try: query['nb_rooms'] = int(querydlg.ui.nbRooms.itemText(querydlg.ui.nbRooms.currentIndex())) except ValueError: query['nb_rooms'] = 0 self.config.set('queries', name, query) self.config.save() self.reloadQueriesList(name)
def make256xterm(): """Return a [r, g, b, r, g, b, ...] table with the colors of the 256 xterm colors. The table is indexed: [0:3] corresponds to color 0. """ color256 = [] # standard 16 colors color256 += list(sum((PILColor.getrgb(c) for c in '''black maroon green olive navy purple teal silver gray red lime yellow blue fuchsia aqua white'''.split()), ())) steps = (0, 95, 135, 175, 215, 255) for r in steps: for g in steps: for b in steps: color256 += [r, g, b] # grays for v in range(8, 248, 10): color256 += [v, v, v] assert len(color256) == 256 * 3 return color256
def selectComboValue(self, box, value): for i in range(box.count()): if box.itemText(i) == str(value): box.setCurrentIndex(i) break
def toggleChecks(self): allck = all(self.mdl.index(n, 0, QModelIndex()).data(Qt.CheckStateRole) == Qt.Checked for n in range(self.mdl.rowCount(QModelIndex()))) new = Qt.Unchecked if allck else Qt.Checked for n in range(self.mdl.rowCount(QModelIndex())): self.mdl.setData(self.mdl.index(n, 0, QModelIndex()), new, Qt.CheckStateRole)
def set_value(self, value): self._value = value for i in range(self.count()): if self.itemData(i) == self._value.get(): self.setCurrentIndex(i) return