conduit r1373 - in trunk: . conduit conduit/dataproviders conduit/modules/FileModule test/python-tests test/python-tests/data
- From: jstowers svn gnome org
- To: svn-commits-list gnome org
- Subject: conduit r1373 - in trunk: . conduit conduit/dataproviders conduit/modules/FileModule test/python-tests test/python-tests/data
- Date: Fri, 14 Mar 2008 04:24:06 +0000 (GMT)
Author: jstowers
Date: Fri Mar 14 04:24:05 2008
New Revision: 1373
URL: http://svn.gnome.org/viewvc/conduit?rev=1373&view=rev
Log:
2008-03-14 John Stowers <john stowers gmail com>
* conduit/Vfs.py:
* test/python-tests/TestCoreVfs.py: Add functions (and tests) for getting
the root uri for a removable volume.
* conduit/dataproviders/File.py:
* conduit/modules/FileModule/FileModule.py: Save the sync groups relative
path and group name if it is stored on a removable volume. When a removable
volume is inserted, check for this information and create a preconfigured
folder dataprovider. Fixes #511691
* test/python-tests/TestDataProviderFolder.py:
* test/python-tests/data/folder.list: Tests for above.
Added:
trunk/test/python-tests/TestDataProviderFolder.py
trunk/test/python-tests/data/folder.list
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/conduit/Vfs.py
trunk/conduit/dataproviders/File.py
trunk/conduit/modules/FileModule/FileModule.py
trunk/test/python-tests/TestCoreVfs.py
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Fri Mar 14 04:24:05 2008
@@ -3,6 +3,9 @@
* You can now specify your own labels when saving emails
* Removed the build dependency on dbus, just check for python-dbus > 0.80.0
* Restore the expanded columns in the data provider pane
+* Improved removable volume support (like USB keys). Now, inserting a USB
+ key that has been synchronized on another computer will automatically create
+ a preconfigured dataprovider for synchronizing the folders of interest.
NEW in 0.3.8:
==============
Modified: trunk/conduit/Vfs.py
==============================================================================
--- trunk/conduit/Vfs.py (original)
+++ trunk/conduit/Vfs.py Fri Mar 14 04:24:05 2008
@@ -27,6 +27,40 @@
APP = "gnome-open"
os.spawnlp(os.P_NOWAIT, APP, APP, uri)
+def uri_to_local_path(uri):
+ """
+ @returns: The local path (/foo/bar) for the given URI. Throws a
+ RuntimeError (wtf??) if the uri is not a local one
+ """
+ return gnomevfs.get_local_path_from_uri(uri)
+
+def uri_get_volume_root_uri(uri):
+ """
+ @returns: The root path of the volume at the given uri, or None
+ """
+ try:
+ path = uri_to_local_path(uri)
+ return VolumeMonitor().get_volume_for_path(path).get_activation_uri()
+ except:
+ return None
+
+def uri_is_on_removable_volume(uri):
+ """
+ @returns: True if the specified uri is on a removable volume, like a USB key
+ or removable/mountable disk.
+ """
+ #HACKISH
+ #return uri.count("/media/") != 0
+ scheme = gnomevfs.get_uri_scheme(uri)
+ if scheme == "file":
+ try:
+ path = uri_to_local_path(uri)
+ return VolumeMonitor().get_volume_for_path(path).is_user_visible()
+ except:
+ return False
+ return False
+
+
def uri_get_filesystem_type(uri):
"""
@returns: The filesystem that uri is stored on or None if it cannot
@@ -35,7 +69,7 @@
scheme = gnomevfs.get_uri_scheme(uri)
if scheme == "file":
try:
- path = gnomevfs.get_local_path_from_uri(uri)
+ path = uri_to_local_path(uri)
volume = VolumeMonitor().get_volume_for_path(path)
return volume.get_filesystem_type()
except RuntimeError:
@@ -124,6 +158,16 @@
log.warn("Error checking if location exists")
return False
+def uri_make_directory(uri):
+ """
+ Makes a directory with the default permissions. Does not catch any
+ error
+ """
+ gnomevfs.make_directory(
+ uri,
+ gnomevfs.PERM_USER_ALL | gnomevfs.PERM_GROUP_READ | gnomevfs.PERM_GROUP_EXEC | gnomevfs.PERM_OTHER_READ | gnomevfs.PERM_OTHER_EXEC
+ )
+
def uri_make_directory_and_parents(uri):
"""
Because gnomevfs.make_dir does not perform as mkdir -p this function
@@ -144,10 +188,7 @@
dirs.reverse()
for d in dirs:
log.debug("Making directory %s" % d)
- gnomevfs.make_directory(
- d,
- gnomevfs.PERM_USER_ALL | gnomevfs.PERM_GROUP_READ | gnomevfs.PERM_GROUP_EXEC | gnomevfs.PERM_OTHER_READ | gnomevfs.PERM_OTHER_EXEC
- )
+ uri_make_directory(d)
#
# For monitoring locations
Modified: trunk/conduit/dataproviders/File.py
==============================================================================
--- trunk/conduit/dataproviders/File.py (original)
+++ trunk/conduit/dataproviders/File.py Fri Mar 14 04:24:05 2008
@@ -1,5 +1,6 @@
import os.path
import logging
+import ConfigParser
log = logging.getLogger("dataproviders.File")
import conduit
@@ -13,6 +14,59 @@
TYPE_FILE = "0"
TYPE_FOLDER = "1"
+def is_on_removable_volume(folderUri):
+ return Vfs.uri_is_on_removable_volume(folderUri)
+
+def get_removable_volume_info(folderUri):
+ """
+ Returns the root uri of the volume, and local path of the
+ group config file
+ """
+ rooturi = Vfs.uri_get_volume_root_uri(folderUri)
+ path = Vfs.uri_join(
+ Vfs.uri_to_local_path(rooturi),
+ ".conduit")
+ return rooturi,path
+
+def save_removable_volume_group_file(folderUri, folderGroupName):
+ if is_on_removable_volume(folderUri):
+ #write to the /volume/root/.conduit file
+ rooturi,path = get_removable_volume_info(folderUri)
+ fp = open(path, "w+r")
+ conf = ConfigParser.SafeConfigParser()
+ conf.readfp(fp)
+ #save the relative path, and the group name
+ #in INI format
+ #
+ #[DEFAULT]
+ #relative/uri/from/volume/root = group name
+ #
+ log.debug("Saving group (%s = %s) to %s" % (folderUri,folderGroupName,path))
+ conf.set(
+ "DEFAULT",
+ folderUri.replace(rooturi,""),
+ folderGroupName
+ )
+ conf.write(fp)
+ fp.close()
+ return True
+ return False
+
+def read_removable_volume_group_file(folderUri):
+ if is_on_removable_volume(folderUri):
+ #read from the /volume/root/.conduit file
+ rooturi,path = get_removable_volume_info(folderUri)
+ if Vfs.uri_exists(path):
+ conf = ConfigParser.SafeConfigParser()
+ fp = open(path, "r")
+ conf.readfp(fp)
+ items = conf.items("DEFAULT")
+ fp.close()
+ for i,j in items:
+ log.debug("Read group (%s = %s)" % (i,j))
+ return items
+ return ()
+
class FileSource(DataProvider.DataSource, Vfs.FolderScannerThreadManager):
_category_ = conduit.dataproviders.CATEGORY_FILES
@@ -172,7 +226,7 @@
self.compareIgnoreMtime = compareIgnoreMtime
self.files = []
-
+
def initialize(self):
return True
@@ -261,6 +315,8 @@
def finish(self, aborted, error, conflict):
DataProvider.TwoWay.finish(self)
self.files = []
+ #Save the .group file to the root of this volume (if it is removable)
+ save_removable_volume_group_file(self.folder, self.folderGroupName)
def add(self, LUID):
f = File.File(URI=LUID)
Modified: trunk/conduit/modules/FileModule/FileModule.py
==============================================================================
--- trunk/conduit/modules/FileModule/FileModule.py (original)
+++ trunk/conduit/modules/FileModule/FileModule.py Fri Mar 14 04:24:05 2008
@@ -15,7 +15,7 @@
MODULES = {
"FileSource" : { "type": "dataprovider" },
"FolderTwoWay" : { "type": "dataprovider" },
-# "RemovableDeviceFactory" : { "type": "dataprovider-factory" }
+ "RemovableDeviceFactory" : { "type": "dataprovider-factory" }
}
class FileSource(FileDataProvider.FileSource):
@@ -68,7 +68,6 @@
DEFAULT_COMPARE_IGNORE_MTIME = False
def __init__(self, *args):
- print "#"*100,self.DEFAULT_FOLDER
FileDataProvider.FolderTwoWay.__init__(self,
self.DEFAULT_FOLDER,
self.DEFAULT_GROUP,
@@ -135,9 +134,10 @@
def __init__(self, **kwargs):
VolumeFactory.VolumeFactory.__init__(self, **kwargs)
- self.foo = {}
+ self._volumes = []
def _make_class(self, folder, name):
+ log.info("Creating preconfigured folder dataprovider: %s" % folder)
klass = type(
"FolderTwoWay",
(FolderTwoWay,),
@@ -156,27 +156,27 @@
prop2 = self._get_properties(props["info.parent"])
if prop2.has_key("storage.removable") and prop2["storage.removable"] == True:
mount,label = self._get_device_info(props)
- #check for the presence of a mount/.conduit file
- #which describe the folder sync groups, and their names,
- #on this volume
- #
- #The format of this file is n lines in the form
- # group_name|path
- # group_name|path
- path = Vfs.uri_join(mount,".conduit")
- if Vfs.uri_exists(path):
- self.foo[udi] = [self._make_class("/tmp",i) for i in range(2)]
+ log.info("Detected removable volume %s %s" % (label,mount))
+ #check for the presence of a mount/.conduit group file
+ #which describe the folder sync groups, and their names,
+ mountUri = "file://%s" % mount
+ for relativeUri,name in FileDataProvider.read_removable_volume_group_file(mountUri):
+ klass = self._make_class(
+ #uri is relative, make it absolute
+ "%s%s" % (mountUri,relativeUri),
+ name)
+ self._volumes.append(klass)
return True
return False
def get_category(self, udi, **kwargs):
return DataProviderCategory.DataProviderCategory(
kwargs['label'],
- "multimedia-player-ipod-video-white",
+ "drive-removable-media",
udi)
def get_dataproviders(self, udi, **kwargs):
- return self.foo[udi]
+ return self._volumes
def get_args(self, udi, **kwargs):
return ()
Modified: trunk/test/python-tests/TestCoreVfs.py
==============================================================================
--- trunk/test/python-tests/TestCoreVfs.py (original)
+++ trunk/test/python-tests/TestCoreVfs.py Fri Mar 14 04:24:05 2008
@@ -36,4 +36,18 @@
ok("Scanned /tmp ok - found %s" % fileuri, "file://"+fileuri in t1.get_uris())
ok("Scanned %s ok (empty)" % tmpdiruri, t2.get_uris() == [])
+# Test the volume management stuff
+ntfsUri = get_external_resources('folder')['ntfs-volume']
+fstype = Vfs.uri_get_filesystem_type(ntfsUri)
+ok("Get filesystem type (%s)" % fstype,fstype == "ntfs")
+ok("Escape illegal chars in filenames", Vfs.uri_sanitize_for_filesystem("invalid:|name",fstype).count(":") == 0)
+
+localUri = get_external_resources('folder')['folder']
+ok("Local uri --> path", Vfs.uri_to_local_path(localUri) == "/tmp")
+ok("Local uri not removable", Vfs.uri_is_on_removable_volume(localUri) == False)
+
+removableUri = get_external_resources('folder')['removable-volume']
+ok("Removable volume detected removable", Vfs.uri_is_on_removable_volume(removableUri))
+ok("Removable volume calculate root path", Vfs.uri_get_volume_root_uri(removableUri) == "file:///media/media")
+
finished()
Added: trunk/test/python-tests/TestDataProviderFolder.py
==============================================================================
--- (empty file)
+++ trunk/test/python-tests/TestDataProviderFolder.py Fri Mar 14 04:24:05 2008
@@ -0,0 +1,17 @@
+#common sets up the conduit environment
+from common import *
+
+import conduit.dataproviders.File as FileDataProvider
+import conduit.Vfs as Vfs
+
+#Test removable volume support
+removableUri = get_external_resources('folder')['removable-volume']
+ok("Is on a removable volume", FileDataProvider.is_on_removable_volume(removableUri))
+
+#save and restore a group
+groupName = "GroupName Is Lame"
+groupInfo = (removableUri, groupName)
+ok("Save group info", FileDataProvider.save_removable_volume_group_file(*groupInfo))
+readInfo = FileDataProvider.read_removable_volume_group_file(removableUri)
+ok("Read group info (%s)" % str(readInfo), len(readInfo) > 0 and readInfo[0][1] == groupName)
+finished()
Added: trunk/test/python-tests/data/folder.list
==============================================================================
--- (empty file)
+++ trunk/test/python-tests/data/folder.list Fri Mar 14 04:24:05 2008
@@ -0,0 +1,15 @@
+#So that we dont have to keep a bunch of files in svn or on the web
+#to run the test suite on different machines, this file allows locations
+#to be specified in a section (as returned by Utils.get_user_string())
+#
+#Note: Items in the default section should always be accessible
+#Note: If two items have the same key, the one in your section replaces
+#the one in the default section
+[DEFAULT]
+folder=file:///tmp
+
+[john nzjrs-desktop]
+removable-volume=file:///media/media/MusicToSort/Kora
+ntfs-volume=file:///media/windows
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]