Updating based on work with MormonChannel
authorEd Page <eopage@byu.net>
Sat, 29 May 2010 04:19:04 +0000 (23:19 -0500)
committerEd Page <eopage@byu.net>
Sat, 29 May 2010 04:19:04 +0000 (23:19 -0500)
.gitignore
Makefile
src/REPLACEME.py [new file with mode: 0755]
src/REPLACEME_gtk.py [new file with mode: 0755]
src/constants.py
src/hildonize.py
src/util/go_utils.py
support/builddeb.py

index 0d20b64..1948f58 100644 (file)
@@ -1 +1,2 @@
 *.pyc
+.profile
index af801b1..389b948 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-PROJECT_NAME=
+PROJECT_NAME=REPLACEME
 SOURCE_PATH=src
 SOURCE=$(shell find $(SOURCE_PATH) -iname "*.py")
 PROGRAM=$(SOURCE_PATH)/$(PROJECT_NAME).py
diff --git a/src/REPLACEME.py b/src/REPLACEME.py
new file mode 100755 (executable)
index 0000000..af4b40e
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Copyright (C) 2007 Christoph Würstle
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+"""
+
+import os
+import sys
+import logging
+
+_moduleLogger = logging.getLogger(__name__)
+sys.path.append('../lib')
+
+
+import constants
+import REPLACEME_gtk
+
+
+if __name__ == "__main__":
+       try:
+               os.makedirs(constants._data_path_)
+       except OSError, e:
+               if e.errno != 17:
+                       raise
+
+       try:
+               os.makedirs(constants._cache_path_)
+       except OSError, e:
+               if e.errno != 17:
+                       raise
+
+       logFormat = '(%(asctime)s) %(levelname)-5s %(threadName)s.%(name)s: %(message)s'
+       logging.basicConfig(level=logging.DEBUG, filename=constants._user_logpath_, format=logFormat)
+       _moduleLogger.info("%s %s-%s" % (constants.__app_name__, constants.__version__, constants.__build__))
+       _moduleLogger.info("OS: %s" % (os.uname()[0], ))
+       _moduleLogger.info("Kernel: %s (%s) for %s" % os.uname()[2:])
+       _moduleLogger.info("Hostname: %s" % os.uname()[1])
+
+       REPLACEME_gtk.run()
diff --git a/src/REPLACEME_gtk.py b/src/REPLACEME_gtk.py
new file mode 100755 (executable)
index 0000000..85a9b6b
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import gc
+import logging
+import ConfigParser
+
+import gobject
+import dbus
+import gtk
+
+try:
+       import osso
+except ImportError:
+       osso = None
+
+import constants
+import hildonize
+import util.misc as misc_utils
+
+
+_moduleLogger = logging.getLogger(__name__)
+PROFILE_STARTUP = False
+
+
+class REPLACEMElProgram(hildonize.get_app_class()):
+
+       def __init__(self):
+               super(REPLACEMElProgram, self).__init__()
+
+               if not hildonize.IS_HILDON_SUPPORTED:
+                       _moduleLogger.info("No hildonization support")
+
+               if osso is not None:
+                       self._osso_c = osso.Context(constants.__app_name__, constants.__version__, False)
+                       self._deviceState = osso.DeviceState(self._osso_c)
+                       self._deviceState.set_device_state_callback(self._on_device_state_change, 0)
+               else:
+                       _moduleLogger.info("No osso support")
+                       self._osso_c = None
+                       self._deviceState = None
+
+       def _save_settings(self):
+               config = ConfigParser.SafeConfigParser()
+
+               self._REPLACEME.save_settings(config, "Windows")
+
+               with open(constants._user_settings_, "wb") as configFile:
+                       config.write(configFile)
+
+       def _load_settings(self):
+               config = ConfigParser.SafeConfigParser()
+               config.read(constants._user_settings_)
+
+               self._REPLACEME.load_settings(config, "Windows")
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData):
+               """
+               For system_inactivity, we have no background tasks to pause
+
+               @note Hildon specific
+               """
+               if memory_low:
+                       gc.collect()
+
+               if save_unsaved_data or shutdown:
+                       self._save_settings()
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_destroy(self, widget = None, data = None):
+               try:
+                       self.quit()
+               finally:
+                       gtk.main_quit()
+
+       def quit(self):
+               try:
+                       self._save_settings()
+               except Exception:
+                       _moduleLogger.exception("Error saving settigns")
+
+               try:
+                       self._deviceState.close()
+               except AttributeError:
+                       pass # Either None or close was removed (in Fremantle)
+               except Exception:
+                       _moduleLogger.exception("Error closing device state")
+               try:
+                       self._osso_c.close()
+               except AttributeError:
+                       pass # Either None or close was removed (in Fremantle)
+               except Exception:
+                       _moduleLogger.exception("Error closing osso state")
+
+
+def run():
+       gobject.threads_init()
+       gtk.gdk.threads_init()
+       l = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+       # HACK Playback while silent on Maemo 5
+       hildonize.set_application_name("FMRadio")
+
+       app = REPLACEMElProgram()
+       if not PROFILE_STARTUP:
+               try:
+                       gtk.main()
+               except KeyboardInterrupt:
+                       app.quit()
+                       raise
+       else:
+               app.quit()
+
+
+if __name__ == "__main__":
+       logging.basicConfig(level=logging.DEBUG)
+       run()
index bcaa5a9..8be32c8 100644 (file)
@@ -1,7 +1,7 @@
 import os
 
-__pretty_app_name__ = ""
-__app_name__ = ""
+__pretty_app_name__ = "REPLACEME"
+__app_name__ = "REPLACEME"
 __version__ = "0.1.0"
 __build__ = 0
 __app_magic__ = 0xdeadbeef
index 77d585a..339eb2a 100644 (file)
@@ -47,24 +47,26 @@ except AttributeError:
        get_app_class = _null_get_app_class
 
 
-def _hildon_set_application_title(window, title):
-       pass
+def _hildon_set_application_name(name):
+       gtk.set_application_name(name)
 
 
-def _null_set_application_title(window, title):
-       window.set_title(title)
+def _null_set_application_name(name):
+       pass
 
 
-if IS_HILDON_SUPPORTED:
-       set_application_title = _hildon_set_application_title
-else:
-       set_application_title = _null_set_application_title
+try:
+       gtk.set_application_name
+       set_application_name = _hildon_set_application_name
+except AttributeError:
+       set_application_name = _null_set_application_name
 
 
 def _fremantle_hildonize_window(app, window):
        oldWindow = window
        newWindow = hildon.StackableWindow()
-       oldWindow.get_child().reparent(newWindow)
+       if oldWindow.get_child() is not None:
+               oldWindow.get_child().reparent(newWindow)
        app.add_window(newWindow)
        return newWindow
 
@@ -72,7 +74,8 @@ def _fremantle_hildonize_window(app, window):
 def _hildon_hildonize_window(app, window):
        oldWindow = window
        newWindow = hildon.Window()
-       oldWindow.get_child().reparent(newWindow)
+       if oldWindow.get_child() is not None:
+               oldWindow.get_child().reparent(newWindow)
        app.add_window(newWindow)
        return newWindow
 
@@ -356,6 +359,28 @@ else:
        hildonize_combo_entry = _null_hildonize_combo_entry
 
 
+def _null_create_seekbar():
+       adjustment = gtk.Adjustment(0, 0, 101, 1, 5, 1)
+       seek = gtk.HScale(adjustment)
+       seek.set_draw_value(False)
+       return seek
+
+
+def _fremantle_create_seekbar():
+       seek = hildon.Seekbar()
+       seek.set_range(0.0, 100)
+       seek.set_draw_value(False)
+       seek.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
+       return seek
+
+
+try:
+       hildon.Seekbar
+       create_seekbar = _fremantle_create_seekbar
+except AttributeError:
+       create_seekbar = _null_create_seekbar
+
+
 def _fremantle_hildonize_scrollwindow(scrolledWindow):
        pannableWindow = hildon.PannableArea()
 
index 20ccac1..d066542 100644 (file)
@@ -95,20 +95,24 @@ class Async(object):
 
 class Timeout(object):
 
-       def __init__(self, func):
+       def __init__(self, func, once = True):
                self.__func = func
                self.__timeoutId = None
+               self.__once = once
 
        def start(self, **kwds):
                assert self.__timeoutId is None
 
+               callback = self._on_once if self.__once else self.__func
+
                assert len(kwds) == 1
                timeoutInSeconds = kwds["seconds"]
                assert 0 <= timeoutInSeconds
+
                if timeoutInSeconds == 0:
-                       self.__timeoutId = gobject.idle_add(self._on_once)
+                       self.__timeoutId = gobject.idle_add(callback)
                else:
-                       self.__timeoutId = timeout_add_seconds(timeoutInSeconds, self._on_once)
+                       self.__timeoutId = timeout_add_seconds(timeoutInSeconds, callback)
 
        def is_running(self):
                return self.__timeoutId is not None
@@ -153,6 +157,10 @@ class AsyncPool(object):
                        pass # eat up queue to cut down dumb work
                self.__workQueue.put(_QUEUE_EMPTY)
 
+       def clear_tasks(self):
+               for _ in algorithms.itr_available(self.__workQueue):
+                       pass # eat up queue to cut down dumb work
+
        def add_task(self, func, args, kwds, on_success, on_error):
                task = func, args, kwds, on_success, on_error
                self.__workQueue.put(task)
@@ -244,6 +252,24 @@ class AsyncLinearExecution(object):
                        )
 
 
+class AutoSignal(object):
+
+       def __init__(self, toplevel):
+               self.__disconnectPool = []
+               toplevel.connect("destroy", self.__on_destroy)
+
+       def connect_auto(self, widget, *args):
+               id = widget.connect(*args)
+               self.__disconnectPool.append((widget, id))
+
+       @misc.log_exception(_moduleLogger)
+       def __on_destroy(self, widget):
+               _moduleLogger.info("Destroy: %r (%s to clean up)" % (self, len(self.__disconnectPool)))
+               for widget, id in self.__disconnectPool:
+                       widget.disconnect(id)
+               del self.__disconnectPool[:]
+
+
 def throttled(minDelay, queue):
        """
        Throttle the calls to a function by queueing all the calls that happen
