Merge branch 'master' of github.com:sugarlabs/sugar-toolkit-gtk3
This commit is contained in:
		
						commit
						4b1a0a1bda
					
				@ -14,3 +14,37 @@
 | 
				
			|||||||
# License along with this library; if not, write to the
 | 
					# License along with this library; if not, write to the
 | 
				
			||||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
					# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
				
			||||||
# Boston, MA 02111-1307, USA.
 | 
					# Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from gi.repository import Gio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from sugar3.bundle.activitybundle import ActivityBundle
 | 
				
			||||||
 | 
					from sugar3.bundle.contentbundle import ContentBundle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def bundle_from_archive(path, mime_type=None):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Return an appropriate Bundle object for a given file path.
 | 
				
			||||||
 | 
					    The bundle type is identified by mime_type, which is guessed if not
 | 
				
			||||||
 | 
					    provided.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if mime_type is None:
 | 
				
			||||||
 | 
					        mime_type, certainty = Gio.content_type_guess(path, data=None)
 | 
				
			||||||
 | 
					    if mime_type == ActivityBundle.MIME_TYPE:
 | 
				
			||||||
 | 
					        return ActivityBundle(path)
 | 
				
			||||||
 | 
					    elif mime_type == ContentBundle.MIME_TYPE:
 | 
				
			||||||
 | 
					        return ContentBundle(path)
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def bundle_from_dir(path):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Return an appropriate Bundle object for a given directory containing
 | 
				
			||||||
 | 
					    an unzipped bundle.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if os.path.exists(os.path.join(path, 'activity', 'activity.info')):
 | 
				
			||||||
 | 
					        return ActivityBundle(path)
 | 
				
			||||||
 | 
					    elif os.path.exists(os.path.join(path, 'library', 'library.info')):
 | 
				
			||||||
 | 
					        return ContentBundle(path)
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
				
			|||||||
@ -226,10 +226,6 @@ class ActivityBundle(Bundle):
 | 
				
			|||||||
            raise NotInstalledException
 | 
					            raise NotInstalledException
 | 
				
			||||||
        return os.path.join(self._path, 'icons')
 | 
					        return os.path.join(self._path, 'icons')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_path(self):
 | 
					 | 
				
			||||||
        """Get the activity bundle path."""
 | 
					 | 
				
			||||||
        return self._path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_name(self):
 | 
					    def get_name(self):
 | 
				
			||||||
        """Get the activity user-visible name."""
 | 
					        """Get the activity user-visible name."""
 | 
				
			||||||
        return self._name
 | 
					        return self._name
 | 
				
			||||||
