Logo Search packages:      
Sourcecode: webboard version File versions  Download package

webboard.py

#!/usr/bin/env python
# WebBoard allows you to publish text on a public pastebin on the net
# This applications is based on the command line tool paste of 
# Dennis Kaarsemaker
#
#   (c) 2005 - Dennis Kaarsemaker <dennis@kaarsemaker.net>
#   (c) 2006 - Sebastian Heinlein <sebastian.heinlein@web.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


import sys
import os
import thread
import time
import datetime
import subprocess
import urllib

try:
    import pygtk
    pygtk.require('2.0')
    import gtk
    import gtk.glade
    from urllib2 import urlopen
    from sre import compile
    import gettext
    from gettext import gettext as _
    gettext.bindtextdomain('webboard')
    gettext.textdomain('webboard')
    gtk.glade.bindtextdomain('webboard')
    gtk.glade.textdomain('webboard')
except:
    print "faild to import all modules"
    sys.exit(1)

try:
    import wbconfig
    from wbconfig import WebBoardConfig
except:
    import webboard.wbconfig
    from webboard.wbconfig import WebBoardConfig

00056 class WebBoard:
    def __init__(self, config, history, clip=False, file=None):
        icons = gtk.icon_theme_get_default()
        self.logo_pixbuf=icons.load_icon("gtk-paste", 32, 0)
        gtk.window_set_default_icon_list(self.logo_pixbuf)

        self.glade = gtk.glade.XML(os.path.join(wbconfig.glade_dir,
                "webboard.glade"))
        self.glade.signal_autoconnect(self)
        self.textview = self.glade.get_widget("textview")
        # setup drag'n'drop
        self.textview.drag_dest_set(gtk.DEST_DEFAULT_ALL, \
                                    [('text/uri-list',0 , 0)], \
                                    gtk.gdk.ACTION_COPY)
        self.textview.connect("drag_motion", \
                              self.on_textview_drag_motion)
        self.textview.connect("drag_data_received", \
                              self.on_textview_drag_data_received)
        self.window_main = self.glade.get_widget("window_main")
        self.button_browser = self.glade.get_widget("button_browser")
        self.button_send = self.glade.get_widget("button_send")
        self.combobox_pastebin = self.glade.get_widget("combobox_pastebin")
        self.statusbar = self.glade.get_widget("statusbar")

        self.context = self.statusbar.get_context_id("context_webboard")

        self.clipboard = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)

        self.config = config
        self.config.add_notifier(self.on_config_changed)
        self.history = history

        self.tooltips = gtk.Tooltips()

        self.on_config_changed()

        self.buffer = self.textview.get_buffer()
        text = self.clipboard.wait_for_text()
        if (clip is False) or (text is None):
            self.buffer.set_text(self.welcome)
        else:
            self.buffer.set_text(text)
        self.buffer.select_range(self.buffer.get_start_iter(),
                                 self.buffer.get_end_iter())

        if file != None:
            self.open_file(file)

        self.button_send.grab_default()
        self.window_main.show()

        gtk.main()
        return

