コード例 #1
0
class ImgurUploader(cream.Module):

    def __init__(self):

        cream.Module.__init__(self, 'org.sbillaudelle.ImgurUploader')
        
        def start_attempt_cb(*args):
            print args
        
        self.connect('start-attempt', start_attempt_cb)

        parser = optparse.OptionParser()
        (options, args) = parser.parse_args()

        self.imgur = Imgur(API_KEY)

        self.interface = gtk.Builder()
        self.interface.add_from_file(os.path.join(self.context.get_path(), 'data/interface.ui'))

        self.window = self.interface.get_object('window')
        self.treeview = self.interface.get_object('treeview')
        self.filechooser = self.interface.get_object('filechooser')
        self.upload_button = self.interface.get_object('upload_button')
        self.close_button = self.interface.get_object('close_button')
        self.add_image_button = self.interface.get_object('add_image_button')
        self.remove_image_button = self.interface.get_object('remove_image_button')
        self.context_menu = self.interface.get_object('context_menu')
        self.copy_item = self.interface.get_object('copy_item')

        icon_path = os.path.join(self.context.get_path(), 'data/imgur.png')
        self.window.set_icon_from_file(icon_path)
        self.window.set_title(self.context.manifest['name'])

        self.filefilter = gtk.FileFilter()
        self.filefilter.set_name("Alle Bilddateien")
        self.filefilter.add_mime_type('image/bmp')
        self.filefilter.add_mime_type('image/gif')
        self.filefilter.add_mime_type('image/jpeg')
        self.filefilter.add_mime_type('image/jpg')
        self.filefilter.add_mime_type('image/pjpeg')
        self.filefilter.add_mime_type('image/png')
        self.filefilter.add_mime_type('image/tiff')
        self.filefilter.add_mime_type('image/x-bmp')

        self.filechooser.add_filter(self.filefilter)
        self.filechooser.set_current_folder(os.path.expanduser('~'))

        self.window.connect('destroy', lambda *args: self.quit())
        self.add_image_button.connect('clicked', self.add_image_cb)
        self.remove_image_button.connect('clicked', self.remove_image_cb)
        self.upload_button.connect('clicked', lambda *args: self.upload())
        self.close_button.connect('clicked', lambda *args: self.quit())
        self.treeview.connect('button-press-event', self.context_menu_cb)
        self.copy_item.connect('activate', self.copy_url_cb)

        # Initialize drag and drop...
        self.treeview.drag_dest_set(0, [], 0)
        self.treeview.connect('drag_motion', self.drag_motion_cb)
        self.treeview.connect('drag_drop', self.drag_drop_cb)
        self.treeview.connect('drag_data_received', self.drag_data_cb)

        theme = gtk.IconTheme.get_default()
        icon_info = theme.lookup_icon('ok', 16, 0)
        self.icon_done = gdkpixbuf.Pixbuf.new_from_file(icon_info.get_filename())

        self.liststore = gtk.ListStore(gdkpixbuf.Pixbuf, str, gdkpixbuf.Pixbuf, bool, bool, int, str, str, bool)
        
        self.treeview.set_model(self.liststore)
        self.treeview_selection = self.treeview.get_selection()
        self.treeview_selection.set_mode(gtk.SelectionMode.MULTIPLE)

        self.column_info = gtk.TreeViewColumn("Image")
        self.column_info.set_property('expand', True)
        self.column_url = gtk.TreeViewColumn("URL")
        self.column_status = gtk.TreeViewColumn("Status")
        self.treeview.append_column(self.column_info)
        self.treeview.append_column(self.column_url)
        self.treeview.append_column(self.column_status)

        cellrenderer_preview = gtk.CellRendererPixbuf()
        cellrenderer_title = gtk.CellRendererText()
        self.column_info.pack_start(cellrenderer_preview, False)
        self.column_info.pack_start(cellrenderer_title, True)
        self.column_info.add_attribute(cellrenderer_preview, 'pixbuf', 0)
        self.column_info.add_attribute(cellrenderer_title, 'text', 1)

        cellrenderer_url = gtk.CellRendererText()
        self.column_url.pack_start(cellrenderer_url, True)
        self.column_url.add_attribute(cellrenderer_url, 'markup', 7)

        cellrenderer_spinner = gtk.CellRendererSpinner()
        self.column_status.pack_end(cellrenderer_spinner, False)
        self.column_status.add_attribute(cellrenderer_spinner, 'visible', 3)
        self.column_status.add_attribute(cellrenderer_spinner, 'active', 3)
        self.column_status.add_attribute(cellrenderer_spinner, 'pulse', 5)

        cellrenderer_status = gtk.CellRendererPixbuf()
        self.column_status.pack_end(cellrenderer_status, False)
        self.column_status.add_attribute(cellrenderer_status, 'pixbuf', 2)
        self.column_status.add_attribute(cellrenderer_status, 'visible', 4)

        self.window.show_all()

        self.count = 0
        gobject.timeout_add(100, self.pulse, self.liststore, self.column_status, cellrenderer_spinner)

        for arg in args:
            self.add_image(arg)
            
    @property
    def selected_images(self):
        return self.treeview.get_selection().get_selected_rows()[1]


    def copy_url_cb(self, source):
        data = ''

        for row in self.selected_images:
            data += '\n' + self.liststore[row][7].replace('<tt>', '').replace('</tt>', '')

        clipboard = gtk.Clipboard.get(gdk.atom_intern('CLIPBOARD', True))
        clipboard.set_text(data.strip(), -1)


    def context_menu_cb(self, source, event):

        if event.button == 3:
            x = int(event.x)
            y = int(event.y)
            path_info = self.treeview.get_path_at_pos(x, y)
            if path_info is not None:
                path, col, cellx, celly = path_info
                if not path in self.selected_images:
                    self.treeview.set_cursor(path, col, 0)
                if self.liststore[path][4]:
                    self.copy_item.set_property('sensitive', True)
                else:
                    self.copy_item.set_property('sensitive', False)
                self.context_menu.popup(None, None, None, None, event.button, event.time)
            return True

        elif event.button == 1 and event.type == gdk.EventType._2BUTTON_PRESS:
            x = int(event.x)
            y = int(event.y)
            path_info = self.treeview.get_path_at_pos(x, y)
            if path_info is not None:
                path, col, cellx, celly = path_info

                if self.liststore[path][4]:
                    url = self.liststore[self.selected_images[0]][7]
                    url = url.replace('<tt>', '').replace('</tt>', '')
                    webbrowser.open(url)


    def drag_motion_cb(self, source, context, x, y, time):
        context.drag_status(gdk.DragAction.MOVE, time)
        return True

    def drag_drop_cb(self, source, context, x, y, time):
        if 'text/uri-list' in context.targets:
            source.drag_get_data(context, 'text/uri-list', time)
        return True

    def drag_data_cb(self, source, context, x, y, data, info, time):
        for uri in data.get_uris():
            path = unquote(uri).replace('file://', '')
            filename = os.path.split(path)[0]
            mimetype = mimetypes.guess_type(path)[0]

            if self.filefilter.filter((path, uri, filename, mimetype)):
                self.add_image(path)

        context.finish(True, False, time)



    def upload(self):
        thread.start_new_thread(self._upload, ())


    def _upload(self):

        for image in self.liststore:
            if image[4]:
                continue

            #gtk.gdk.threads_enter()
            image[3] = True
            #gtk.gdk.threads_leave()

            data = self.imgur.upload(image[6])

            #gtk.gdk.threads_enter()
            image[7] = "<tt>{0}</tt>".format(data['rsp']['image']['imgur_page'])
            image[3] = False
            image[4] = True
            #gtk.gdk.threads_leave()


    def pulse(self, liststore, column, spinner):

        self.count+=1
        
        for item in liststore:
            item[5] = self.count

        return True


    def add_image_cb(self, source):

        res = self.filechooser.run()
        self.filechooser.hide()

        if res == 1:
            filenames = self.filechooser.get_filenames()
            for filename in filenames:
                self.add_image(filename)


    def remove_image_cb(self, source):

        selection = self.treeview_selection.get_selected_rows()[1]

        for row in selection:
            if self.liststore[row][3]:
                self.treeview_selection.unselect_path(row)

        selection = self.treeview_selection.get_selected_rows()[1]

        if not selection:
            return

        while selection:
            row = selection[0]
            self.liststore.remove(self.liststore.get_iter(row))
            selection = self.treeview_selection.get_selected_rows()[1]


    def add_image(self, image_path):
        thread.start_new_thread(self._add_image, (image_path,))


    def _add_image(self, image_path):

        icon = gdkpixbuf.Pixbuf.new_from_file(image_path)
        width = icon.get_width()
        height = icon.get_height()
        factor = float(width) / float(height)

        icon = icon.scale_simple(int(20 * factor), 20, gdkpixbuf.InterpType.BILINEAR)

        #gtk.gdk.threads_enter()
        self.liststore.append((icon, os.path.basename(image_path), self.icon_done, False, False, 0, image_path, '', True))