@ -287,9 +283,8 @@ class ActivityBundle(Bundle):
 | 
				
			|||||||
        """Get whether there should be a visible launcher for the activity"""
 | 
					        """Get whether there should be a visible launcher for the activity"""
 | 
				
			||||||
        return self._show_launcher
 | 
					        return self._show_launcher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def install(self, install_dir=None):
 | 
					    def install(self):
 | 
				
			||||||
        if install_dir is None:
 | 
					        install_dir = env.get_user_activities_path()
 | 
				
			||||||
            install_dir = env.get_user_activities_path()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._unzip(install_dir)
 | 
					        self._unzip(install_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -348,7 +343,9 @@ class ActivityBundle(Bundle):
 | 
				
			|||||||
            os.unlink(dst)
 | 
					            os.unlink(dst)
 | 
				
			||||||
        os.symlink(src, dst)
 | 
					        os.symlink(src, dst)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def uninstall(self, install_path, force=False, delete_profile=False):
 | 
					    def uninstall(self, force=False, delete_profile=False):
 | 
				
			||||||
 | 
					        install_path = self.get_path()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if os.path.islink(install_path):
 | 
					        if os.path.islink(install_path):
 | 
				
			||||||
            # Don't remove the actual activity dir if it's a symbolic link
 | 
					            # Don't remove the actual activity dir if it's a symbolic link
 | 
				
			||||||
            # because we may be removing user data.
 | 
					            # because we may be removing user data.
 | 
				
			||||||
 | 
				
			|||||||
@ -26,8 +26,7 @@ import os
 | 
				
			|||||||
import urllib
 | 
					import urllib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from sugar3 import env
 | 
					from sugar3 import env
 | 
				
			||||||
from sugar3.bundle.bundle import Bundle, NotInstalledException, \
 | 
					from sugar3.bundle.bundle import Bundle, MalformedBundleException
 | 
				
			||||||
    MalformedBundleException
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from sugar3.bundle.bundleversion import NormalizedVersion
 | 
					from sugar3.bundle.bundleversion import NormalizedVersion
 | 
				
			||||||
from sugar3.bundle.bundleversion import InvalidVersionError
 | 
					from sugar3.bundle.bundleversion import InvalidVersionError
 | 
				
			||||||
@ -185,6 +184,10 @@ class ContentBundle(Bundle):
 | 
				
			|||||||
    def get_activity_start(self):
 | 
					    def get_activity_start(self):
 | 
				
			||||||
        return self._activity_start
 | 
					        return self._activity_start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_icon(self):
 | 
				
			||||||
 | 
					        # To be implemented later
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _run_indexer(self):
 | 
					    def _run_indexer(self):
 | 
				
			||||||
        xdg_data_dirs = os.getenv('XDG_DATA_DIRS',
 | 
					        xdg_data_dirs = os.getenv('XDG_DATA_DIRS',
 | 
				
			||||||
                                  '/usr/local/share/:/usr/share/')
 | 
					                                  '/usr/local/share/:/usr/share/')
 | 
				
			||||||
@ -215,29 +218,17 @@ class ContentBundle(Bundle):
 | 
				
			|||||||
        # needs rethinking while fixing ContentBundle support
 | 
					        # needs rethinking while fixing ContentBundle support
 | 
				
			||||||
        return self._library_version
 | 
					        return self._library_version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_installed(self):
 | 
					 | 
				
			||||||
        if self._zip_file is None:
 | 
					 | 
				
			||||||
            return True
 | 
					 | 
				
			||||||
        elif os.path.isdir(self.get_root_dir()):
 | 
					 | 
				
			||||||
            return ContentBundle(self.get_root_dir()).get_library_version() \
 | 
					 | 
				
			||||||
                == self.get_library_version()
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def install(self):
 | 
					    def install(self):
 | 
				
			||||||
        # TODO ignore passed install_path argument
 | 
					 | 
				
			||||||
        # needs rethinking while fixing ContentBundle support
 | 
					 | 
				
			||||||
        install_path = env.get_user_library_path()
 | 
					        install_path = env.get_user_library_path()
 | 
				
			||||||
        self._unzip(install_path)
 | 
					        self._unzip(install_path)
 | 
				
			||||||
        self._run_indexer()
 | 
					        self._run_indexer()
 | 
				
			||||||
        return self.get_root_dir()
 | 
					        return self.get_root_dir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def uninstall(self):
 | 
					    def uninstall(self, force=False, delete_profile=False):
 | 
				
			||||||
        if self._zip_file is None:
 | 
					        install_dir = self._path
 | 
				
			||||||
            if not self.is_installed():
 | 
					 | 
				
			||||||
                raise NotInstalledException
 | 
					 | 
				
			||||||
            install_dir = self._path
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            install_dir = os.path.join(self.get_root_dir())
 | 
					 | 
				
			||||||
        self._uninstall(install_dir)
 | 
					        self._uninstall(install_dir)
 | 
				
			||||||
        self._run_indexer()
 | 
					        self._run_indexer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_user_activity(self):
 | 
				
			||||||
 | 
					        # All content bundles are installed in user storage
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
				
			|||||||
@ -125,8 +125,12 @@ class ObjectChooser(object):
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            what_filter = self._what_filter
 | 
					            what_filter = self._what_filter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._chooser_id = journal.ChooseObjectWithFilter(
 | 
					        if self._filter_type is None:
 | 
				
			||||||
            self._parent_xid, what_filter, self._filter_type)
 | 
					            self._chooser_id = journal.ChooseObject(
 | 
				
			||||||
 | 
					                self._parent_xid, what_filter)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._chooser_id = journal.ChooseObjectWithFilter(
 | 
				
			||||||
 | 
					                self._parent_xid, what_filter, self._filter_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Gdk.threads_leave()
 | 
					        Gdk.threads_leave()
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										0
									
								
								tests/data/sample.content/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/data/sample.content/index.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										10
									
								
								tests/data/sample.content/library/library.info
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/data/sample.content/library/library.info
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					[Library]
 | 
				
			||||||
 | 
					name = sample
 | 
				
			||||||
 | 
					long_name = sample
 | 
				
			||||||
 | 
					global_name = org.sugarlabs.samplecontent
 | 
				
			||||||
 | 
					library_version = 1
 | 
				
			||||||
 | 
					host_version = 1
 | 
				
			||||||
 | 
					l10n = false
 | 
				
			||||||
 | 
					locale = en
 | 
				
			||||||
 | 
					license = CC-BY 2.0
 | 
				
			||||||
 | 
					category = media
 | 
				
			||||||
							
								
								
									
										49
									
								
								tests/test_bundle.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								tests/test_bundle.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2013, 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 os
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from sugar3.bundle import bundle_from_dir, bundle_from_archive
 | 
				
			||||||
 | 
					from sugar3.bundle.activitybundle import ActivityBundle
 | 
				
			||||||
 | 
					from sugar3.bundle.contentbundle import ContentBundle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tests_dir = os.path.dirname(__file__)
 | 
				
			||||||
 | 
					data_dir = os.path.join(tests_dir, "data")
 | 
				
			||||||
 | 
					SAMPLE_ACTIVITY_PATH = os.path.join(data_dir, 'sample.activity')
 | 
				
			||||||
 | 
					SAMPLE_CONTENT_PATH = os.path.join(data_dir, 'sample.content')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestBundle(unittest.TestCase):
 | 
				
			||||||
 | 
					    def test_bundle_from_dir(self):
 | 
				
			||||||
 | 
					        bundle = bundle_from_dir(SAMPLE_ACTIVITY_PATH)
 | 
				
			||||||
 | 
					        self.assertIsInstance(bundle, ActivityBundle)
 | 
				
			||||||
 | 
					        bundle = bundle_from_dir(SAMPLE_CONTENT_PATH)
 | 
				
			||||||
 | 
					        self.assertIsInstance(bundle, ContentBundle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_activity_bundle_from_archive(self):
 | 
				
			||||||
 | 
					        os.chdir(SAMPLE_ACTIVITY_PATH)
 | 
				
			||||||
 | 
					        subprocess.check_call(["./setup.py", "dist_xo"])
 | 
				
			||||||
 | 
					        xo_path = os.path.join(".", "dist", "Sample-1.xo")
 | 
				
			||||||
 | 
					        bundle = bundle_from_archive(xo_path)
 | 
				
			||||||
 | 
					        self.assertIsInstance(bundle, ActivityBundle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_content_bundle_from_archive(self):
 | 
				
			||||||
 | 
					        os.chdir(data_dir)
 | 
				
			||||||
 | 
					        subprocess.check_call(["zip", "-r", "sample-1.xol", "sample.content"])
 | 
				
			||||||
 | 
					        bundle = bundle_from_archive("./sample-1.xol")
 | 
				
			||||||
 | 
					        self.assertIsInstance(bundle, ContentBundle)
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user