index 203beaf..84c17d3 100755 (executable)
@@ -12,7 +12,8 @@ import constants
 
 
 __appname__ = constants.__app_name__
-__description__ = """
+__description__ = """REPLACEME
+REPLACEME
 .
 Homepage:
 """
@@ -21,6 +22,7 @@ __email__ = "eopage@byu.net"
 __version__ = constants.__version__
 __build__ = constants.__build__
 __changelog__ = """
+REPLACEME
 """
 
 
@@ -30,13 +32,13 @@ gtk-update-icon-cache -f /usr/share/icons/hicolor
 """
 
 
-def find_files(path):
+def find_files(prefix, path):
        for root, dirs, files in os.walk(path):
                for file in files:
-                       if file.startswith("src-"):
+                       if file.startswith(prefix+"-"):
                                fileParts = file.split("-")
                                unused, relPathParts, newName = fileParts[0], fileParts[1:-1], fileParts[-1]
-                               assert unused == "src"
+                               assert unused == prefix
                                relPath = os.sep.join(relPathParts)
                                yield relPath, file, newName
 
@@ -80,9 +82,9 @@ def build_package(distribution):
        p.recommends = ", ".join([
        ])
        p.section = {
-               "debian": "",
-               "diablo": "",
-               "fremantle": "",
+               "debian": "REPLACEME",
+               "diablo": "user/REPLACEME",
+               "fremantle": "user/REPLACEME",
        }[distribution]
        p.arch = "all"
        p.urgency = "low"
