diff options
author | Muayyad Alsadi <alsadi@ojuba.org> | 2009-07-28 22:35:50 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2009-07-28 22:36:21 +0100 |
commit | 3a75f454a53294a62a8f1eb93d0c3e53cc02a966 (patch) | |
tree | 97f97766a229a039e55d95a0d385201bcb36a959 | |
parent | 816307af5d6f4f424ccf84f98621f6dc72380413 (diff) |
Add the start of MediaManager code for external media handling
Signed-off-by: Richard Hughes <richard@hughsie.com>
-rw-r--r-- | backends/yum/Makefile.am | 1 | ||||
-rwxr-xr-x | backends/yum/yumBackend.py | 107 | ||||
-rw-r--r-- | backends/yum/yumMediaManager.py | 84 |
3 files changed, 191 insertions, 1 deletions
diff --git a/backends/yum/Makefile.am b/backends/yum/Makefile.am index a91c5b0cd..b5f61d1b0 100644 --- a/backends/yum/Makefile.am +++ b/backends/yum/Makefile.am @@ -3,6 +3,7 @@ dist_helper_DATA = \ yum-comps-groups.conf \ yumBackend.py \ yumComps.py \ + yumMediaManager.py \ yumFilter.py plugindir = $(PK_PLUGIN_DIR) diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py index b26ba0c1a..0bccc8475 100755 --- a/backends/yum/yumBackend.py +++ b/backends/yum/yumBackend.py @@ -15,20 +15,26 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# Copyright (C) 2007-2008 +# Copyright (C) 2007-2009 # Tim Lauridsen <timlau@fedoraproject.org> # Seth Vidal <skvidal@fedoraproject.org> # Luke Macken <lmacken@redhat.com> # James Bowes <jbowes@dangerouslyinc.com> # Robin Norwood <rnorwood@redhat.com> # Richard Hughes <richard@hughsie.com> +# +# MediaGrabber: +# Based on the logic of pirut by Jeremy Katz <katzj@redhat.com> +# Rewritten by Muayyad Alsadi <alsadi@ojuba.org> # imports from packagekit.backend import * from packagekit.progress import * +from packagekit.enums import * from packagekit.package import PackagekitPackage import yum from urlgrabber.progress import BaseMeter, format_number +from urlgrabber.grabber import URLGrabber, URLGrabError from yum.rpmtrans import RPMBaseCallback from yum.constants import * from yum.update_md import UpdateMetadata @@ -52,6 +58,7 @@ import ConfigParser from yumFilter import * from yumComps import * +from yumMediaManager import MediaManager # Global vars yumbase = None @@ -2805,6 +2812,7 @@ class PackageKitYumBase(yum.YumBase): self.missingGPGKey = None self.dsCallback = DepSolveCallback(backend) self.backend = backend + self.mediagrabber = self.MediaGrabber # Setup Repo GPG support callbacks try: self.repos.confirm_func = self._repo_gpg_confirm @@ -2816,6 +2824,103 @@ class PackageKitYumBase(yum.YumBase): else: raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc())) + def MediaGrabber(self, *args, **kwargs): + """ + Handle physical media. + + This module can be summarized like this: + For all media: + - Lock it + - If not mounted: mount it + - If it's the wanted media: break + - If no media found: ask the user to insert it and loop again + .... + Release the media + """ + media_id = kwargs["mediaid"] + disc_number = kwargs["discnum"] + name = kwargs["name"] + discs_s = '' + found = False + + manager = MediaManager() + media = None + found = False + + # loop over and over, retry because the user might insert disc #2 when we need disc #5 + while 1: + # check for the needed media in every media provided by yumMediaManager + for media in manager: + # mnt now holds the mount point + mnt = media.acquire() + found = False + + # if not mounted skip this media for this loop + if not mnt: + continue + + # load ".discinfo" from the media and parse it + if os.path.exists("%s/.discinfo" %(mnt,)): + f = open("%s/.discinfo" %(mnt,), "r") + lines = f.readlines() + f.close() + theid = lines[0].strip() + discs_s = lines[3].strip() + + # if discs_s == ALL then no need to match disc number + if discs_s != 'ALL': + discs = map(lambda x: int(x), discs_s.split(",")) + samenum = disc_number in discs + else: + samenum = True + + # if the media is different or of different number skip it and loop over + if media_id != theid or not samenum: + continue + + # the actual copying is done by URLGrabber + ug = URLGrabber(checkfunc = kwargs["checkfunc"]) + try: + ug.urlgrab("%s/%s" %(mnt, kwargs["relative"]), + kwargs["local"], text=kwargs["text"], + range=kwargs["range"], copy_local=1) + except (IOError, URLGrabError): + pass + else: + found = True + + # if we found it end the for loop + if found: + break + + # if we found it end the while loop + if found: + break + + # construct human readable media_text + if disc_number: + media_text = "%s #%d" % (name, disc_number) + else: + media_text = name + + # see http://lists.freedesktop.org/archives/packagekit/2009-May/004808.html + # and http://cgit.freedesktop.org/packagekit/commit/?id=79e8736197b552a5ce206a712cd3b6c80cf2e86d + self.backend.media_change_required(MEDIA_TYPE_DISC, name, media_text) + self.backend.error(ERROR_MEDIA_CHANGE_REQUIRED, + "Insert media labeled '%s' or disable media repos" % media_text, + exit = False) + break + + # if we got a media object destruct it to release the media (which will unmount and unlock if needed) + if media: + del media + + # I guess we come here when the user in PK clicks cancel + if not found: + # yumRepo will catch this + raise yum.Errors.MediaError, "The disc was not inserted" + return kwargs["local"] + def _repo_gpg_confirm(self, keyData): """ Confirm Repo GPG signature import """ if not keyData: diff --git a/backends/yum/yumMediaManager.py b/backends/yum/yumMediaManager.py new file mode 100644 index 000000000..9f1db4336 --- /dev/null +++ b/backends/yum/yumMediaManager.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# Licensed under the GNU General Public License Version 2 +# +# 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. + +# Copyright (C) 2009 +# Muayyad Saleh Alsadi <alsadi@ojuba.org> + +""" +This is a module for dealing with removable media +NOTE: releasing (unmounting and unlocking) is done when media is destructed +""" + +class MediaDevice(object): + """ + You should just use acquire() to get the mount point (the implementation is + supposed to be smart enough to return mount point when it's already mounted) + You don't need to manually call release(), just destruct MediaDevice object + and the implementation should do that if needed. + """ + def __init__(self, media_id): + """ + media_id argument is the implementation-specific id, provided by MediaManager. + """ + self._unmount_needed = False + self._unlocked_needed = False + raise NotImplemented + + def __del__(self): + if self._unmount_needed: + self.unmount() + if self._unlocked_needed: + self.unlock() + + def is_removable(self): + raise NotImplemented + + def is_mounted(self): + raise NotImplemented + + def is_locked(self): + raise NotImplemented + + def get_mount_point(self): + raise NotImplemented + + def lock(self): + raise NotImplemented + + def unlock(self): + raise NotImplemented + + def mount(self): + raise NotImplemented + + def unmount(self): + raise NotImplemented + + def acquire(self): + raise NotImplemented + + def release(self): + raise NotImplemented + +class MediaManager (object): + """Just iterate over an instance of this class to get MediaDevice objects""" + def __init__(self): + raise NotImplemented + + def __iter__(self): + raise NotImplemented + |