conduit r1262 - in trunk: . conduit conduit/modules/NetworkModule tools/eog-plugin
- From: jstowers svn gnome org
- To: svn-commits-list gnome org
- Subject: conduit r1262 - in trunk: . conduit conduit/modules/NetworkModule tools/eog-plugin
- Date: Wed, 23 Jan 2008 11:43:35 +0000 (GMT)
Author: jstowers
Date: Wed Jan 23 11:43:35 2008
New Revision: 1262
URL: http://svn.gnome.org/viewvc/conduit?rev=1262&view=rev
Log:
2008-01-23 John Stowers <john stowers gmail com>
* conduit/Main.py: Improve help message
* conduit/modules/NetworkModule/Client.py:
* conduit/modules/NetworkModule/Server.py:
* conduit/modules/NetworkModule/XMLRPCUtils.py: Dont create a new Peerlister
every time. Small improvements to hopefully improve cancellation.
* tools/eog-plugin/conduit.py:
* tools/eog-plugin/config.glade: Add Facebook and ShutterFly support. Clear
the sidebar when sync finishes
Modified:
trunk/ChangeLog
trunk/conduit/Main.py
trunk/conduit/modules/NetworkModule/Client.py
trunk/conduit/modules/NetworkModule/Server.py
trunk/conduit/modules/NetworkModule/XMLRPCUtils.py
trunk/tools/eog-plugin/conduit.py
trunk/tools/eog-plugin/config.glade
Modified: trunk/conduit/Main.py
==============================================================================
--- trunk/conduit/Main.py (original)
+++ trunk/conduit/Main.py Wed Jan 23 11:43:35 2008
@@ -53,13 +53,16 @@
iconify = False
self.ui = "gtk"
try:
- opts, args = getopt.getopt(sys.argv[1:], "hs:ciu:",
- ["help", "settings=", "console", "iconify", "ui="])
+ opts, args = getopt.getopt(sys.argv[1:], "hvs:ciu:",
+ ["help", "version", "settings=", "console", "iconify", "ui="])
#parse args
for o, a in opts:
if o in ("-h", "--help"):
self._usage()
sys.exit(0)
+ if o in ("-v", "--version"):
+ print "%s %s" % (conduit.APPNAME, conduit.APPVERSION)
+ sys.exit(0)
if o in ("-s", "--settings"):
self.settingsFile = os.path.join(os.getcwd(), a)
if o in ("-c", "--console"):
@@ -161,14 +164,18 @@
self.Quit()
def _usage(self):
- print """Conduit: Usage
-$ %s [OPTIONS]
-
+ print """Usage: conduit [OPTIONS] - Synchronize things
OPTIONS:
- -h, --help Print this help notice.
- -c, --console Launch Conduit with no GUI) (default=no).
- -s, --settings=FILE Override saving conduit settings to FILE
- -i, --iconify Iconify on startup (default=no)""" % sys.argv[0]
+ -h, --help Show this message.
+ -c, --console Launch with no GUI.
+ (default=no)
+ -s, --settings=FILE Save settings to FILE.
+ (default=~/.conduit/settings.xml)
+ -i, --iconify Iconify on startup.
+ (default=no)
+ -u, --ui=NAME Run with the specified UI
+ (default=gtk)
+ -v, --version Show version information"""
@dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='b')
def HasGUI(self):
Modified: trunk/conduit/modules/NetworkModule/Client.py
==============================================================================
--- trunk/conduit/modules/NetworkModule/Client.py (original)
+++ trunk/conduit/modules/NetworkModule/Client.py Wed Jan 23 11:43:35 2008
@@ -30,14 +30,14 @@
self.categories = {}
self.dataproviders = {}
- self.peers = []
+ self.peers = {}
try:
self.monitor = Peers.AvahiMonitor(self.host_available, self.host_removed)
except:
log.warn("Error starting client")
def quit(self):
- for p in self.peers:
+ for p in self.peers.values():
p.stop()
def host_available(self, name, host, address, port, extra_info):
@@ -45,40 +45,34 @@
Callback which is triggered when a dataprovider is advertised on
a remote conduit instance
"""
- log.debug("Remote host '%s' detected" % host)
-
- # Path to remote data services
url = "http://%s" % host
+ log.debug("Remote host '%s' detected" % url)
- # Create a categories group for this host?
- if not self.categories.has_key(url):
+ if not self.peers.has_key(url):
+ #Create a category group for this host
self.categories[url] = DataProviderCategory.DataProviderCategory("On %s" % host, "computer", host)
-
- # Create a dataproviders list for this host
- self.dataproviders[url] = {}
-
- # Request all dp's for this host. Because there is no
- # avahi signal when the text entry in a avahi publish group
- # is changed, we must poll detected peers....
- request = _PeerLister(url, port)
- request.connect("complete", self.dataprovider_process)
- request.start()
- self.peers.append(request)
+ # Create a dataproviders list for this host
+ self.dataproviders[url] = {}
+ # Request all dp's for this host. Because there is no
+ # avahi signal when the text entry in a avahi publish group
+ # is changed, we must poll detected peers....
+ request = _PeerLister(url, port)
+ request.connect("complete", self.dataprovider_process)
+ request.start()
+ self.peers[url] = request
def host_removed(self, url):
"""
Callback which is triggered when a host is no longer available
"""
log.debug("Remote host '%s' removed" % url)
-
- if self.categories.has_key(url):
+ if self.peers.has_key(url):
self.categories.remove(url)
-
- if self.dataproviders.has_key(url):
- for uid, dp in self.dataproviders[url].iteritems():
+ for uid, dp in self.dataproviders[url].items():
self.dataprovider_removed(dp)
self.dataproviders.remove(url)
-
+ self.peers.remove(url)
+
def dataprovider_process(self, peerLister):
"""
"""
@@ -170,15 +164,14 @@
server = xmlrpclib.Server("%s:%s/" % (self.url,self.port))
#Gross cancellable spinning loop...
while not self.stopped:
- while self._ticks > (self.FREQ / self.SLEEP):
+ if self._ticks > (self.FREQ / self.SLEEP):
try:
self.data_out = server.list_shared_dataproviders()
gobject.idle_add(self.emit, "complete")
- self._ticks = 0
- except socket.error:
+ except:
#If the server has died or not started yet
pass
-
+ self._ticks = 0
else:
time.sleep(self.SLEEP)
self._ticks += 1
Modified: trunk/conduit/modules/NetworkModule/Server.py
==============================================================================
--- trunk/conduit/modules/NetworkModule/Server.py (original)
+++ trunk/conduit/modules/NetworkModule/Server.py Wed Jan 23 11:43:35 2008
@@ -114,11 +114,11 @@
def quit(self):
#stop all the xmlrpc servers
+ for server in self.shared.values():
+ server.stop()
+
if self.peerAnnouncer != None:
self.peerAnnouncer.stop()
-
- for server in self.shared.values():
- server.stop()
def share_dataprovider(self, dpw):
"""
Modified: trunk/conduit/modules/NetworkModule/XMLRPCUtils.py
==============================================================================
--- trunk/conduit/modules/NetworkModule/XMLRPCUtils.py (original)
+++ trunk/conduit/modules/NetworkModule/XMLRPCUtils.py Wed Jan 23 11:43:35 2008
@@ -77,13 +77,18 @@
while not inputObjects and not self.closed:
try:
inputObjects, outputObjects, errorObjects = select.select([self.socket], [], [], 0.2)
- return self.socket.accept()
+ sock, addr = self.socket.accept()
+ return (sock, addr)
+ except socket.timeout:
+ if self.closed:
+ raise
+ except socket.error:
+ #Occurs at shutdown, raise to stop serving
+ if self.closed:
+ raise
except select.error:
#Occurs sometimes at start up, race condition, ignore
pass
- except socket.error:
- #Occurs at shutdown, raise to stop serving
- raise
def start(self):
threading.Thread(target=self.serve).start()
Modified: trunk/tools/eog-plugin/conduit.py
==============================================================================
--- trunk/tools/eog-plugin/conduit.py (original)
+++ trunk/tools/eog-plugin/conduit.py Wed Jan 23 11:43:35 2008
@@ -18,7 +18,9 @@
"FlickrTwoWay" : "Upload to Flickr",
"PicasaTwoWay" : "Upload to Picasa",
"SmugMugTwoWay" : "Upload to SmugMug",
+ "ShutterflySink" : "Upload to Shutterfly",
"BoxDotNetTwoWay" : "Upload to Box.net",
+ "FacebookSink" : "Upload to Facebook",
"TestImageSink" : "Test"
}
@@ -113,18 +115,28 @@
self.store.set_value(rowref, STATUS_IDX, "finished")
def _on_sync_completed(self, abort, error, conflict):
- #FIXME:
- #on error or abort, add to the conduit gui syncset to allow
- #the user to debug it.
rowref = self._get_rowref()
- #update the status
- self.store.set_value(rowref, STATUS_IDX, "finished")
- #tell the view to redraw
- self.store.row_changed(
- self.store.get_path(rowref),
- rowref
- )
-
+ if abort == False and error == False:
+ self.clear()
+ #update the status
+ self.store.set_value(rowref, STATUS_IDX, "finished")
+ else:
+ #show the error message in the conduit gui
+ self.store.set_value(rowref, STATUS_IDX, "error")
+
+ def clear(self):
+ rowref = self._get_rowref()
+ #Delete all the images from the list of images to upload
+ delete = []
+ child = self.store.iter_children(rowref)
+ while child != None:
+ delete.append(child)
+ child = self.store.iter_next(child)
+ #need to do in two steps so we dont modify the store while
+ #iterating
+ for d in delete:
+ self.store.remove(d)
+
def add_photo(self, pixbuf, uri):
ok = self.conduit.AddData(uri,dbus_interface=EXPORTER_DBUS_IFACE)
if ok == True:
@@ -154,10 +166,9 @@
)
class ConduitApplicationWrapper:
- def __init__(self):
- #conduit dbus application
+ def __init__(self, startConduit, addToGui):
+ self.addToGui = addToGui
self.app = None
- #the conduit dbus objects
self.conduits = {}
#the liststore with icons of the images to be uploaded
self.store = gtk.TreeStore(
@@ -167,18 +178,16 @@
str #STATUS_IDX
)
- #setup the DBus connection
- self._connect_to_conduit_application()
-
- def _connect_to_conduit_application(self):
- try:
- remote_object = dbus.SessionBus().get_object(APPLICATION_DBUS_IFACE,"/")
- self.app = dbus.Interface(remote_object, APPLICATION_DBUS_IFACE)
- self.dps = self.app.GetAllDataProviders()
- except dbus.exceptions.DBusException:
- self.app = None
- print "Conduit unavailable"
-
+ if startConduit:
+ self.start()
+ else:
+ obj = self.bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
+ dbus_iface = dbus.Interface(obj, 'org.freedesktop.DBus')
+ if dbus_iface.NameHasOwner(APPLICATION_DBUS_IFACE):
+ self.start()
+ else:
+ raise Exception("Could not connect to conduit")
+
def _build_conduit(self, sinkName):
if sinkName in self.dps:
print "Building exporter conduit %s" % sinkName
@@ -191,31 +200,50 @@
if name not in self.conduits:
self._build_conduit(name)
- imageuri = eogImage.get_uri_for_display()
-
- #proportionally scale the pixbuf
- thumb = eogImage.get_thumbnail()
- pb = thumb.scale_simple(ICON_SIZE,ICON_SIZE,gtk.gdk.INTERP_BILINEAR)
-
- #add the photo to the remote condui and the liststore
- print "Upload ", name, eogImage
- self.conduits[name].add_photo(pixbuf=pb,uri=imageuri)
+ if eogImage != None:
+ #proportionally scale the pixbuf
+ thumb = eogImage.get_thumbnail()
+ pb = thumb.scale_simple(ICON_SIZE,ICON_SIZE,gtk.gdk.INTERP_BILINEAR)
+
+ #add the photo to the remote condui and the liststore
+ self.conduits[name].add_photo(
+ pixbuf=pb,
+ uri=eogImage.get_uri_for_display()
+ )
+
+
+ def start(self):
+ if not self.connected():
+ try:
+ remote_object = dbus.SessionBus().get_object(APPLICATION_DBUS_IFACE,"/")
+ self.app = dbus.Interface(remote_object, APPLICATION_DBUS_IFACE)
+ self.dps = self.app.GetAllDataProviders()
+ except dbus.exceptions.DBusException:
+ self.app = None
+ print "Conduit unavailable"
def sync(self):
- for c in self.conduits:
- self.conduits[c].sync()
+ if self.connected():
+ for c in self.conduits:
+ self.conduits[c].sync()
+
+ def clear(self):
+ if self.connected():
+ for c in self.conduits:
+ self.conduits[c].clear()
def connected(self):
- #are we connected to conduit dbus interface
return self.app != None
class ConduitPlugin(eog.Plugin):
def __init__(self):
self.dir = os.path.abspath(os.path.join(__file__, ".."))
self.gladefile = os.path.join(self.dir, "config.glade")
-
- self.window = None
- self.conduit = ConduitApplicationWrapper()
+
+ self.conduit = ConduitApplicationWrapper(
+ startConduit=True,
+ addToGui=False
+ )
def _on_upload_clicked(self, sender, window):
currentImage = window.get_image()
@@ -225,6 +253,9 @@
def _on_sync_clicked(self, *args):
self.conduit.sync()
+ def _on_clear_clicked(self, *args):
+ self.conduit.clear()
+
def _on_row_activated(self, treeview, path, view_column):
#check the user didnt click a header row
rowref = treeview.get_model().get_iter(path)
@@ -261,11 +292,15 @@
view.append_column(col1)
#upload and clear button
- okbtn = gtk.Button(stock=gtk.STOCK_OK)
+ okbtn = gtk.Button(label="Synchronize")
+ okbtn.set_image(
+ gtk.image_new_from_stock(gtk.STOCK_REFRESH,gtk.ICON_SIZE_BUTTON)
+ )
okbtn.connect("clicked",self._on_sync_clicked)
clearbtn = gtk.Button(stock=gtk.STOCK_CLEAR)
- bbox.pack_start(okbtn)
- bbox.pack_start(clearbtn)
+ clearbtn.connect("clicked",self._on_clear_clicked)
+ bbox.pack_start(okbtn,expand=True)
+ bbox.pack_start(clearbtn,expand=True)
sidebar = window.get_sidebar()
sidebar.add_page("Photo Uploads", box)
@@ -305,24 +340,20 @@
#render the headers different to the data
if tree_model.iter_depth(rowref) == 0:
status = tree_model.get_value(rowref, STATUS_IDX)
- name = "%s <i>(%s)</i>" % (name,status)
-
+ name = '%s <span foreground="grey" style="italic">(%s)</span>' % (name,status)
cell_renderer.set_property("markup", name)
def activate(self, window):
#the sidebar and menu integration must be done once per eog window instance
- print "ACTIVATE"
- self.window = window
if self.conduit.connected() == True:
self._prepare_sidebar(window)
self._prepare_tools_menu(window)
-
def deactivate(self, window):
- print "DEACTIVATE"
+ pass
def update_ui(self, window):
- print "UPDATE"
+ pass
def is_configurable(self):
return False
Modified: trunk/tools/eog-plugin/config.glade
==============================================================================
--- trunk/tools/eog-plugin/config.glade (original)
+++ trunk/tools/eog-plugin/config.glade Wed Jan 23 11:43:35 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.3.3 on Wed Aug 15 10:24:52 2007 -->
+<!--Generated with glade3 3.4.0 on Wed Jan 23 16:51:51 2008 -->
<glade-interface>
<widget class="GtkDialog" id="ConfigDialog">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -18,129 +18,32 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Enable Synchronizing Photos with the Following Locations</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkExpander" id="expander1">
+ <widget class="GtkCheckButton" id="checkbutton1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <widget class="GtkCheckButton" id="checkbutton1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Enabled</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <widget class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Username: </property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="padding">5</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="entry1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Flickr</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkExpander" id="expander3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <widget class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">SmugMug</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
+ <property name="label" translatable="yes">Start Conduit if it is not running.</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
- <property name="position">2</property>
+ <property name="fill">False</property>
</packing>
</child>
<child>
- <widget class="GtkExpander" id="expander2">
+ <widget class="GtkCheckButton" id="checkbutton2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">iPod Photos</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
+ <property name="label" translatable="yes">Show synchronization process in Conduit.</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
- <property name="position">3</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
</packing>
</child>
</widget>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]