From fa3f8c6b67ffeeede5fafd2ce63f47dec7dc6fa3 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 28 May 2010 23:19:04 -0500 Subject: [PATCH] Updating based on work with MormonChannel --- .gitignore | 1 + Makefile | 2 +- src/REPLACEME.py | 43 ++++++++++++++++++ src/REPLACEME_gtk.py | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/constants.py | 4 +- src/hildonize.py | 45 ++++++++++++++----- src/util/go_utils.py | 32 ++++++++++++-- support/builddeb.py | 32 +++++++------- 8 files changed, 248 insertions(+), 31 deletions(-) create mode 100755 src/REPLACEME.py create mode 100755 src/REPLACEME_gtk.py diff --git a/.gitignore b/.gitignore index 0d20b64..1948f58 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.pyc +.profile diff --git a/Makefile b/Makefile index af801b1..389b948 100644 --- 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 index 0000000..af4b40e --- /dev/null +++ b/src/REPLACEME.py @@ -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 index 0000000..85a9b6b --- /dev/null +++ b/src/REPLACEME_gtk.py @@ -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() diff --git a/src/constants.py b/src/constants.py index bcaa5a9..8be32c8 100644 --- a/src/constants.py +++ b/src/constants.py @@ -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 diff --git a/src/hildonize.py b/src/hildonize.py index 77d585a..339eb2a 100644 --- a/src/hildonize.py +++ b/src/hildonize.py @@ -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() diff --git a/src/util/go_utils.py b/src/util/go_utils.py index 20ccac1..d066542 100644 --- a/src/util/go_utils.py +++ b/src/util/go_utils.py @@ -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 diff --git a/support/builddeb.py b/support/builddeb.py index 203beaf..84c17d3 100755 --- a/support/builddeb.py +++ b/support/builddeb.py @@ -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 -- 1.7.9.5