[X2Go-Commits] pyhoca-gui.git - build-baikal (branch) updated: 0.4.0.2

X2Go dev team git-admin at x2go.org
Sun Apr 21 22:53:44 CEST 2013


The branch, build-baikal has been updated
       via  3aac457efc8cf241d07ab1d9a7b1202438561af3 (commit)
       via  d118ba6b089df9d28ae4b10d05a0e1994d9bbe8d (commit)
       via  72a92e5d645ef83875eb3556d92df669ace84580 (commit)
       via  19fd6c12a12101f98d21b179d4d9b679ddee69a1 (commit)
       via  aeb4143ad02160bd081a02acb19335f6b71bd326 (commit)
       via  18e7c0a8a11ae17a1002fb36d83de8da7d54972b (commit)
       via  36bca6ba1d1e1e0c4516bba600d60850c3987b05 (commit)
       via  288f8f2637ccec75be0a6ef2f4921e1e71355d77 (commit)
       via  dfee09267d6011ac62903e23e6af29aa9e386d21 (commit)
       via  96d5f345ca16bd64dd197a81012c709b10926f2c (commit)
       via  eea34d1e7db596e3ed69f9c9965d6b7f52deba93 (commit)
       via  fecb8d6798efb1b1c4c6ad693bd1b5dfb2bb73a2 (commit)
       via  6c800d1d3c4aa478d47c0b8ecce8f9813d9ba85f (commit)
       via  b9cca13c17518fe387aaaca4ad8c10adf507167b (commit)
       via  af60d3076e8cb45ea8e330ff0f4405d4428c4e36 (commit)
       via  a12f581df11af39c67eecc0518fbaad96b3af1bf (commit)
      from  4ebcd63a16444ab642c4a9bccc2c8a05b392a8bf (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 debian/changelog               |   20 +++++
 debian/control                 |    2 +-
 icon2exe.py                    |  193 ++++++++++++++++++++++++++++++++++++++++
 paramiko                       |    2 +-
 pyhoca-gui                     |    2 +-
 pyhoca/wxgui/__init__.py       |    2 +-
 pyhoca/wxgui/frontend.py       |    4 +-
 pyhoca/wxgui/menus_taskbar.py  |    2 +
 pyhoca/wxgui/notify.py         |  152 +++++++++++++++++++++++++++++++
 pyhoca/wxgui/profilemanager.py |    1 +
 pyhoca/wxgui/taskbar.py        |   66 +++++++-------
 setup.py                       |  148 +++++++++++++++++++++++++-----
 12 files changed, 531 insertions(+), 63 deletions(-)
 create mode 100644 icon2exe.py

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index c7060e8..ddf5d69 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,23 @@
+pyhoca-gui (0.4.0.2-0~x2go1) unstable; urgency=low
+
+  * New upstream version (0.4.0.2):
+    - Make PyHoca-GUI aware of the Cinnamon desktop shell.
+    - Make sure that there is no KeyException when checking/unchecking the
+      restoreexports item in the shared folders menu.
+  * MS Windows specific: 
+    + Use bbfreeze to freeze the Win32 version of PyHoca-GUI.
+    + Make sure PyHoca-GUI freezing works with gevent 1.0b3 and later.
+    + Freeze with gui_only enabled, hides the console Window PyHoca-GUI runs in.
+    + Provide icon2exe.py for adding .ico files to .exe files. Thanks
+      to the original authors: Giovanni Bajo and previously McMillan
+      Enterprises, Inc.
+    + Use TaskBarIcon.ShowBalloon() instead of wx.NotificationMessage for
+      notifications. Let's us get rid of the multiple notification icons
+      in the system tray.
+    + On MS Windows, also use the PyHoca icon in the system tray.
+
+ -- Mike Gabriel <mike.gabriel at das-netzwerkteam.de>  Sun, 21 Apr 2013 22:45:46 +0200
+
 pyhoca-gui (0.4.0.1-0~x2go1) unstable; urgency=low
 
   * Fix image installation in setup.py. Thanks to Orion Poplawski for spotting.
diff --git a/debian/control b/debian/control
index 9666a0e..1cfaf9a 100644
--- a/debian/control
+++ b/debian/control
@@ -24,7 +24,7 @@ Architecture: all
 Depends: 
  ${misc:Depends},
  python,
- python-x2go (>=0.4.0.0-0~),
+ python-x2go (>=0.4.0.3-0~),
  python-argparse,
  python-notify,
  python-setproctitle,
diff --git a/icon2exe.py b/icon2exe.py
new file mode 100644
index 0000000..c066575
--- /dev/null
+++ b/icon2exe.py
@@ -0,0 +1,193 @@
+#! /usr/bin/env python
+# Copyright (C) 2005, Giovanni Bajo
+# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
+#
+# 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 Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+# This code has been adopted from this project:
+# git://deluge-torrent.org/delugemaster
+
+RT_ICON = 3
+RT_GROUP_ICON = 14
+LOAD_LIBRARY_AS_DATAFILE = 2
+
+import struct
+import types
+try:
+    StringTypes = types.StringTypes
+except AttributeError:
+    StringTypes = [ type("") ]
+
+class Structure:
+    def __init__ (self):
+        size = self._sizeInBytes = struct.calcsize (self._format_)
+        self._fields_ = list (struct.unpack (self._format_, '\000' * size))
+        indexes = self._indexes_ = {}
+        for i in range (len (self._names_)):
+            indexes[self._names_[i]] = i
+    def dump (self):
+        print "I: DUMP of", self
+        for name in self._names_:
+            if name[0] != '_':
+                print "I: %20s = %s" % (name, getattr (self, name))
+        print
+    def __getattr__ (self, name):
+        if name in self._names_:
+            index = self._indexes_[name]
+            return self._fields_[index]
+        try:
+            return self.__dict__[name]
+        except KeyError:
+            raise AttributeError, name
+    def __setattr__ (self, name, value):
+        if name in self._names_:
+            index = self._indexes_[name]
+            self._fields_[index] = value
+        else:
+            self.__dict__[name] = value
+    def tostring (self):
+        return apply (struct.pack, [self._format_,] + self._fields_)
+    def fromfile (self, file):
+        data = file.read (self._sizeInBytes)
+        self._fields_ = list (struct.unpack (self._format_, data))
+
+class ICONDIRHEADER (Structure):
+    _names_ = "idReserved", "idType", "idCount"
+    _format_ = "hhh"
+
+class ICONDIRENTRY (Structure):
+    _names_ = "bWidth", "bHeight", "bColorCount", "bReserved", "wPlanes", "wBitCount", "dwBytesInRes", "dwImageOffset"
+    _format_ = "bbbbhhii"
+
+class GRPICONDIR (Structure):
+    _names_ = "idReserved", "idType", "idCount"
+    _format_ = "hhh"
+
+class GRPICONDIRENTRY (Structure):
+    _names_ = "bWidth", "bHeight", "bColorCount", "bReserved", "wPlanes", "wBitCount", "dwBytesInRes", "nID"
+    _format_ = "bbbbhhih"
+
+class IconFile:
+    def __init__ (self, path):
+        self.path = path
+        file = open (path, "rb")
+        self.entries = []
+        self.images = []
+        header = self.header = ICONDIRHEADER()
+        header.fromfile (file)
+        for i in range (header.idCount):
+            entry = ICONDIRENTRY()
+            entry.fromfile (file)
+            self.entries.append (entry)
+        for e in self.entries:
+            file.seek (e.dwImageOffset, 0)
+            self.images.append (file.read (e.dwBytesInRes))
+
+    def grp_icon_dir (self):
+        return self.header.tostring()
+
+    def grp_icondir_entries (self, id=1):
+        data = ""
+        for entry in self.entries:
+            e = GRPICONDIRENTRY()
+            for n in e._names_[:-1]:
+                setattr(e, n, getattr (entry, n))
+            e.nID = id
+            id = id + 1
+            data = data + e.tostring()
+        return data
+
+
+def CopyIcons_FromIco (dstpath, srcpath, id=1):
+    import win32api #, win32con
+    icons = map(IconFile, srcpath)
+    print "I: Updating icons from", srcpath, "to", dstpath
+
+    hdst = win32api.BeginUpdateResource (dstpath, 0)
+
+    iconid = 1
+    for i in range(len(icons)):
+        f = icons[i]
+        data = f.grp_icon_dir()
+        data = data + f.grp_icondir_entries(iconid)
+        win32api.UpdateResource (hdst, RT_GROUP_ICON, i, data)
+        print "I: Writing RT_GROUP_ICON %d resource with %d bytes" % (i, len(data))
+        for data in f.images:
+            win32api.UpdateResource (hdst, RT_ICON, iconid, data)
+            print "I: Writing RT_ICON %d resource with %d bytes" % (iconid, len (data))
+            iconid = iconid + 1
+
+    win32api.EndUpdateResource (hdst, 0)
+
+def CopyIcons (dstpath, srcpath):
+    import os.path, string
+
+    if type(srcpath) in StringTypes:
+        srcpath = [ srcpath ]
+
+    def splitter(s):
+        try:
+            srcpath, index = map(string.strip, string.split(s, ','))
+            return srcpath, int(index)
+        except ValueError:
+            return s, None
+
+    srcpath = map(splitter, srcpath)
+    print "I: SRCPATH", srcpath
+
+    if len(srcpath) > 1:
+        # At the moment, we support multiple icons only from .ico files
+        srcs = []
+        for s in srcpath:
+            e = os.path.splitext(s[0])[1]
+            if string.lower(e) != '.ico':
+                raise ValueError, "multiple icons supported only from .ico files"
+            if s[1] is not None:
+                raise ValueError, "index not allowed for .ico files"
+            srcs.append(s[0])
+        return CopyIcons_FromIco(dstpath, srcs)
+
+    srcpath,index = srcpath[0]
+    srcext = os.path.splitext(srcpath)[1]
+    if string.lower (srcext) == '.ico':
+        return CopyIcons_FromIco (dstpath, [srcpath])
+    if index is not None:
+        print "I: Updating icons from", srcpath, ", %d to" % index, dstpath
+    else:
+        print "I: Updating icons from", srcpath, "to", dstpath
+    import win32api #, win32con
+    hdst = win32api.BeginUpdateResource (dstpath, 0)
+    hsrc = win32api.LoadLibraryEx (srcpath, 0, LOAD_LIBRARY_AS_DATAFILE)
+    if index is None:
+        grpname = win32api.EnumResourceNames (hsrc, RT_GROUP_ICON)[0]
+    elif index >= 0:
+        grpname = win32api.EnumResourceNames (hsrc, RT_GROUP_ICON)[index]
+    else:
+        grpname = -index
+    data = win32api.LoadResource (hsrc, RT_GROUP_ICON, grpname)
+    win32api.UpdateResource (hdst, RT_GROUP_ICON, grpname, data)
+    for iconname in win32api.EnumResourceNames (hsrc, RT_ICON):
+        data = win32api.LoadResource (hsrc, RT_ICON, iconname)
+        win32api.UpdateResource (hdst, RT_ICON, iconname, data)
+    win32api.FreeLibrary (hsrc)
+    win32api.EndUpdateResource (hdst, 0)
+
+if __name__ == "__main__":
+    import sys
+
+    dstpath = sys.argv[1]
+    srcpath = sys.argv[2:]
+    CopyIcons(dstpath, srcpath)
+
diff --git a/paramiko b/paramiko
index 84dd28b..79a7991 120000
--- a/paramiko
+++ b/paramiko
@@ -1 +1 @@
-/home/mike/MyDocuments/4projects/x2go-upstream/python-paramiko/paramiko
\ No newline at end of file
+../python-paramiko/paramiko
\ No newline at end of file
diff --git a/pyhoca-gui b/pyhoca-gui
index a516e9d..34f08b4 100755
--- a/pyhoca-gui
+++ b/pyhoca-gui
@@ -27,7 +27,7 @@ import re
 PROG_NAME = os.path.basename(sys.argv[0]).replace('.exe', '')
 PROG_PID  = os.getpid()
 
-if hasattr(sys, 'frozen') and sys.frozen in ("windows_exe", "console_exe"):
+if hasattr(sys, 'frozen') and str(sys.frozen) in ("windows_exe", "console_exe", "1", ):
     class Win32_Logging(object):
 
         softspace = 0
diff --git a/pyhoca/wxgui/__init__.py b/pyhoca/wxgui/__init__.py
index 016bae2..7c31c27 100644
--- a/pyhoca/wxgui/__init__.py
+++ b/pyhoca/wxgui/__init__.py
@@ -18,6 +18,6 @@
 # Free Software Foundation, Inc.,
 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 
-__VERSION__ = '0.4.0.1'
+__VERSION__ = '0.4.0.2'
 
 from frontend import *
diff --git a/pyhoca/wxgui/frontend.py b/pyhoca/wxgui/frontend.py
index 1cc930a..4f49af5 100644
--- a/pyhoca/wxgui/frontend.py
+++ b/pyhoca/wxgui/frontend.py
@@ -310,7 +310,7 @@ class PyHocaGUI(wx.App, x2go.X2GoClient):
         if x2go.X2GOCLIENT_OS in ('Linux', 'Mac'):
             self.notifier = notify.libnotify_NotifierPopup(self)
         if x2go.X2GOCLIENT_OS in ('Windows'):
-            self.notifier = notify.notificationmessage_NotifierPopup(self.about)
+            self.notifier = notify.showballoon_NotifierPopup(self.about)
 
         self._sub_windows = []
         self._logon_windows = {}
@@ -715,7 +715,7 @@ class PyHocaGUI(wx.App, x2go.X2GoClient):
             self.WakeUpIdle()
             self.ExitMainLoop()
 
-        self._remember_shared_folders[profile_name] = self.get_profile_config(profile_name)['restoreexports']
+        self._remember_shared_folders[profile_name] = self.get_profile_config(profile_name, 'restoreexports')
         self.taskbar.SetIconIdle()
 
     def OnSessionAuthenticate(self, evt, session_uuid=None):
diff --git a/pyhoca/wxgui/menus_taskbar.py b/pyhoca/wxgui/menus_taskbar.py
index cfcbe04..2d08231 100644
--- a/pyhoca/wxgui/menus_taskbar.py
+++ b/pyhoca/wxgui/menus_taskbar.py
@@ -371,6 +371,8 @@ class PyHocaGUI_Menu_TaskbarProfileSharedFolders(wx.Menu):
         self.AppendSeparator()
 
         _remember_shared_folders_item = self.AppendCheckItem(id=ID_REMEMBERSHAREDFOLDERS, text=_(u"Restore shares in next session"))
+        if not self._PyHocaGUI._remember_shared_folders.has_key(profile_name):
+            self._PyHocaGUI._remember_shared_folders[profile_name] = self._PyHocaGUI.get_profile_config(profile_name, 'restoreexports')
         _remember_shared_folders_item.Check(self._PyHocaGUI._remember_shared_folders[profile_name])
 
         self._PyHocaGUI.Bind(wx.EVT_MENU, self._PyHocaGUI.OnShareCustomLocalFolder, id=ID_SHARECUSTOMLOCALFOLDER)
diff --git a/pyhoca/wxgui/notify.py b/pyhoca/wxgui/notify.py
index 8a462b2..2b27c6b 100644
--- a/pyhoca/wxgui/notify.py
+++ b/pyhoca/wxgui/notify.py
@@ -25,6 +25,7 @@ if X2GOCLIENT_OS in ('Linux', 'Mac'):
     import pynotify
 import exceptions
 import basepath
+from taskbar import MakeIcon
 
 import x2go.utils as utils
 
@@ -151,6 +152,157 @@ class libnotify_NotifierPopup(object):
         pass
 
 
+class showballoon_NotifierPopup(object):
+    """\
+    L{PyHocaGUI} notification utilizing C{wx.TaskBarIcon.ShowBalloon()}, used on Windows OS.
+
+    """
+    title = {}
+    text = {}
+    icon = {}
+    timeout = {}
+
+    def __init__(self, _about):
+        """\
+        Notifier popup (constructor).
+
+        @param _about: main application window
+        @type _about: C{obj}
+
+        """
+        self._PyHocaGUI = _about._PyHocaGUI
+        self._pyhoca_logger = self._PyHocaGUI._pyhoca_logger
+
+    def prepare(self, context, title=None, text=None, icon=None, timeout=None):
+        """\
+        Prepare a notification that gets sent to C{libnotify} later (by the L{send()} method).
+
+        Use C{context} as a unique identifier. When sending the notification later, C{context}
+        will unequivocally map to the notification content that shall get sent.
+
+        @param context: a unique identifier for this notification preparation
+        @type context: C{str}
+        @param title: notification title
+        @type title: C{str}
+        @param text: notification text
+        @type text: C{str}
+        @param icon: icon name for an icon that appears with the notification
+        @type icon: C{str}
+        @param timeout: let notification disappear after C{<timeout>} milliseconds
+        @type timeout: C{int}
+
+        """
+        if title is not None:
+            self.title[context] = title
+        if text is not None:
+            self.text[context] = text
+        if icon is not None:
+            self.icon[context] = icon
+        if timeout is not None:
+            self.timeout[context] = timeout
+
+    def send(self, title=None, text=None, context=None, icon=None, timeout=8000):
+        """\
+        Send notifications directly (or use a prepared notification).
+
+        @param title: notification title
+        @type title: C{str}
+        @param text: notification text
+        @type text: C{str}
+        @param context: an identifier that refers to a prepared notification
+        @type context: C{str}
+        @param icon: icon name for an icon that appears with the notification
+        @type icon: C{str}
+        @param timeout: let notification disappear after C{<timeout>} milliseconds
+        @type timeout: C{int}
+
+        """
+        if context is not None:
+            try:
+                title = self.title[context]
+                del self.title[context]
+            except KeyError:
+                pass
+            try:
+                text = self.text[context]
+                del self.text[context]
+            except KeyError:
+                pass
+            try:
+                icon = self.icon[context]
+                del self.icon[context]
+            except KeyError:
+                pass
+            try:
+                timeout = self.timeout[context]
+                del self.timeout[context]
+            except KeyError:
+                pass
+
+        # libnotify timeouts are given in millisecs, on Windows we use seconds...
+        timeout = timeout / 1000
+
+        _icon_map_wx = {
+            'audio_error': wx.ICON_ERROR,
+            'auth_success': wx.ICON_INFORMATION,
+            'auth_failed': wx.ICON_WARNING,
+            'auth_error': wx.ICON_ERROR,
+            'auth_disconnect': wx.ICON_INFORMATION,
+            'profile_add': wx.ICON_INFORMATION,
+            'profile_delete': wx.ICON_INFORMATION,
+            'profile_edit': wx.ICON_INFORMATION,
+            'profile_save': wx.ICON_INFORMATION,
+            'profile_error': wx.ICON_ERROR,
+            'session_cleanall': wx.ICON_INFORMATION,
+            'session_error': wx.ICON_ERROR,
+            'session_pause': wx.ICON_INFORMATION,
+            'session_printing': wx.ICON_INFORMATION,
+            'session_resume': wx.ICON_INFORMATION,
+            'session_start': wx.ICON_INFORMATION,
+            'session_terminate': wx.ICON_INFORMATION,
+            'session_warning': wx.ICON_WARNING,
+        }
+        if icon in _icon_map_wx.keys():
+           icon = _icon_map_wx[icon]
+        else:
+           icon = wx.ICON_INFORMATION
+
+        try:
+            if not self._PyHocaGUI.disable_notifications:
+                # you will need wxPython >= 2.9 for this
+                self._PyHocaGUI.taskbar.ShowBalloon(
+                    title,
+                    text,
+                    timeout*1000,
+                    icon,
+                )
+        except:
+            pass
+
+        # on Windows some error messages are already encoded, some are not, depending from which module they come
+        try: _title = title.encode(utils.get_encoding())
+        except: _title = title
+        try: _text = text.encode(utils.get_encoding())
+        except: _text = text
+
+        try: self._pyhoca_logger('['+_title+'] '+_text, loglevel=log.loglevel_NOTICE)
+        except UnicodeDecodeError: self._pyhoca_logger('Unicode error occurred while rendering a log message...', loglevel=log.loglevel_WARN)
+
+    def Close(self):
+        """\
+        Provide a C{Close()} method which does nothing.
+
+        """
+        pass
+
+    def Destroy(self):
+        """\
+        Provide a C{Destroy()} method which does nothing.
+
+        """
+        pass
+
+
 class notificationmessage_NotifierPopup(object):
     """\
     L{PyHocaGUI} notification utilizing C{wx.NotificationMessage()}, used on Windows OS.
diff --git a/pyhoca/wxgui/profilemanager.py b/pyhoca/wxgui/profilemanager.py
index a97ca49..e0eb785 100644
--- a/pyhoca/wxgui/profilemanager.py
+++ b/pyhoca/wxgui/profilemanager.py
@@ -76,6 +76,7 @@ class PyHocaGUI_ProfileManager(wx.Dialog):
 
         self.action = action
         self.sessionChoices = {
+            'CINNAMON': _(u'Cinnamon Desktop (CINNAMON)'),
             'GNOME': _(u'GNOME Desktop (GNOME)'),
             'KDE': _(u'K Desktop Environment (KDE)'),
             'LXDE': _(u'Lightweight X Desktop (LXDE)'),
diff --git a/pyhoca/wxgui/taskbar.py b/pyhoca/wxgui/taskbar.py
index 03dda9f..dad25b4 100644
--- a/pyhoca/wxgui/taskbar.py
+++ b/pyhoca/wxgui/taskbar.py
@@ -50,6 +50,35 @@ import basepath
 
 _icons_location = basepath.icons_basepath
 
+def MakeIcon(icon_name, fallback_name='pyhoca-trayicon'):
+    """\
+    The various platforms have different requirements for the
+    icon size...
+
+    @param icon_name: rel. file name of the icon image
+    @type icon_name: C{str}
+    @param fallback_name: a fallback icon file name in case C{icon_name} cannot be found
+    @type fallback_name: C{str}
+
+    """
+    if "wxMSW" in wx.PlatformInfo:
+        icon_size = '16x16'
+    elif "wxGTK" in wx.PlatformInfo:
+        icon_size = '22x22'
+    elif "wxMAC" in wx.PlatformInfo:
+        icon_size = '128x128'
+
+    if icon_name is None:
+        icon_name = fallback_name
+
+    icon_file = '%s/PyHoca/%s/%s.png' % (_icons_location, icon_size, icon_name)
+    if not (os.path.isfile(str(icon_file)) or os.path.islink(str(icon_file))):
+        icon_file = '%s/PyHoca/%s/%s.png' % (_icons_location, icon_size, fallback_name)
+
+    img = wx.Image(icon_file)
+    icon = wx.IconFromBitmap(img.ConvertToBitmap())
+    return icon
+
 
 class PyHocaGUI_TaskBarIcon(wx.TaskBarIcon):
     """\
@@ -85,11 +114,11 @@ class PyHocaGUI_TaskBarIcon(wx.TaskBarIcon):
         """
         if x2go.X2GOCLIENT_OS == 'Windows':
             icon_name = self._PyHocaGUI.tray_icon_connecting or self._PyHocaGUI.tray_icon
-            self.icon = self.MakeIcon(icon_name=icon_name, fallback_name='x2go-logo-ubuntu')
+            self.icon = MakeIcon(icon_name=icon_name, fallback_name='pyhoca-trayicon')
             self.SetIcon(self.icon, _(u"PyHoca-GUI\nConnecting you to ,,%s\'\'") % profile_name)
         else:
             icon_name = self._PyHocaGUI.tray_icon_connecting or self._PyHocaGUI.tray_icon
-            self.icon = self.MakeIcon(icon_name=icon_name, fallback_name='pyhoca-trayicon')
+            self.icon = MakeIcon(icon_name=icon_name, fallback_name='pyhoca-trayicon')
             self.SetIcon(self.icon, _(u"PyHoca-GUI (Python X2Go Client)\nCurrently connecting you to remote X2Go server ,,%s\'\'") % profile_name)
 
     def SetIconIdle(self):
@@ -99,11 +128,11 @@ class PyHocaGUI_TaskBarIcon(wx.TaskBarIcon):
         """
         if x2go.X2GOCLIENT_OS == 'Windows':
             icon_name = self._PyHocaGUI.tray_icon
-            self.icon = self.MakeIcon(icon_name=icon_name, fallback_name='x2go-logo-ubuntu')
+            self.icon = MakeIcon(icon_name=icon_name, fallback_name='pyhoca-trayicon')
             self.SetIcon(self.icon, _(u"PyHoca-GUI\nConnecting you to X2Go..."))
         else:
             icon_name = self._PyHocaGUI.tray_icon
-            self.icon = self.MakeIcon(icon_name=icon_name, fallback_name='pyhoca-trayicon')
+            self.icon = MakeIcon(icon_name=icon_name, fallback_name='pyhoca-trayicon')
             self.SetIcon(self.icon, _(u"PyHoca-GUI (Python X2Go Client)\nClient for connecting you to a remote X2Go server"))
 
     def CreateSessionManagerPopupMenu(self, evt):
@@ -148,35 +177,6 @@ class PyHocaGUI_TaskBarIcon(wx.TaskBarIcon):
         self.menu_optionsmanager = self.PopupMenu(menus_taskbar.PyHocaGUI_Menu_TaskbarOptionsManager(self._PyHocaGUI, caller=self,))
         return self.menu_optionsmanager
 
-    def MakeIcon(self, icon_name, fallback_name='pyhoca-trayicon'):
-        """\
-        The various platforms have different requirements for the
-        icon size...
-
-        @param icon_name: rel. file name of the icon image
-        @type icon_name: C{str}
-        @param fallback_name: a fallback icon file name in case C{icon_name} cannot be found
-        @type fallback_name: C{str}
-
-        """
-        if "wxMSW" in wx.PlatformInfo:
-            icon_size = '16x16'
-        elif "wxGTK" in wx.PlatformInfo:
-            icon_size = '22x22'
-        elif "wxMAC" in wx.PlatformInfo:
-            icon_size = '128x128'
-
-        if icon_name is None:
-            icon_name = fallback_name
-
-        icon_file = '%s/PyHoca/%s/%s.png' % (_icons_location, icon_size, icon_name)
-        if not (os.path.isfile(str(icon_file)) or os.path.islink(str(icon_file))):
-            icon_file = '%s/PyHoca/%s/%s.png' % (_icons_location, icon_size, fallback_name)
-
-        img = wx.Image(icon_file)
-        icon = wx.IconFromBitmap(img.ConvertToBitmap())
-        return icon
-
     def Close(self):
         """\
         Remove the applet icon from the system tray.
diff --git a/setup.py b/setup.py
index eabb468..41c74a2 100755
--- a/setup.py
+++ b/setup.py
@@ -35,12 +35,23 @@ URL = 'http://www.x2go.org'
 LIBRARY_ZIP = r"lib\shardlib.zip"
 
 from setuptools import setup, find_packages
-from distutils.core import setup
+from distutils.core import setup, Command
 import platform
 
+base = None
+executables = []
 if platform.system() == 'Windows':
+    default_win32exe_freezer = 'bbfreeze'
     NSIS_COMPILE = os.path.join(os.environ['ProgramFiles'], 'NSIS', 'makensis.exe')
-    from py2exe.build_exe import py2exe
+    if 'build_with_py2exe' in (sys.argv[1], 'build_with_{freezer}'.format(freezer=default_win32exe_freezer)):
+        from py2exe.build_exe import py2exe
+        Freezer = object
+    elif 'build_with_bbfreeze' in (sys.argv[1], 'build_with_{freezer}'.format(freezer=default_win32exe_freezer)):
+        from bbfreeze import Freezer
+        py2exe = object
+    else:
+        py2exe = object
+        Freezer = object
     import os, os.path
     import subprocess
     sys.path.append(os.path.normpath('../pyhoca-contrib/mswin/ms-vc-runtime'))
@@ -48,6 +59,7 @@ if platform.system() == 'Windows':
 elif platform.system() == 'Linux':
     from DistUtilsExtra.command import *
     py2exe = object
+    Freezer = object
 
 from glob import glob
 import shutil
@@ -108,27 +120,33 @@ class NSISScript(object):
             raise RuntimeError("NSIS compilation return code: %d" % retcode)
 
 
-class build_installer(py2exe):
+class build_installer(object):
 
-    # This class first builds the exe file(s), then creates an NSIS installer
-    # that runs your program from a temporary directory.
+    # This class first invokes building the the exe file(s) and then creates an NSIS
+    # installer
+    def __init__(self, dist_dir):
+        self.dist_dir = dist_dir
+
+    def do_build_exe(self):
+        # replace this method with the freezer's build_exe logic
+        pass
 
     def run(self):
 
+        # clean up dist_dir
         shutil.rmtree(self.dist_dir, ignore_errors=True)
+        # and recreate a clean one afterwards
+        os.makedirs(self.dist_dir)
 
-        # First, let py2exe do it's work.
-        py2exe.run(self)
-
-        lib_dir = self.lib_dir
-        dist_dir = self.dist_dir
+        # First, build the exe file
+        self.do_build_exe()
 
         # Create the installer, using the files py2exe has created.
         script = NSISScript(
                             PROGRAM_NAME,
                             PROGRAM_DESC,
                             PROGRAM_VERSION,
-                            dist_dir,
+                            self.dist_dir,
                             os.path.normpath(PROGRAM_ICON)
                            )
         print "*** creating the NSIS setup script***"
@@ -136,6 +154,75 @@ class build_installer(py2exe):
         print "*** compiling the NSIS setup script***"
         script.compile()
 
+
+class build_installer_py2exe(build_installer, py2exe):
+
+    def __init__(self, *args, **kwargs):
+        py2exe.__init__(self, *args, **kwargs)
+        build_installer.__init__(dist_dir=self.dist_dir)
+
+    def do_build_exe(self):
+
+        # First, let py2exe do it's work.
+        py2exe.run(self)
+
+class build_installer_bbfreeze(build_installer, Freezer, Command):
+
+    user_options = [
+        ('dist-dir=', 'd',
+         "directory to put final built distributions in (default is dist)"),
+
+        ("excludes=", 'e',
+         "comma-separated list of modules to exclude"),
+        ("includes=", 'i',
+         "comma-separated list of modules to include"),
+    ]
+
+    def __init__(self, *args, **kwargs):
+        Command.__init__(self, *args)
+        build_installer.__init__(self, dist_dir=self.dist_dir)
+
+    def initialize_options(self):
+        self.includes = []
+        self.excludes = []
+        self.packages = []
+        self.compressed = False
+        self.dist_dir = None
+
+    def finalize_options(self):
+        self.includes = fancy_split(self.includes)
+        self.excludes = fancy_split(self.excludes)
+        self.compressed = False
+        if self.dist_dir is None:
+            self.dist_dir = 'dist'
+        self.dist_dir = os.path.abspath(os.path.join(os.getcwd(), self.dist_dir))
+        if not os.path.exists(self.dist_dir):
+            os.makedirs(self.dist_dir)
+
+    def do_build_exe(self):
+        Freezer.__init__(self, self.dist_dir,
+            includes=self.includes,
+            excludes=self.excludes,
+        )
+        self.addScript("pyhoca-gui", gui_only=True)
+        Freezer.__call__(self)
+        if self.distribution.has_data_files():
+            print "*** copy data files ***"
+            install_data = self.reinitialize_command('install_data')
+            install_data.install_dir = self.dist_dir
+            install_data.ensure_finalized()
+            install_data.run()
+
+def fancy_split(str, sep=","):
+    # a split which also strips whitespace from the items
+    # passing a list or tuple will return it unchanged
+    if str is None:
+        return []
+    if hasattr(str, "split"):
+        return [item.strip() for item in str.split(sep)]
+    return str
+
+
 if platform.system() == 'Windows':
 
     dll_data_files = [("Microsoft.VC90.CRT", glob(r'..\\pyhoca-contrib\\mswin\\ms-vc-runtime\\*.*'))]
@@ -159,9 +246,11 @@ if platform.system() == 'Windows':
 
     cmd_class.update(
         {
-            "build_exe": build_installer,
+            "build_with_py2exe": build_installer_py2exe,
+            "build_with_bbfreeze": build_installer_bbfreeze,
         }
     )
+    cmd_class.update({ 'build_exe': cmd_class['build_with_{freezer}'.format(freezer=default_win32exe_freezer)] })
 
 elif platform.system() == 'Linux':
     cmd_class.update(
@@ -187,6 +276,27 @@ elif platform.system() == 'Linux':
                       manpage_files
     )
 
+if platform.system() == 'Windows':
+    cmd_options={
+        'py2exe': {
+            'includes': ['greenlet', 'gevent.core', 'gevent.ares', 'gevent._semaphore', 'gevent._util', ],
+            'compressed': 1,
+            'optimize': 2,
+        },
+        'build_with_py2exe': {
+            'includes': ['greenlet', 'gevent.core', 'gevent.ares', 'gevent._semaphore', 'gevent._util', ],
+            'compressed': 1,
+            'optimize': 2,
+        },
+        'build_with_bbfreeze': {
+            'includes': ['greenlet', 'gevent.core', 'gevent.ares', 'gevent._semaphore', 'gevent._util', 'gevent.resolver_thread', 'gevent.resolver_ares', 'gevent.socket', 'gevent.threadpool', 'gevent.select', 'gevent.subprocess', ],
+            'excludes': ['MSVCR90.dll', 'MSVCP90.dll', ],
+        }
+    }
+    cmd_options.update({ 'build_exe': cmd_options['build_with_{freezer}'.format(freezer=default_win32exe_freezer)] })
+else:
+    cmd_options={}
+
 setup(
     name = PROGRAM_NAME,
     version = PROGRAM_VERSION,
@@ -208,16 +318,6 @@ setup(
     ],
     data_files=data_files,
     zipfile = LIBRARY_ZIP,
-    options={
-        'py2exe': {
-            'includes': ['greenlet', 'gevent.core', ],
-            'compressed': 1,
-            'optimize': 2,
-        },
-        'build_exe': {
-            'includes': ['greenlet', 'gevent.core', ],
-            'compressed': 1,
-            'optimize': 2,
-        }
-    }
+    executables = executables,
+    options=cmd_options,
 )


hooks/post-receive
-- 
pyhoca-gui.git (Python X2Go Client (wxPython GUI))

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "pyhoca-gui.git" (Python X2Go Client (wxPython GUI)).




More information about the x2go-commits mailing list