@@ -91,11 +93,11 @@ def build_package(distribution):
        p.changelog = __changelog__
        p.postinstall = __postinstall__
        p.icon = {
-               "debian": "",
-               "diablo": "",
-               "fremantle": "", # Fremantle natively uses 48x48
+               "debian": "REPLACEME",
+               "diablo": "REPLACEME",
+               "fremantle": "REPLACEME", # Fremantle natively uses 48x48
        }[distribution]
-       p["/usr/bin"] = [ "" ]
+       p["/usr/bin"] = [ "REPLACEME" ]
        for relPath, files in unflatten_files(find_files(".")).iteritems():
                fullPath = ""
                if relPath:
@@ -104,10 +106,10 @@ def build_package(distribution):
                        "|".join((oldName, newName))
                        for (oldName, newName) in files
                )
-       p["/usr/share/applications/hildon"] = [""]
-       p["/usr/share/icons/hicolor/26x26/hildon"] = [""]
-       p["/usr/share/icons/hicolor/64x64/hildon"] = [""]
-       p["/usr/share/icons/hicolor/scalable/hildon"] = [""]
+       p["/usr/share/applications/hildon"] = ["REPLACEME.desktop"]
+       p["/usr/share/icons/hicolor/26x26/hildon"] = ["REPLACEME"]
+       p["/usr/share/icons/hicolor/64x64/hildon"] = ["REPLACEME"]
+       p["/usr/share/icons/hicolor/scalable/hildon"] = ["REPLACEME"]
 
        if distribution == "debian":
                print p