Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/journal
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/journal')
-rw-r--r--src/jarabe/journal/Makefile.am1
-rw-r--r--src/jarabe/journal/journaltoolbox.py18
-rw-r--r--src/jarabe/journal/volumesmanager.py321
-rw-r--r--src/jarabe/journal/volumestoolbar.py58
4 files changed, 39 insertions, 359 deletions
diff --git a/src/jarabe/journal/Makefile.am b/src/jarabe/journal/Makefile.am
index 11886d6..a8ef90f 100644
--- a/src/jarabe/journal/Makefile.am
+++ b/src/jarabe/journal/Makefile.am
@@ -14,5 +14,4 @@ sugar_PYTHON = \
objectchooser.py \
palettes.py \
query.py \
- volumesmanager.py \
volumestoolbar.py
diff --git a/src/jarabe/journal/journaltoolbox.py b/src/jarabe/journal/journaltoolbox.py
index 7e2709f..637965f 100644
--- a/src/jarabe/journal/journaltoolbox.py
+++ b/src/jarabe/journal/journaltoolbox.py
@@ -36,7 +36,7 @@ from sugar import mime
from sugar.datastore import datastore
from jarabe.model import bundleregistry
-from jarabe.journal import volumesmanager
+from jarabe.model import volume
from jarabe.journal import misc
_AUTOSEARCH_TIMEOUT = 1000
@@ -374,9 +374,9 @@ class EntryToolbar(gtk.Toolbar):
if self._jobject:
misc.resume(self._jobject, service_name)
- def _copy_menu_item_activate_cb(self, menu_item, volume):
+ def _copy_menu_item_activate_cb(self, menu_item, vol):
if self._jobject:
- datastore.copy(self._jobject, volume.id)
+ datastore.copy(self._jobject, vol.id)
def _refresh_copy_palette(self):
palette = self._copy.get_palette()
@@ -385,16 +385,16 @@ class EntryToolbar(gtk.Toolbar):
palette.menu.remove(menu_item)
menu_item.destroy()
- volumes_manager = volumesmanager.get_volumes_manager()
- for volume in volumes_manager.get_volumes():
- if self._jobject.metadata['mountpoint'] == volume.id:
+ volumes_manager = volume.get_volumes_manager()
+ for vol in volumes_manager.get_volumes():
+ if self._jobject.metadata['mountpoint'] == vol.id:
continue
- menu_item = MenuItem(volume.name)
- menu_item.set_image(Icon(icon_name=volume.icon_name,
+ menu_item = MenuItem(vol.name)
+ menu_item.set_image(Icon(icon_name=vol.icon_name,
icon_size=gtk.ICON_SIZE_MENU))
menu_item.connect('activate',
self._copy_menu_item_activate_cb,
- volume)
+ vol)
palette.menu.append(menu_item)
menu_item.show()
diff --git a/src/jarabe/journal/volumesmanager.py b/src/jarabe/journal/volumesmanager.py
deleted file mode 100644
index b7e1e37..0000000
--- a/src/jarabe/journal/volumesmanager.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# Copyright (C) 2007, One Laptop Per Child
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import logging
-from gettext import gettext as _
-import gconf
-
-import gobject
-import dbus
-
-from sugar.graphics.xocolor import XoColor
-from sugar.datastore import datastore
-
-HAL_SERVICE_NAME = 'org.freedesktop.Hal'
-HAL_MANAGER_PATH = '/org/freedesktop/Hal/Manager'
-HAL_MANAGER_IFACE = 'org.freedesktop.Hal.Manager'
-HAL_DEVICE_IFACE = 'org.freedesktop.Hal.Device'
-HAL_VOLUME_IFACE = 'org.freedesktop.Hal.Device.Volume'
-
-MOUNT_OPTION_UID = 500
-MOUNT_OPTION_UMASK = 000
-
-_volumes_manager = None
-
-class VolumesManager(gobject.GObject):
-
- __gtype_name__ = 'VolumesManager'
-
- __gsignals__ = {
- 'volume-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object])),
- 'volume-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object]))
- }
-
- def __init__(self):
- gobject.GObject.__init__(self)
-
- self._volumes = []
-
- client = gconf.client_get_default()
- color = XoColor(client.get_string('/desktop/sugar/user/color'))
-
- # Internal flash is not in HAL
- internal_fash_id = datastore.mounts()[0]['id']
- self._volumes.append(Volume(internal_fash_id, _('Journal'),
- 'activity-journal', color,
- None, False))
-
- bus = dbus.SystemBus()
- proxy = bus.get_object(HAL_SERVICE_NAME, HAL_MANAGER_PATH)
- self._hal_manager = dbus.Interface(proxy, HAL_MANAGER_IFACE)
- self._hal_manager.connect_to_signal('DeviceAdded',
- self._hal_device_added_cb)
-
- for udi in self._hal_manager.FindDeviceByCapability('volume'):
- if self._is_device_relevant(udi):
- try:
- self._add_hal_device(udi)
- except Exception, e:
- logging.error('Exception when mounting device %r: %r' % \
- (udi, e))
-
- def get_volumes(self):
- return self._volumes
-
- def _get_volume_by_udi(self, udi):
- for volume in self._volumes:
- if volume.udi == udi:
- return volume
- return None
-
- def _hal_device_added_cb(self, udi):
- bus = dbus.SystemBus()
- device_object = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(device_object, HAL_DEVICE_IFACE)
- if device.QueryCapability('volume'):
- logging.debug('VolumesManager._hal_device_added_cb: %r', udi)
- if self._is_device_relevant(udi):
- self._add_hal_device(udi)
-
- def _is_device_relevant(self, udi):
- bus = dbus.SystemBus()
- device_object = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(device_object, HAL_DEVICE_IFACE)
-
- # Ignore volumes without a filesystem.
- if device.GetProperty('volume.fsusage') != 'filesystem':
- return False
- # Ignore root.
- if device.GetProperty('volume.mount_point') == '/':
- return False
-
- storage_udi = device.GetProperty('block.storage_device')
- obj = bus.get_object(HAL_SERVICE_NAME, storage_udi)
- storage_device = dbus.Interface(obj, HAL_DEVICE_IFACE)
-
- # Ignore non-removable storage.
- if not storage_device.GetProperty('storage.hotpluggable'):
- return False
-
- return True
-
- def _add_hal_device(self, udi):
- logging.debug('VolumeToolbar._add_hal_device: %r' % udi)
-
- bus = dbus.SystemBus()
- device_object = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(device_object, HAL_DEVICE_IFACE)
-
- # listen to mount/unmount
- device.connect_to_signal('PropertyModified',
- lambda *args: self._hal_device_property_modified_cb(udi, *args))
-
- bus.add_signal_receiver(self._hal_device_removed_cb,
- 'DeviceRemoved',
- HAL_MANAGER_IFACE, HAL_SERVICE_NAME,
- HAL_MANAGER_PATH, arg0=udi)
-
- if device.GetProperty('volume.is_mounted'):
- volume_id = self._mount_in_datastore(udi)
- return
-
- label = device.GetProperty('volume.label')
- fs_type = device.GetProperty('volume.fstype')
- valid_options = device.GetProperty('volume.mount.valid_options')
- options = []
-
- if 'uid=' in valid_options:
- options.append('uid=%i' % MOUNT_OPTION_UID)
-
- if 'umask=' in valid_options:
- options.append('umask=%i' % MOUNT_OPTION_UMASK)
-
- if 'noatime' in valid_options:
- options.append('noatime')
-
- if 'utf8' in valid_options:
- options.append('utf8')
-
- if 'iocharset=' in valid_options:
- options.append('iocharset=utf8')
-
- mount_point = label
- if not mount_point:
- mount_point = device.GetProperty('volume.uuid')
-
- volume = dbus.Interface(device_object, HAL_VOLUME_IFACE)
-
- # Try 100 times to get a mount point
- mounted = False
- i = 0
- while not mounted:
- try:
- if i > 0:
- volume.Mount('%s_%d' % (mount_point, i), fs_type, options)
- else:
- volume.Mount(mount_point, fs_type, options)
- mounted = True
- except dbus.DBusException, e:
- s = 'org.freedesktop.Hal.Device.Volume.MountPointNotAvailable'
- if i < 100 and e.get_dbus_name() == s:
- i += 1
- else:
- raise
-
- def _hal_device_property_modified_cb(self, udi, count, changes):
- if 'volume.is_mounted' in [change[0] for change in changes]:
- logging.debug('VolumesManager._hal_device_property_modified: %r' % \
- (udi))
- bus = dbus.SystemBus()
- #proxy = bus.get_object(HAL_SERVICE_NAME, HAL_MANAGER_PATH)
- #hal_manager = dbus.Interface(proxy, HAL_MANAGER_IFACE)
- # TODO: Why this doesn't work?
- #if not hal_manager.DeviceExists(udi):
- # return
-
- proxy = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(proxy, HAL_DEVICE_IFACE)
- try:
- is_mounted = device.GetProperty('volume.is_mounted')
- except dbus.DBusException, e:
- logging.debug('e: %s' % e)
- return
-
- if is_mounted:
- if self._get_volume_by_udi(udi) is not None:
- # device already mounted in the datastore
- return
- volume_id = self._mount_in_datastore(udi)
- else:
- self.unmount_from_datastore(udi)
- return
-
- def _mount_in_datastore(self, udi):
- logging.debug('VolumeToolbar._mount_in_datastore: %r' % udi)
-
- bus = dbus.SystemBus()
- device_object = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(device_object, HAL_DEVICE_IFACE)
-
- mount_point = device.GetProperty('volume.mount_point')
- ds_mounts = datastore.mounts()
- for ds_mount in ds_mounts:
- if mount_point == ds_mount['uri']:
- return ds_mount['id']
-
- mount_id = datastore.mount('inplace:' + mount_point,
- dict(title=mount_point))
- if not mount_id:
- self._unmount_hal_device(udi)
- raise RuntimeError('datastore.mount(%r, %r) failed.' % (
- 'inplace:' + mount_point,
- dict(title=mount_point)))
-
- volume_name = device.GetProperty('volume.label')
- if not volume_name:
- volume_name = device.GetProperty('volume.uuid')
- client = gconf.client_get_default()
- color = XoColor(client.get_string('/desktop/sugar/user/color'))
- volume = Volume(mount_id,
- volume_name,
- self._get_icon_for_volume(udi),
- color,
- udi,
- True)
- self._volumes.append(volume)
- self.emit('volume-added', volume)
-
- logging.debug('mounted volume %s' % mount_point)
-
- def _hal_device_removed_cb(self, udi):
- logging.debug('VolumesManager._hal_device_removed_cb: %r', udi)
- bus = dbus.SystemBus()
- #proxy = bus.get_object(HAL_SERVICE_NAME, HAL_MANAGER_PATH)
- #hal_manager = dbus.Interface(proxy, HAL_MANAGER_IFACE)
- # TODO: Why this doesn't work?
- #if not hal_manager.DeviceExists(udi):
- # self._unmount_from_datastore(udi)
- # self._remove_button(udi)
- # return
-
- proxy = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(proxy, HAL_DEVICE_IFACE)
- try:
- is_mounted = device.GetProperty('volume.is_mounted')
- except dbus.DBusException, e:
- logging.debug('e: %s' % e)
- self.unmount_from_datastore(udi)
- return
-
- if is_mounted:
- self._unmount_from_datastore(udi)
- self._unmount_hal_device(udi)
-
- def unmount_from_datastore(self, udi):
- logging.debug('VolumesManager._unmount_from_datastore: %r', udi)
- volume = self._get_volume_by_udi(udi)
- if volume is not None:
- datastore.unmount(volume.id)
-
- self._volumes.remove(volume)
- self.emit('volume-removed', volume)
-
- def unmount_hal_device(self, udi):
- logging.debug('VolumesManager._unmount_hal_device: %r', udi)
- bus = dbus.SystemBus()
- device_object = bus.get_object(HAL_SERVICE_NAME, udi)
- volume = dbus.Interface(device_object, HAL_VOLUME_IFACE)
- volume.Unmount([])
-
- def _get_icon_for_volume(self, udi):
- bus = dbus.SystemBus()
- device_object = bus.get_object(HAL_SERVICE_NAME, udi)
- device = dbus.Interface(device_object, HAL_DEVICE_IFACE)
-
- storage_udi = device.GetProperty('block.storage_device')
- obj = bus.get_object(HAL_SERVICE_NAME, storage_udi)
- storage_device = dbus.Interface(obj, HAL_DEVICE_IFACE)
-
- storage_drive_type = storage_device.GetProperty('storage.drive_type')
- if storage_drive_type == 'sd_mmc':
- return 'media-flash-sd-mmc'
- else:
- return 'media-flash-usb'
-
-class Volume(object):
- def __init__(self, volume_id, name, icon_name, icon_color, udi,
- can_unmount):
- self.id = volume_id
- self.name = name
- self.icon_name = icon_name
- self.icon_color = icon_color
- self.udi = udi
- self.can_unmount = can_unmount
-
- def unmount(self):
- get_volumes_manager().unmount_from_datastore(self.udi)
- get_volumes_manager().unmount_hal_device(self.udi)
-
-def get_volumes_manager():
- global _volumes_manager
- if _volumes_manager is None:
- _volumes_manager = VolumesManager()
- return _volumes_manager
-
diff --git a/src/jarabe/journal/volumestoolbar.py b/src/jarabe/journal/volumestoolbar.py
index 736a130..b29f325 100644
--- a/src/jarabe/journal/volumestoolbar.py
+++ b/src/jarabe/journal/volumestoolbar.py
@@ -24,7 +24,7 @@ from sugar.datastore import datastore
from sugar.graphics.radiotoolbutton import RadioToolButton
from sugar.graphics.palette import Palette
-from jarabe.journal import volumesmanager
+from jarabe.model import volume
class VolumesToolbar(gtk.Toolbar):
__gtype_name__ = 'VolumesToolbar'
@@ -43,43 +43,45 @@ class VolumesToolbar(gtk.Toolbar):
self.connect('destroy', self.__destroy_cb)
- gobject.idle_add(self._set_up_volumes)
+ # TODO: It's unclear now how removable devices will be handled in the
+ # Journal. Disable for now.
+ #gobject.idle_add(self._set_up_volumes)
def __destroy_cb(self, widget):
- volumes_manager = volumesmanager.get_volumes_manager()
+ volumes_manager = volume.get_volumes_manager()
volumes_manager.disconnect(self._volume_added_hid)
volumes_manager.disconnect(self._volume_removed_hid)
def _set_up_volumes(self):
- volumes_manager = volumesmanager.get_volumes_manager()
+ volumes_manager = volume.get_volumes_manager()
self._volume_added_hid = \
volumes_manager.connect('volume-added', self._volume_added_cb)
self._volume_removed_hid = \
volumes_manager.connect('volume-removed',
self._volume_removed_cb)
- for volume in volumes_manager.get_volumes():
- self._add_button(volume)
+ for vol in volumes_manager.get_volumes():
+ self._add_button(vol)
- def _volume_added_cb(self, volumes_manager, volume):
- self._add_button(volume)
+ def _volume_added_cb(self, volumes_manager, vol):
+ self._add_button(vol)
- def _volume_removed_cb(self, volumes_manager, volume):
- self._remove_button(volume)
+ def _volume_removed_cb(self, volumes_manager, vol):
+ self._remove_button(vol)
- def _add_button(self, volume):
- logging.debug('VolumeToolbar._add_button: %r' % volume.name)
+ def _add_button(self, vol):
+ logging.debug('VolumeToolbar._add_button: %r' % vol.name)
if self._volume_buttons:
group = self._volume_buttons[0]
else:
group = None
- palette = Palette(volume.name)
+ palette = Palette(vol.name)
- button = VolumeButton(volume, group)
+ button = VolumeButton(vol, group)
button.set_palette(palette)
- button.connect('toggled', self._button_toggled_cb, volume)
+ button.connect('toggled', self._button_toggled_cb, vol)
if self._volume_buttons:
position = self.get_item_index(self._volume_buttons[-1]) + 1
else:
@@ -89,26 +91,26 @@ class VolumesToolbar(gtk.Toolbar):
self._volume_buttons.append(button)
- if volume.can_unmount:
+ if vol.can_unmount:
menu_item = gtk.MenuItem(_('Unmount'))
- menu_item.connect('activate', self._unmount_activated_cb, volume)
+ menu_item.connect('activate', self._unmount_activated_cb, vol)
palette.menu.append(menu_item)
menu_item.show()
if len(self.get_children()) > 1:
self.show()
- def _button_toggled_cb(self, button, volume):
+ def _button_toggled_cb(self, button, vol):
if button.props.active:
- self.emit('volume-changed', volume.id)
+ self.emit('volume-changed', vol.id)
- def _unmount_activated_cb(self, menu_item, volume):
- logging.debug('VolumesToolbar._unmount_activated_cb: %r', volume.udi)
- volume.unmount()
+ def _unmount_activated_cb(self, menu_item, vol):
+ logging.debug('VolumesToolbar._unmount_activated_cb: %r', vol.udi)
+ vol.unmount()
- def _remove_button(self, volume):
+ def _remove_button(self, vol):
for button in self.get_children():
- if button.volume.id == volume.id:
+ if button.volume.id == vol.id:
self._volume_buttons.remove(button)
self.remove(button)
self.get_children()[0].props.active = True
@@ -118,13 +120,13 @@ class VolumesToolbar(gtk.Toolbar):
return
class VolumeButton(RadioToolButton):
- def __init__(self, volume, group):
+ def __init__(self, vol, group):
RadioToolButton.__init__(self)
- self.props.named_icon = volume.icon_name
- self.props.xo_color = volume.icon_color
+ self.props.named_icon = vol.icon_name
+ self.props.xo_color = vol.icon_color
self.props.group = group
- self.volume = volume
+ self.volume = vol
self.drag_dest_set(gtk.DEST_DEFAULT_ALL,
[('journal-object-id', 0, 0)],
gtk.gdk.ACTION_COPY)