OSDN Git Service

implement Install Events
authorShyouzou Sugitani <shy@users.sourceforge.jp>
Sun, 10 Nov 2013 13:52:56 +0000 (22:52 +0900)
committerShyouzou Sugitani <shy@users.sourceforge.jp>
Sun, 10 Nov 2013 13:52:56 +0000 (22:52 +0900)
ChangeLog
lib/ninix/communicate.py
lib/ninix/install.py
lib/ninix_main.py

index beabb1e..3309f92 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun November 10 2013   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * 以下のインストールイベントを実装した.
+         OnInstallBegin
+         OnInstallComplete
+         OnInstallFailure
+         OnKinokoObjectInstalled
+
 Thu November 7 2013   Shyouzou Sugitani <shy@users.sourceforge.jp>
        * リフレッシュインストールの場合には, そうであることが分かる様に
          ファイル削除の警告メッセージを変更した.
index 7f6692c..8800613 100644 (file)
@@ -32,6 +32,10 @@ class Communicate:
         return [chr(1).join(value) for value in self.__ghosts.values() \
                     if value[0] != name]
 
+    def notify_all(self, event, references):
+        for sakura in self.__ghosts.keys():
+            sakura.enqueue_event(event, *references)
+
     ON_OTHER_EVENT = {
         'OnBoot': 'OnOtherGhostBooted',
         'OnFirstBoot': 'OnOtherGhostBooted',
index 5122459..4e23d48 100644 (file)
@@ -134,6 +134,7 @@ class Installer:
         return os.fsencode(tmpdir) # XXX
 
     def get_file_type(self, tmpdir):
+        errno = 0
         # check the file type
         inst = ninix.home.read_install_txt(tmpdir)
         if not inst:
@@ -166,21 +167,40 @@ class Installer:
         elif filetype == 'kinoko':
             pass
         else:
-            fatal('unsupported file type({0})'.format(filetype))
+            errno = 2
+            #fatal('unsupported file type({0})'.format(filetype))
         if filetype in ['shell.inverse', 'ghost.inverse']:
-            fatal('unsupported file type({0})'.format(filetype))
-        return filetype
+            errno = 2
+            #fatal('unsupported file type({0})'.format(filetype))
+        return filetype, errno
 
     def install(self, filename, homedir):
+        errno = 0
         homedir = os.fsencode(homedir) # XXX
-        tmpdir = self.extract_files(filename)
-        filetype = self.get_file_type(tmpdir)
         try:
-            func = getattr(self, 'install_{0}'.format(filetype))
-            target_dirs = func(filename, tmpdir, homedir)
+            tmpdir = self.extract_files(filename)
+        except:
+            errno = 1
+        if errno != 0:
+            return None, None, None, errno
+        try:
+            filetype, errno = self.get_file_type(tmpdir)
+        except:
+            errno = 4
+            filetype = None
+        if errno != 0:
+            shutil.rmtree(tmpdir)
+            return filetype, None, None, errno
+        func = getattr(self, 'install_{0}'.format(filetype))
+        try:
+            target_dirs, names, errno = func(filename, tmpdir, homedir)
+        except:
+            target_dirs = None
+            names = None
+            errno = 5
         finally:
             shutil.rmtree(tmpdir)
-        return filetype, target_dirs
+        return filetype, target_dirs, names, errno
 
 
     def download(self, url, basedir):
@@ -342,12 +362,14 @@ class Installer:
         for path in self.list_all_files(ghost_src, b''):
             filelist.append((os.path.join(ghost_src, path),
                              os.path.join(ghost_dst, path)))
+        ghost_name = inst.get('name')
         # find shell
         for path in self.list_all_files(shell_src, b''):
             filelist.append((os.path.join(shell_src, path),
                              os.path.join(shell_dst, path)))
         # find balloon
         balloon_dir = inst and inst.get('balloon.directory')
+        balloon_name = None
         if balloon_dir:
             balloon_dir = ninix.home.get_normalized_path(balloon_dir)
             balloon_dst = os.path.join(homedir, b'balloon', balloon_dir)
@@ -356,6 +378,8 @@ class Installer:
                 balloon_src = ninix.home.get_normalized_path(balloon_src)
             else:
                 balloon_src = balloon_dir
+            inst_balloon = ninix.home.read_install_txt(
+                os.path.join(tmpdir, balloon_src))
             if os.path.exists(balloon_dst) and \
                     not self. confirm_removal(balloon_dst, 'balloon'):
                 pass # don't install balloon
@@ -368,6 +392,7 @@ class Installer:
                     balloon_list.append((os.path.join(tmpdir, balloon_src, path),
                                          os.path.join(balloon_dst, path)))
                 self.install_files(balloon_list)
+                balloon_name = inst_balloon.get('name')
         if os.path.exists(prefix):
             inst_dst = ninix.home.read_install_txt(prefix)
             if inst.get_with_type('refresh', int, 0):
@@ -378,10 +403,10 @@ class Installer:
                     mask.append('HISTORY')
                     self.remove_files_and_dirs(prefix, mask)
                 else:
-                    return
+                    return None, None, 3
             else:
                 if not self.confirm_overwrite(prefix, 'ghost'):
-                    return
+                    return None, None, 3
         # install files
         logging.info('installing {0} (ghost)'.format(archive))
         self.install_files(filelist)
@@ -397,7 +422,8 @@ class Installer:
                 logging.error('cannot write {0}'.format(path))
         if balloon_dir is None: # XXX
             balloon_dir = ''
-        return (os.fsdecode(target_dir), os.fsdecode(balloon_dir))
+        return (os.fsdecode(target_dir), os.fsdecode(balloon_dir)), \
+            (ghost_name, balloon_name), 0
 
     def install_supplement(self, archive, tmpdir, homedir):
         inst = ninix.home.read_install_txt(tmpdir)
@@ -418,10 +444,11 @@ class Installer:
                     candidates.append(dirname)
             if not candidates:
                 logging.info('not found')
+                return None, None, 4
             else:
                 target = self.select(candidates)
                 if target is None:
-                    return
+                    return None, None, 4
                 path = os.path.join(homedir, b'ghost', target)
                 if 'directory' in inst:
                     if inst.get('type') == 'shell':
@@ -431,13 +458,13 @@ class Installer:
                             logging.error('supplement type not specified')
                         else:
                             logging.error('unsupported supplement type: {0}'.format(inst['type']))
-                        return
+                        return None, None, 4
                 logging.info('found')
                 if not os.path.exists(path):
                     os.makedirs(path)
                 os.remove(os.path.join(tmpdir, b'install.txt'))
                 distutils.dir_util.copy_tree(os.fsdecode(tmpdir), os.fsdecode(path))
-                return os.fsdecode(target)
+                return os.fsdecode(target), inst.get('name'), 0
 
     def install_balloon(self, archive, srcdir, homedir):
         # find install.txt
@@ -464,14 +491,14 @@ class Installer:
                                 inst.get('refreshundeletemask', '').split(':')]
                     self.remove_files_and_dirs(dstdir, mask)
                 else:
