Example #1
0
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)
Example #2
0
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)
Example #3
0
 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)
Example #4
0
    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
Example #5
0
    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
Example #6
0
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
Example #7
0
    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?"
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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
Example #11
0
    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)
Example #12
0
    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('~')
Example #13
0
    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)
Example #14
0
    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
Example #15
0
    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
Example #16
0
    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)
Example #17
0
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
Example #18
0
 def selectComboValue(self, box, value):
     for i in range(box.count()):
         if box.itemText(i) == str(value):
             box.setCurrentIndex(i)
             break
Example #19
0
 def selectComboValue(self, box, value):
     for i in range(box.count()):
         if box.itemText(i) == str(value):
             box.setCurrentIndex(i)
             break
Example #20
0
 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)
Example #21
0
 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