00110     def _get_file_path_from_dnd_dropped_uri(self, uri):
        """ helper to get a useful path from a drop uri"""
        path = urllib.url2pathname(uri) # escape special chars
        path = path.strip('\r\n\x00') # remove \r\n and NULL
        # get the path to file
        if path.startswith('file:\\\\\\'): # windows
            path = path[8:] # 8 is len('file:///')
        elif path.startswith('file://'): # nautilus, rox
            path = path[7:] # 7 is len('file://')
        elif path.startswith('file:'): # xffm
            path = path[5:] # 5 is len('file:')
        return path
    
    def on_textview_drag_motion(self, widget, content, x, y, time):
        # Unset the selection in the textview. Otherwise we cannot
        # drop the file
        self.buffer.select_range(self.buffer.get_start_iter(),
                                 self.buffer.get_start_iter())

    def open_file(self, path):
        if os.path.exists(path):
            self.textview.get_buffer().set_text(file(path).read())

    def on_textview_drag_data_received(self, widget, context, x, y,
                                       selection, target_type, timestamp):
        uri = selection.data.strip()
        uri_splitted = uri.split()
        for uri in uri_splitted:
            path = self._get_file_path_from_dnd_dropped_uri(uri)
            self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
            while gtk.events_pending(): gtk.main_iteration()
            try:
                self.open_file(path)
            except IOError, e:
                pass
            self.window_main.window.set_cursor(None)

    def on_history_changed(self):
        self.history.update()

    def on_config_changed(self):
        # TRANSLATORS: tooltip of the button "publish"
        #              %s is the URL of the pastebin server
        self.tooltips.set_tip(self.button_send,
                              _("Publish the text on %s and copy the link "\
                                "to the relating website into the clipboard") \
                                % self.config.pastebin)
        # TRANSLATORS: default welcome text
        #              %s is the URL of the pastebin server
        self.welcome = _("Enter, copy or drag and drop source code and text "
                         "notes for publishing on %s") % self.config.pastebin
        # TRANSLATORS: The Window title - %s is the URL of the server
        self.window_main.set_title(_("WebBoard - %s") % self.config.pastebin)


    def on_window_main_destroy(self, widget):
        self.clipboard.store()
        gtk.main_quit()
        return

    def on_history_activate(self, widget, data):
        self.clipboard.set_text(data, len=-1)

    def on_button_send_clicked(self, widget=None):
        # Post the buffer
        self.statusbar.push(self.context,_("Publishing..."))
        self.window_main.set_sensitive(False)
        self.textview.set_sensitive(False)
        self.textview.set_editable(False)
        self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
        self.post = self.buffer.get_text(self.buffer.get_start_iter(),
                                             self.buffer.get_end_iter(), False)
        if self.post is "":
            self.statusbar.push(self.context,_("No text for publishing"))
        else:
            lock = thread.allocate_lock()
            lock.acquire()
            thread.start_new_thread(self.send, (self.post, lock))
            while lock.locked():
                time.sleep(0.05)
                while gtk.events_pending():
                    gtk.main_iteration()

            if self.ret is False:
                self.statusbar.push(self.context,_("Could not publish the text"\
                                                   " at %s") % self.config.pastebin)
            else:
                self.url = "%s/%s" % (self.config.pastebin, self.ret)
                if not (self.url.startswith("http://") or
                        self.url.startswith("https://")):
                    self.url = "http://" + self.url
                # Write URL to the clipboard for easy paste
                self.statusbar.push(self.context,
                        _("Published at %s") % self.url)
                # set a nice title for the link
                text = self.post[:].lstrip(" \n\t").rstrip(" \n\t")
                text.replace("\n", "")
                if len(text) > 26:
                    text = "%s..." % text[0:20]
                # add to history
                now = datetime.datetime.now()
                stamp = time.mktime(now.timetuple())
                self.history.add(stamp , text, self.url)
                # copy link to the clipboard
                self.clipboard.set_text(self.url, len=-1)

        self.button_browser.set_sensitive(True)
        self.window_main.window.set_cursor(None)
        self.window_main.set_sensitive(True)
        self.textview.set_editable(True)
        self.textview.set_sensitive(True)


    def on_menu_quit_activate(self, widget):
        self.window_main.destroy()

    def on_menu_info_activate(self, widget):
        wbconfig.about_info(self)

    def on_button_clear_clicked(self, widget):
        # Clear the buffer
        self.buffer.set_text("")


    def on_button_browser_clicked(self, widget=None):
        if os.path.exists('/usr/bin/gnome-open'):
            command = ['gnome-open', self.url]
        else:
            command = ['x-www-browser', self.url]
        p = subprocess.Popen(command, close_fds=True, stdin=subprocess.PIPE,\
                             stdout=subprocess.PIPE)


    def send(self, post, lock, *args):
        self.ret = False
        pastebin = self.config.pastebin
        if not (pastebin[:7] == 'http://'):
            pastebin = 'http://' + pastebin
        data = "format=text&paste=Submit&code2=%s&poster=%s" % \
                (self.urlencode(post), self.urlencode(self.config.user))
        try:
            u = urlopen(pastebin, data)
            f = "".join(u.readlines())
            rx = compile("<a.*?/(\d+)\">")
            ar = rx.findall(f)
            if len(ar) > 0:
                self.ret = ar[0]
            lock.release()
        except:
            self.ret = False
            lock.release()


00263     def urlencode(self, data):
        """Encode all non-alphanumeric characters as hexadecimal codes"""
        out = ""
        for char in data:
            if char.isalnum() or char in ['-','_']:
                out += char
            else:
                char = hex(ord(char))[2:]
                if len(char) == 1:
                    char = "0" + char
                out += "%" + char
        return out

def main():
    config = WebBoardConfig()
    wb = WebBoard(config, clip=True)
    config.add_notifier(wb.on_config_changed)
    del wb
    del config

if __name__ == '__main__':
    main()


Generated by  Doxygen 1.6.0   Back to index