-                    return
+                    return None, None, 3
             else:
                 if not self.confirm_overwrite(dstdir, 'balloon'):
-                    return
+                    return None, None, 3
         # install files
         logging.info('installing {0} (balloon)'.format(archive))
         self.install_files(filelist)
-        return os.fsdecode(target_dir)
+        return os.fsdecode(target_dir), inst.get('name'), 0
 
     def uninstall_plugin(self, homedir, name):
         try:
@@ -506,7 +533,7 @@ class Installer:
         # install files
         print('installing {0} (plugin)'.format(archive))
         self.install_files(filelist)
-        return plugin_dir
+        return plugin_dir, plugin_name, 0
 
     def uninstall_kinoko(self, homedir, name):
         try:
@@ -547,7 +574,7 @@ class Installer:
         # install files
         logging.info('installing {0} (kinoko)'.format(archive))
         self.install_files(filelist)
-        return dstdir
+        return dstdir, (kinoko_name, kinoko['ghost'], kinoko['category']), 0
 
     def uninstall_nekoninni(self, homedir, dir):
         nekoninni_dir = os.path.join(homedir, b'nekodorif', b'skin', dir)
@@ -577,7 +604,7 @@ class Installer:
         # install files
         logging.info('installing {0} (nekodorif skin)'.format(archive))
         self.install_files(filelist)
-        return target_dir
+        return target_dir, inst.get('name'), 0
 
     def uninstall_katochan(self, homedir, target_dir):
         katochan_dir = os.path.join(
@@ -608,7 +635,7 @@ class Installer:
         # install files
         logging.info('installing {0} (nekodorif katochan)'.format(archive))
         self.install_files(filelist)
-        return target_dir
+        return target_dir, inst.get('name'), 0
 
     def list_all_files(self, top, target_dir):
         filelist = []
index 2540cfc..316b9b6 100644 (file)
@@ -600,11 +600,40 @@ class Application:
         self.notify_preference_changed()
 
     def do_install(self, filename):
+        self.communicate.notify_all('OnInstallBegin', [])
         try:
-            filetype, target_dirs = self.installer.install(
+            filetype, target_dirs, names, errno = self.installer.install(
                 filename, ninix.home.get_ninix_home())
         except:
             target_dirs = None
+        if errno != 0:
+            error_reason = {
+                1: 'extraction',
+                2: 'invalid type',
+                3: 'artificial',
+                4: 'unsupported',
+            }
+            self.communicate.notify_all('OnInstallFailure',
+                                        [error_reason.get(errno, 'unkown')])
+            # XXX: ninix-ayaでは発生しない.
+            ##self.communicate.notify_all('OnInstallRefuse', [])
+        else:
+            ##self.communicate.notify_all('OnInstallCompleteEx', []) # FIXME
+            if filetype != 'kinoko':
+                if filetype == 'ghost':
+                    if target_dirs[1]:
+                        id = 'ghost with balloon'
+                        name2 = names[1]
+                    else:
+                        id = filetype
+                        name2 = None
+                    name = names[0]
+                else:
+                    id = filetype
+                    name2 = None
+                    name = names
+                self.communicate.notify_all('OnInstallComplete',
+                                            [id, name, name2])
         if target_dirs:
             if filetype == 'ghost':
                 self.add_sakura(target_dirs[0])
@@ -634,6 +663,7 @@ class Application:
                 self.katochan = ninix.home.search_katochan()
             elif filetype == 'kinoko':
                 self.kinoko = ninix.home.search_kinoko()
+                self.communicate.notify_all('OnKinokoObjectInstalled', names)
 
     def notify_installedghostname(self, key=None):
         installed = []