0.6.1-1 Added dbus locking mechanism, and widget changes
authorYves <ymarcoz@n900-sdk.(none)>
Sun, 25 Apr 2010 01:20:12 +0000 (18:20 -0700)
committerYves <ymarcoz@n900-sdk.(none)>
Sun, 25 Apr 2010 01:20:12 +0000 (18:20 -0700)
33 files changed:
Makefile
data/40px.png [deleted file]
data/48px.png [new file with mode: 0644]
debian/changelog
debian/control
debian/cron.d.ex [deleted file]
debian/emacsen-install.ex [deleted file]
debian/emacsen-remove.ex [deleted file]
debian/emacsen-startup.ex [deleted file]
debian/feedingit-default.ex [deleted file]
debian/feedingit.doc-base.EX [deleted file]
debian/init.d.ex [deleted file]
debian/manpage.1.ex [deleted file]
debian/manpage.sgml.ex [deleted file]
debian/manpage.xml.ex [deleted file]
debian/menu.ex [deleted file]
debian/postinst.ex [deleted file]
debian/postrm.ex [deleted file]
debian/preinst.ex [deleted file]
debian/prerm.ex [deleted file]
src/FeedingIt
src/FeedingIt.desktop
src/FeedingIt.py
src/config.py
src/feedingit.service
src/feedingit_status.desktop [new file with mode: 0644]
src/feedingit_status.py [new file with mode: 0644]
src/feedingit_status.service [new file with mode: 0644]
src/feedingit_widget.py
src/feedingitdbus.py
src/rss.py
src/update_feeds.py [new file with mode: 0644]
src/updatedbus.py [new file with mode: 0644]

index 7bf2d8c..0c4a421 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,25 +14,29 @@ install:
        install src/rss.py ${DESTDIR}/opt/FeedingIt
        install src/opml.py ${DESTDIR}/opt/FeedingIt
        install src/config.py ${DESTDIR}/opt/FeedingIt
+       #install src/feedingit_status.desktop ${DESTDIR}/opt/FeedingIt
+       install src/update_feeds.py ${DESTDIR}/opt/FeedingIt
+       install src/updatedbus.py ${DESTDIR}/opt/FeedingIt
        install src/BeautifulSoup.py ${DESTDIR}/opt/FeedingIt
        install src/feedingitdbus.py ${DESTDIR}/opt/FeedingIt
        install -d ${DESTDIR}/usr/share/applications/hildon
        install src/FeedingIt.desktop ${DESTDIR}/usr/share/applications/hildon
-       install -d ${DESTDIR}/usr/share/icons/hicolor/40x40/apps/
-       install data/40px.png ${DESTDIR}/usr/share/icons/hicolor/40x40/apps/feedingit.png
+       install -d ${DESTDIR}/usr/share/icons/hicolor/48x48/apps/
+       install data/48px.png ${DESTDIR}/usr/share/icons/hicolor/48x48/apps/feedingit.png
        install -d ${DESTDIR}/usr/share/icons/hicolor/26x26/apps/
        install data/26px.png ${DESTDIR}/usr/share/icons/hicolor/26x26/apps/feedingit.png
        install -d ${DESTDIR}/usr/share/icons/hicolor/64x64/apps/
        install data/64px.png ${DESTDIR}/usr/share/icons/hicolor/64x64/apps/feedingit.png
        install -d ${DESTDIR}/usr/share/dbus-1/services/
        install src/feedingit.service ${DESTDIR}/usr/share/dbus-1/services/
+       install src/feedingit_status.service ${DESTDIR}/usr/share/dbus-1/services/
        install -d ${DESTDIR}/etc/osso-backup/applications/
        install src/feedingit.conf ${DESTDIR}/etc/osso-backup/applications/
        install -d ${DESTDIR}/usr/share/applications/hildon-home/
        install src/feedingit_widget.desktop ${DESTDIR}/usr/share/applications/hildon-home/
        install -d ${DESTDIR}/usr/lib/hildon-desktop/
        install src/feedingit_widget.py ${DESTDIR}/usr/lib/hildon-desktop/
-       
+       #install src/feedingit_status.py ${DESTDIR}/usr/lib/hildon-desktop/
        
        
 clean:
diff --git a/data/40px.png b/data/40px.png
deleted file mode 100644 (file)
index 41be97a..0000000
Binary files a/data/40px.png and /dev/null differ
diff --git a/data/48px.png b/data/48px.png
new file mode 100644 (file)
index 0000000..07fbf83
Binary files /dev/null and b/data/48px.png differ
index f5190b9..2f31e00 100644 (file)
@@ -1,3 +1,23 @@
+feedingit (0.6.1-1) unstable; urgency=low
+
+  * Now use dbus as lock mechanisms
+  * Added setting to disable proxy support
+
+ -- Yves <yves@marcoz.org>  Sat, 24 Apr 2010 16:57:19 -0800
+
+feedingit (0.6.1-0) unstable; urgency=low
+
+  * Added autoupdate from the widget
+
+ -- Yves <yves@marcoz.org>  Sat, 17 Apr 2010 20:19:19 -0800
+
+feedingit (0.6.0-1) stable; urgency=low
+
+  * Added dbus communication from app to widget
+  * Fixed updates for articles without titles
+
+ -- Yves <yves@marcoz.org>  Mon, 12 Apr 2010 09:50:19 -0800
+
 feedingit (0.6.0-0) stable; urgency=low
 
   * Added home widget
index 3963b89..8a5a972 100644 (file)
@@ -4,7 +4,7 @@ Priority: optional
 Maintainer: Yves <yves@marcoz.org>
 Build-Depends: debhelper (>= 5)
 Standards-Version: 3.7.2
-XB-Maemo-Display-Name: FeedingIt                                                                                                                      
+XB-Maemo-Display-Name: FeedingIt RSS Reader
 XSBC-Bugtracker: https://garage.maemo.org/tracker/?func=browse&group_id=1202&atid=4512
 
 Package: feedingit
@@ -14,11 +14,9 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, python, python-hildon,
  python-hildondesktop, hildon-desktop-python-loader
 Description:
  RSS Reader
- Its main features are:
- - Portrait mode support
- - Auto-update
- - Swipe left or right while in articles to move to the previous or next article
- - Import/Export of OPML files
+ Its main features are portrait mode support, auto-update, swipe left or right while
+ in articles to move to the previous or next article, import/export of OPML files,
+ image caching, desktop widget
 XB-Maemo-Icon-26:
  iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c                                                                                                                                     
  6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAABl1J
diff --git a/debian/cron.d.ex b/debian/cron.d.ex
deleted file mode 100644 (file)
index cc0277d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# Regular cron jobs for the feedingit package
-#
-0 4    * * *   root    feedingit_maintenance
diff --git a/debian/emacsen-install.ex b/debian/emacsen-install.ex
deleted file mode 100644 (file)
index a6adfc1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /bin/sh -e
-# /usr/lib/emacsen-common/packages/install/feedingit
-
-# Written by Jim Van Zandt <jrv@debian.org>, borrowing heavily
-# from the install scripts for gettext by Santiago Vila
-# <sanvila@ctv.es> and octave by Dirk Eddelbuettel <edd@debian.org>.
-
-FLAVOR=$1
-PACKAGE=feedingit
-
-if [ ${FLAVOR} = emacs ]; then exit 0; fi
-
-echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR}
-
-#FLAVORTEST=`echo $FLAVOR | cut -c-6`
-#if [ ${FLAVORTEST} = xemacs ] ; then
-#    SITEFLAG="-no-site-file"
-#else
-#    SITEFLAG="--no-site-file"
-#fi
-FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile"
-
-ELDIR=/usr/share/emacs/site-lisp/${PACKAGE}
-ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE}
-
-# Install-info-altdir does not actually exist. 
-# Maybe somebody will write it.
-if test -x /usr/sbin/install-info-altdir; then
-    echo install/${PACKAGE}: install Info links for ${FLAVOR}
-    install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz
-fi
-
-install -m 755 -d ${ELCDIR}
-cd ${ELDIR}
-FILES=`echo *.el`
-cp ${FILES} ${ELCDIR}
-cd ${ELCDIR}
-
-cat << EOF > path.el
-(setq load-path (cons "." load-path) byte-compile-warnings nil)
-EOF
-${FLAVOR} ${FLAGS} ${FILES}
-rm -f *.el path.el
-
-exit 0
diff --git a/debian/emacsen-remove.ex b/debian/emacsen-remove.ex
deleted file mode 100644 (file)
index 9d784c7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh -e
-# /usr/lib/emacsen-common/packages/remove/feedingit
-
-FLAVOR=$1
-PACKAGE=feedingit
-
-if [ ${FLAVOR} != emacs ]; then
-    if test -x /usr/sbin/install-info-altdir; then
-        echo remove/${PACKAGE}: removing Info links for ${FLAVOR}
-        install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/feedingit.info.gz
-    fi
-
-    echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR}
-    rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE}
-fi
diff --git a/debian/emacsen-startup.ex b/debian/emacsen-startup.ex
deleted file mode 100644 (file)
index 4c5a503..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-;; -*-emacs-lisp-*-
-;;
-;; Emacs startup file, e.g.  /etc/emacs/site-start.d/50feedingit.el
-;; for the Debian feedingit package
-;;
-;; Originally contributed by Nils Naumann <naumann@unileoben.ac.at>
-;; Modified by Dirk Eddelbuettel <edd@debian.org>
-;; Adapted for dh-make by Jim Van Zandt <jrv@debian.org>
-
-;; The feedingit package follows the Debian/GNU Linux 'emacsen' policy and
-;; byte-compiles its elisp files for each 'emacs flavor' (emacs19,
-;; xemacs19, emacs20, xemacs20...).  The compiled code is then
-;; installed in a subdirectory of the respective site-lisp directory.
-;; We have to add this to the load-path:
-(let ((package-dir (concat "/usr/share/"
-                           (symbol-name flavor)
-                           "/site-lisp/feedingit")))
-;; If package-dir does not exist, the feedingit package must have
-;; removed but not purged, and we should skip the setup.
-  (when (file-directory-p package-dir)
-        (setq load-path (cons package-dir load-path))
-       (autoload 'feedingit-mode "feedingit-mode"
-         "Major mode for editing feedingit files." t)
-       (add-to-list 'auto-mode-alist '("\\.feedingit$" . feedingit-mode))))
-
diff --git a/debian/feedingit-default.ex b/debian/feedingit-default.ex
deleted file mode 100644 (file)
index 7b4e24d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# Defaults for feedingit initscript
-# sourced by /etc/init.d/feedingit
-# installed at /etc/default/feedingit by the maintainer scripts
-
-#
-# This is a POSIX shell fragment
-#
-
-# Additional options that are passed to the Daemon.
-DAEMON_OPTS=""
diff --git a/debian/feedingit.doc-base.EX b/debian/feedingit.doc-base.EX
deleted file mode 100644 (file)
index 29ef39a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Document: feedingit
-Title: Debian feedingit Manual
-Author: <insert document author here>
-Abstract: This manual describes what feedingit is
- and how it can be used to
- manage online manuals on Debian systems.
-Section: unknown
-
-Format: debiandoc-sgml
-Files: /usr/share/doc/feedingit/feedingit.sgml.gz
-
-Format: postscript
-Files: /usr/share/doc/feedingit/feedingit.ps.gz
-
-Format: text
-Files: /usr/share/doc/feedingit/feedingit.text.gz
-
-Format: HTML
-Index: /usr/share/doc/feedingit/html/index.html
-Files: /usr/share/doc/feedingit/html/*.html
-
-  
diff --git a/debian/init.d.ex b/debian/init.d.ex
deleted file mode 100644 (file)
index 63004c7..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#! /bin/sh
-#
-# skeleton     example file to build /etc/init.d/ scripts.
-#              This file should be used to construct scripts for /etc/init.d.
-#
-#              Written by Miquel van Smoorenburg <miquels@cistron.nl>.
-#              Modified for Debian 
-#              by Ian Murdock <imurdock@gnu.ai.mit.edu>.
-#
-# Version:     @(#)skeleton  1.9  26-Feb-2001  miquels@cistron.nl
-#
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DAEMON=/usr/sbin/feedingit
-NAME=feedingit
-DESC=feedingit
-
-test -x $DAEMON || exit 0
-
-# Include feedingit defaults if available
-if [ -f /etc/default/feedingit ] ; then
-       . /etc/default/feedingit
-fi
-
-set -e
-
-case "$1" in
-  start)
-       echo -n "Starting $DESC: "
-       start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
-               --exec $DAEMON -- $DAEMON_OPTS
-       echo "$NAME."
-       ;;
-  stop)
-       echo -n "Stopping $DESC: "
-       start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
-               --exec $DAEMON
-       echo "$NAME."
-       ;;
-  #reload)
-       #
-       #       If the daemon can reload its config files on the fly
-       #       for example by sending it SIGHUP, do it here.
-       #
-       #       If the daemon responds to changes in its config file
-       #       directly anyway, make this a do-nothing entry.
-       #
-       # echo "Reloading $DESC configuration files."
-       # start-stop-daemon --stop --signal 1 --quiet --pidfile \
-       #       /var/run/$NAME.pid --exec $DAEMON
-  #;;
-  force-reload)
-       #
-       #       If the "reload" option is implemented, move the "force-reload"
-       #       option to the "reload" entry above. If not, "force-reload" is
-       #       just the same as "restart" except that it does nothing if the
-       #   daemon isn't already running.
-       # check wether $DAEMON is running. If so, restart
-       start-stop-daemon --stop --test --quiet --pidfile \
-               /var/run/$NAME.pid --exec $DAEMON \
-       && $0 restart \
-       || exit 0
-       ;;
-  restart)
-    echo -n "Restarting $DESC: "
-       start-stop-daemon --stop --quiet --pidfile \
-               /var/run/$NAME.pid --exec $DAEMON
-       sleep 1
-       start-stop-daemon --start --quiet --pidfile \
-               /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
-       echo "$NAME."
-       ;;
-  *)
-       N=/etc/init.d/$NAME
-       # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
-       echo "Usage: $N {start|stop|restart|force-reload}" >&2
-       exit 1
-       ;;
-esac
-
-exit 0
diff --git a/debian/manpage.1.ex b/debian/manpage.1.ex
deleted file mode 100644 (file)
index 837f0e0..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-.\"                                      Hey, EMACS: -*- nroff -*-
-.\" First parameter, NAME, should be all caps
-.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
-.\" other parameters are allowed: see man(7), man(1)
-.TH FEEDINGIT SECTION "December 28, 2009"
-.\" Please adjust this date whenever revising the manpage.
-.\"
-.\" Some roff macros, for reference:
-.\" .nh        disable hyphenation
-.\" .hy        enable hyphenation
-.\" .ad l      left justify
-.\" .ad b      justify to both left and right margins
-.\" .nf        disable filling
-.\" .fi        enable filling
-.\" .br        insert line break
-.\" .sp <n>    insert n+1 empty lines
-.\" for manpage-specific macros, see man(7)
-.SH NAME
-feedingit \- program to do something
-.SH SYNOPSIS
-.B feedingit
-.RI [ options ] " files" ...
-.br
-.B bar
-.RI [ options ] " files" ...
-.SH DESCRIPTION
-This manual page documents briefly the
-.B feedingit
-and
-.B bar
-commands.
-.PP
-.\" TeX users may be more comfortable with the \fB<whatever>\fP and
-.\" \fI<whatever>\fP escape sequences to invode bold face and italics, 
-.\" respectively.
-\fBfeedingit\fP is a program that...
-.SH OPTIONS
-These programs follow the usual GNU command line syntax, with long
-options starting with two dashes (`-').
-A summary of options is included below.
-For a complete description, see the Info files.
-.TP
-.B \-h, \-\-help
-Show summary of options.
-.TP
-.B \-v, \-\-version
-Show version of program.
-.SH SEE ALSO
-.BR bar (1),
-.BR baz (1).
-.br
-The programs are documented fully by
-.IR "The Rise and Fall of a Fooish Bar" ,
-available via the Info system.
-.SH AUTHOR
-feedingit was written by <upstream author>.
-.PP
-This manual page was written by unknown <yves@marcoz.org>,
-for the Debian project (but may be used by others).
diff --git a/debian/manpage.sgml.ex b/debian/manpage.sgml.ex
deleted file mode 100644 (file)
index d1a98d1..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
-
-<!-- Process this file with docbook-to-man to generate an nroff manual
-     page: `docbook-to-man manpage.sgml > manpage.1'.  You may view
-     the manual page with: `docbook-to-man manpage.sgml | nroff -man |
-     less'.  A typical entry in a Makefile or Makefile.am is:
-
-manpage.1: manpage.sgml
-       docbook-to-man $< > $@
-
-    
-       The docbook-to-man binary is found in the docbook-to-man package.
-       Please remember that if you create the nroff version in one of the
-       debian/rules file targets (such as build), you will need to include
-       docbook-to-man in your Build-Depends control field.
-
-  -->
-
-  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
-  <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
-  <!ENTITY dhsurname   "<surname>SURNAME</surname>">
-  <!-- Please adjust the date whenever revising the manpage. -->
-  <!ENTITY dhdate      "<date>December 28, 2009</date>">
-  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
-       allowed: see man(7), man(1). -->
-  <!ENTITY dhsection   "<manvolnum>SECTION</manvolnum>">
-  <!ENTITY dhemail     "<email>yves@marcoz.org</email>">
-  <!ENTITY dhusername  "unknown">
-  <!ENTITY dhucpackage "<refentrytitle>FEEDINGIT</refentrytitle>">
-  <!ENTITY dhpackage   "feedingit">
-
-  <!ENTITY debian      "<productname>Debian</productname>">
-  <!ENTITY gnu         "<acronym>GNU</acronym>">
-  <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
-]>
-
-<refentry>
-  <refentryinfo>
-    <address>
-      &dhemail;
-    </address>
-    <author>
-      &dhfirstname;
-      &dhsurname;
-    </author>
-    <copyright>
-      <year>2003</year>
-      <holder>&dhusername;</holder>
-    </copyright>
-    &dhdate;
-  </refentryinfo>
-  <refmeta>
-    &dhucpackage;
-
-    &dhsection;
-  </refmeta>
-  <refnamediv>
-    <refname>&dhpackage;</refname>
-
-    <refpurpose>program to do something</refpurpose>
-  </refnamediv>
-  <refsynopsisdiv>
-    <cmdsynopsis>
-      <command>&dhpackage;</command>
-
-      <arg><option>-e <replaceable>this</replaceable></option></arg>
-
-      <arg><option>--example <replaceable>that</replaceable></option></arg>
-    </cmdsynopsis>
-  </refsynopsisdiv>
-  <refsect1>
-    <title>DESCRIPTION</title>
-
-    <para>This manual page documents briefly the
-      <command>&dhpackage;</command> and <command>bar</command>
-      commands.</para>
-
-    <para>This manual page was written for the &debian; distribution
-      because the original program does not have a manual page.
-      Instead, it has documentation in the &gnu;
-      <application>Info</application> format; see below.</para>
-
-    <para><command>&dhpackage;</command> is a program that...</para>
-
-  </refsect1>
-  <refsect1>
-    <title>OPTIONS</title>
-
-    <para>These programs follow the usual &gnu; command line syntax,
-      with long options starting with two dashes (`-').  A summary of
-      options is included below.  For a complete description, see the
-      <application>Info</application> files.</para>
-
-    <variablelist>
-      <varlistentry>
-        <term><option>-h</option>
-          <option>--help</option>
-        </term>
-        <listitem>
-          <para>Show summary of options.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>-v</option>
-          <option>--version</option>
-        </term>
-        <listitem>
-          <para>Show version of program.</para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-  <refsect1>
-    <title>SEE ALSO</title>
-
-    <para>bar (1), baz (1).</para>
-
-    <para>The programs are documented fully by <citetitle>The Rise and
-      Fall of a Fooish Bar</citetitle> available via the
-      <application>Info</application> system.</para>
-  </refsect1>
-  <refsect1>
-    <title>AUTHOR</title>
-
-    <para>This manual page was written by &dhusername; &dhemail; for
-      the &debian; system (but may be used by others).  Permission is
-      granted to copy, distribute and/or modify this document under
-      the terms of the &gnu; General Public License, Version 2 any 
-         later version published by the Free Software Foundation.
-    </para>
-       <para>
-         On Debian systems, the complete text of the GNU General Public
-         License can be found in /usr/share/common-licenses/GPL.
-       </para>
-
-  </refsect1>
-</refentry>
-
-<!-- Keep this comment at the end of the file
-Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:2
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-default-dtd-file:nil
-sgml-exposed-tags:nil
-sgml-local-catalogs:nil
-sgml-local-ecat-files:nil
-End:
--->
-
-
diff --git a/debian/manpage.xml.ex b/debian/manpage.xml.ex
deleted file mode 100644 (file)
index a6011aa..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
-
-<!--
-
-Process this file with an XSLT processor: `xsltproc \
--''-nonet /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
-manpages/docbook.xsl manpage.dbk'.  A manual page
-<package>.<section> will be generated.  You may view the
-manual page with: nroff -man <package>.<section> | less'.  A
-typical entry in a Makefile or Makefile.am is:
-
-DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
-manpages/docbook.xsl
-XP=xsltproc -''-nonet
-
-manpage.1: manpage.dbk
-        $(XP) $(DB2MAN) $<
-    
-The xsltproc binary is found in the xsltproc package.  The
-XSL files are in docbook-xsl.  Please remember that if you
-create the nroff version in one of the debian/rules file
-targets (such as build), you will need to include xsltproc
-and docbook-xsl in your Build-Depends control field.
-
--->
-
-  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
-  <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
-  <!ENTITY dhsurname   "<surname>SURNAME</surname>">
-  <!-- Please adjust the date whenever revising the manpage. -->
-  <!ENTITY dhdate      "<date>December 28, 2009</date>">
-  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
-       allowed: see man(7), man(1). -->
-  <!ENTITY dhsection   "<manvolnum>SECTION</manvolnum>">
-  <!ENTITY dhemail     "<email>yves@marcoz.org</email>">
-  <!ENTITY dhusername  "unknown">
-  <!ENTITY dhucpackage "<refentrytitle>FEEDINGIT</refentrytitle>">
-  <!ENTITY dhpackage   "feedingit">
-
-  <!ENTITY debian      "<productname>Debian</productname>">
-  <!ENTITY gnu         "<acronym>GNU</acronym>">
-  <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
-]>
-
-<refentry>
-  <refentryinfo>
-    <address>
-      &dhemail;
-    </address>
-    <author>
-      &dhfirstname;
-      &dhsurname;
-    </author>
-    <copyright>
-      <year>2003</year>
-      <holder>&dhusername;</holder>
-    </copyright>
-    &dhdate;
-  </refentryinfo>
-  <refmeta>
-    &dhucpackage;
-
-    &dhsection;
-  </refmeta>
-  <refnamediv>
-    <refname>&dhpackage;</refname>
-
-    <refpurpose>program to do something</refpurpose>
-  </refnamediv>
-  <refsynopsisdiv>
-    <cmdsynopsis>
-      <command>&dhpackage;</command>
-
-      <arg><option>-e <replaceable>this</replaceable></option></arg>
-
-      <arg><option>--example <replaceable>that</replaceable></option></arg>
-    </cmdsynopsis>
-  </refsynopsisdiv>
-  <refsect1>
-    <title>DESCRIPTION</title>
-
-    <para>This manual page documents briefly the
-      <command>&dhpackage;</command> and <command>bar</command>
-      commands.</para>
-
-    <para>This manual page was written for the &debian; distribution
-      because the original program does not have a manual page.
-      Instead, it has documentation in the &gnu;
-      <application>Info</application> format; see below.</para>
-
-    <para><command>&dhpackage;</command> is a program that...</para>
-
-  </refsect1>
-  <refsect1>
-    <title>OPTIONS</title>
-
-    <para>These programs follow the usual &gnu; command line syntax,
-      with long options starting with two dashes (`-').  A summary of
-      options is included below.  For a complete description, see the
-      <application>Info</application> files.</para>
-
-    <variablelist>
-      <varlistentry>
-        <term><option>-h</option>
-          <option>--help</option>
-        </term>
-        <listitem>
-          <para>Show summary of options.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>-v</option>
-          <option>--version</option>
-        </term>
-        <listitem>
-          <para>Show version of program.</para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-  <refsect1>
-    <title>SEE ALSO</title>
-
-    <para>bar (1), baz (1).</para>
-
-    <para>The programs are documented fully by <citetitle>The Rise and
-      Fall of a Fooish Bar</citetitle> available via the
-      <application>Info</application> system.</para>
-  </refsect1>
-  <refsect1>
-    <title>AUTHOR</title>
-
-    <para>This manual page was written by &dhusername; &dhemail; for
-      the &debian; system (but may be used by others).  Permission is
-      granted to copy, distribute and/or modify this document under
-      the terms of the &gnu; General Public License, Version 2 any 
-         later version published by the Free Software Foundation.
-    </para>
-       <para>
-         On Debian systems, the complete text of the GNU General Public
-         License can be found in /usr/share/common-licenses/GPL.
-       </para>
-
-  </refsect1>
-</refentry>
-
diff --git a/debian/menu.ex b/debian/menu.ex
deleted file mode 100644 (file)
index b440db3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-?package(feedingit):needs="X11|text|vc|wm" section="Apps/see-menu-manual"\
-  title="feedingit" command="/usr/bin/feedingit"
diff --git a/debian/postinst.ex b/debian/postinst.ex
deleted file mode 100644 (file)
index ff994dd..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-# postinst script for feedingit
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <postinst> `configure' <most-recently-configured-version>
-#        * <old-postinst> `abort-upgrade' <new version>
-#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
-#          <new-version>
-#        * <postinst> `abort-remove'
-#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
-#          <failed-install-package> <version> `removing'
-#          <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-    configure)
-    ;;
-
-    abort-upgrade|abort-remove|abort-deconfigure)
-    ;;
-
-    *)
-        echo "postinst called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/postrm.ex b/debian/postrm.ex
deleted file mode 100644 (file)
index b962cae..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# postrm script for feedingit
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <postrm> `remove'
-#        * <postrm> `purge'
-#        * <old-postrm> `upgrade' <new-version>
-#        * <new-postrm> `failed-upgrade' <old-version>
-#        * <new-postrm> `abort-install'
-#        * <new-postrm> `abort-install' <old-version>
-#        * <new-postrm> `abort-upgrade' <old-version>
-#        * <disappearer's-postrm> `disappear' <overwriter>
-#          <overwriter-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-    purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
-    ;;
-
-    *)
-        echo "postrm called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/preinst.ex b/debian/preinst.ex
deleted file mode 100644 (file)
index a5b99ca..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-# preinst script for feedingit
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <new-preinst> `install'
-#        * <new-preinst> `install' <old-version>
-#        * <new-preinst> `upgrade' <old-version>
-#        * <old-preinst> `abort-upgrade' <new-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-    install|upgrade)
-    ;;
-
-    abort-upgrade)
-    ;;
-
-    *)
-        echo "preinst called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/prerm.ex b/debian/prerm.ex
deleted file mode 100644 (file)
index 967a168..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-# prerm script for feedingit
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <prerm> `remove'
-#        * <old-prerm> `upgrade' <new-version>
-#        * <new-prerm> `failed-upgrade' <old-version>
-#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
-#        * <deconfigured's-prerm> `deconfigure' `in-favour'
-#          <package-being-installed> <version> `removing'
-#          <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-    remove|upgrade|deconfigure)
-    ;;
-
-    failed-upgrade)
-    ;;
-
-    *)
-        echo "prerm called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
index a0160e4..b3be2d1 100644 (file)
@@ -1,11 +1,16 @@
 #!/bin/sh
 case "$1" in
 update)
-    dbus-send --print-reply --dest='org.maemo.feedingit' --session /org/maemo/feedingit org.maemo.feedingit.Update
+    dbus-send --print-reply --dest='org.marcoz.feedingit' --session /org/marcoz/feedingit/update org.marcoz.feedingit.UpdateAll
     ;;
 status)
     dbus-send --print-reply --dest='org.maemo.feedingit' --session /org/maemo/feedingit org.maemo.feedingit.GetStatus
     ;;
+dbus)
+       cd /opt/FeedingIt
+       #cp feedingit_status.desktop /usr/share/applications/hildon-status-menu/
+       python2.5 update_feeds.py
+       ;;
 *)
     cd /opt/FeedingIt
     python2.5 FeedingIt.py
index fa98319..eac727b 100644 (file)
@@ -1,6 +1,6 @@
 [Desktop Entry]
 Encoding=UTF-8
-Version=0.1.1
+Version=0.6.1
 Type=Application
 Name=FeedingIt
 Exec=/usr/bin/FeedingIt
index ce0369c..27f978a 100644 (file)
 # ============================================================================
 # Name        : FeedingIt.py
 # Author      : Yves Marcoz
-# Version     : 0.5.4
+# Version     : 0.6.0
 # Description : Simple RSS Reader
 # ============================================================================
 
 import gtk
-import feedparser
-import pango
+from pango import FontDescription
 import hildon
 #import gtkhtml2
 #try:
-import webkit
+from webkit import WebView
 #    has_webkit=True
 #except:
 #    import gtkhtml2
 #    has_webkit=False
-import time
-import dbus
-import pickle
-from os.path import isfile, isdir
-from os import mkdir
-import sys   
-import urllib2
+from os.path import isfile, isdir, exists
+from os import mkdir, remove, stat
 import gobject
 from portrait import FremantleRotation
-import threading
-import thread
+from threading import Thread, activeCount
 from feedingitdbus import ServerObject
+from updatedbus import UpdateServerObject, get_lock
 from config import Config
 from cgi import escape
 
-from rss import *
+from rss import Listing
 from opml import GetOpmlData, ExportOpmlData
-   
-import socket
+
+from socket import setdefaulttimeout
 timeout = 5
-socket.setdefaulttimeout(timeout)
+setdefaulttimeout(timeout)
+del timeout
 
 color_style = gtk.rc_get_style_by_paths(gtk.settings_get_default() , 'GtkButton', 'osso-logical-colors', gtk.Button)
 unread_color = color_style.lookup_color('ActiveTextColor')
@@ -62,6 +57,38 @@ read_color = color_style.lookup_color('DefaultTextColor')
 del color_style
 
 CONFIGDIR="/home/user/.feedingit/"
+LOCK = CONFIGDIR + "update.lock"
+
+from re import sub
+from htmlentitydefs import name2codepoint
+
+##
+# Removes HTML or XML character references and entities from a text string.
+#
+# @param text The HTML (or XML) source text.
+# @return The plain text, as a Unicode string, if necessary.
+# http://effbot.org/zone/re-sub.htm#unescape-html
+def unescape(text):
+    def fixup(m):
+        text = m.group(0)
+        if text[:2] == "&#":
+            # character reference
+            try:
+                if text[:3] == "&#x":
+                    return unichr(int(text[3:-1], 16))
+                else:
+                    return unichr(int(text[2:-1]))
+            except ValueError:
+                pass
+        else:
+            # named entity
+            try:
+                text = unichr(name2codepoint[text[1:-1]])
+            except KeyError:
+                pass
+        return text # leave as is
+    return sub("&#?\w+;", fixup, text)
+
 
 class AddWidgetWizard(hildon.WizardDialog):
     
@@ -121,92 +148,52 @@ class AddWidgetWizard(hildon.WizardDialog):
             return False
         else:
             return True
-
-#class GetImage(threading.Thread):
-#    def __init__(self, url, stream):
-#        threading.Thread.__init__(self)
-#        self.url = url
-#        self.stream = stream
-#    
-#    def run(self):
-#        f = urllib2.urlopen(self.url)
-#        data = f.read()
-#        f.close()
-#        self.stream.write(data)
-#        self.stream.close()
-#
-#class ImageDownloader():
-#    def __init__(self):
-#        self.images = []
-#        self.downloading = False
-#        
-#    def queueImage(self, url, stream):
-#        self.images.append((url, stream))
-#        if not self.downloading:
-#            self.downloading = True
-#            gobject.timeout_add(50, self.checkQueue)
-#        
-#    def checkQueue(self):
-#        for i in range(4-threading.activeCount()):
-#            if len(self.images) > 0:
-#                (url, stream) = self.images.pop() 
-#                GetImage(url, stream).start()
-#        if len(self.images)>0:
-#            gobject.timeout_add(200, self.checkQueue)
-#        else:
-#            self.downloading=False
-#            
-#    def stopAll(self):
-#        self.images = []
-        
-        
-class Download(threading.Thread):
+        
+class Download(Thread):
     def __init__(self, listing, key, config):
-        threading.Thread.__init__(self)
+        Thread.__init__(self)
         self.listing = listing
         self.key = key
         self.config = config
         
     def run (self):
         (use_proxy, proxy) = self.config.getProxy()
-        if use_proxy:
-            self.listing.updateFeed(self.key, self.config.getExpiry(), proxy=proxy, imageCache=self.config.getImageCache() )
-        else:
-            self.listing.updateFeed(self.key, self.config.getExpiry(), imageCache=self.config.getImageCache() )
+        key_lock = get_lock(self.key)
+        if key_lock != None:
+            if use_proxy:
+                from urllib2 import install_opener, build_opener
+                install_opener(build_opener(proxy))
+                self.listing.updateFeed(self.key, self.config.getExpiry(), proxy=proxy, imageCache=self.config.getImageCache() )
+            else:
+                self.listing.updateFeed(self.key, self.config.getExpiry(), imageCache=self.config.getImageCache() )
+        del key_lock
 
         
 class DownloadBar(gtk.ProgressBar):
     def __init__(self, parent, listing, listOfKeys, config, single=False):
-        gtk.ProgressBar.__init__(self)
-        self.listOfKeys = listOfKeys[:]
-        self.listing = listing
-        self.total = len(self.listOfKeys)
-        self.config = config
-        self.current = 0
-        self.single = single
-        
-        if self.total>0:
-            #self.progress = gtk.ProgressBar()
-            #self.waitingWindow = hildon.Note("cancel", parent, "Downloading",
-            #                     progressbar=self.progress)
-            self.set_text("Updating...")
-            self.fraction = 0
-            self.set_fraction(self.fraction)
-            self.show_all()
-            # Create a timeout
-            self.timeout_handler_id = gobject.timeout_add(50, self.update_progress_bar)
-            #self.waitingWindow.show_all()
-            #response = self.waitingWindow.run()
-            #self.listOfKeys = []
-            #while threading.activeCount() > 1:
-                # Wait for current downloads to finish
-            #    time.sleep(0.1)
-            #self.waitingWindow.destroy()
+        
+        update_lock = get_lock("update_lock")
+        if update_lock != None:
+            gtk.ProgressBar.__init__(self)
+            self.listOfKeys = listOfKeys[:]
+            self.listing = listing
+            self.total = len(self.listOfKeys)
+            self.config = config
+            self.current = 0
+            self.single = single
+
+            if self.total>0:
+                self.set_text("Updating...")
+                self.fraction = 0
+                self.set_fraction(self.fraction)
+                self.show_all()
+                # Create a timeout
+                self.timeout_handler_id = gobject.timeout_add(50, self.update_progress_bar)
 
     def update_progress_bar(self):
         #self.progress_bar.pulse()
-        if threading.activeCount() < 4:
-            x = threading.activeCount() - 1
+        if activeCount() < 4:
+            x = activeCount() - 1
             k = len(self.listOfKeys)
             fin = self.total - k - x
             fraction = float(fin)/float(self.total) + float(x)/(self.total*2.)
@@ -216,16 +203,20 @@ class DownloadBar(gtk.ProgressBar):
             if len(self.listOfKeys)>0:
                 self.current = self.current+1
                 key = self.listOfKeys.pop()
-                if (not self.listing.getCurrentlyDisplayedFeed() == key) or (self.single == True):
+                #if self.single == True:
                     # Check if the feed is being displayed
-                    download = Download(self.listing, key, self.config)
-                    download.start()
+                download = Download(self.listing, key, self.config)
+                download.start()
                 return True
-            elif threading.activeCount() > 1:
+            elif activeCount() > 1:
                 return True
             else:
                 #self.waitingWindow.destroy()
                 #self.destroy()
+                try:
+                    del self.update_lock
+                except:
+                    pass
                 self.emit("download-done", "success")
                 return False 
         return True
@@ -385,7 +376,7 @@ class DisplayArticle(hildon.StackableWindow):
         
         # Init the article display
         #if self.config.getWebkitSupport():
-        self.view = webkit.WebView()
+        self.view = WebView()
             #self.view.set_editable(False)
         #else:
         #    import gtkhtml2
@@ -510,6 +501,7 @@ class DisplayArticle(hildon.StackableWindow):
     #    self.show_all()
 
     def _signal_link_clicked(self, object, link):
+        import dbus
         bus = dbus.SessionBus()
         proxy = bus.get_object("com.nokia.osso_browser", "/com/nokia/osso_browser/request")
         iface = dbus.Interface(proxy, 'com.nokia.osso_browser')
@@ -572,17 +564,18 @@ class DisplayFeed(hildon.StackableWindow):
         self.buttons = {}
         for id in self.feed.getIds():
             title = self.feed.getTitle(id)
-            esc_title = title.replace("<em>","").replace("</em>","").replace("&amp;","&").replace("&mdash;", "-").replace("&#8217;", "'")
+            esc_title = unescape(title)
+            #title.replace("<em>","").replace("</em>","").replace("&amp;","&").replace("&mdash;", "-").replace("&#8217;", "'")
             button = gtk.Button(esc_title)
             button.set_alignment(0,0)
             label = button.child
             if self.feed.isEntryRead(id):
-                #label.modify_font(pango.FontDescription("sans 16"))
-                label.modify_font(pango.FontDescription(self.config.getReadFont()))
+                #label.modify_font(FontDescription("sans 16"))
+                label.modify_font(FontDescription(self.config.getReadFont()))
                 label.modify_fg(gtk.STATE_NORMAL, read_color) # gtk.gdk.color_parse("white"))
             else:
                 #print self.listing.getFont() + " bold"
-                label.modify_font(pango.FontDescription(self.config.getUnreadFont()))
+                label.modify_font(FontDescription(self.config.getUnreadFont()))
                 label.modify_fg(gtk.STATE_NORMAL, unread_color)
             label.set_line_wrap(True)
             
@@ -629,21 +622,21 @@ class DisplayFeed(hildon.StackableWindow):
 
     def nextArticle(self, object, index):
         label = self.buttons[index].child
-        label.modify_font(pango.FontDescription(self.config.getReadFont()))
+        label.modify_font(FontDescription(self.config.getReadFont()))
         label.modify_fg(gtk.STATE_NORMAL, read_color) #  gtk.gdk.color_parse("white"))
         id = self.feed.getNextId(index)
         self.button_clicked(object, id, next=True)
 
     def previousArticle(self, object, index):
         label = self.buttons[index].child
-        label.modify_font(pango.FontDescription(self.config.getReadFont()))
+        label.modify_font(FontDescription(self.config.getReadFont()))
         label.modify_fg(gtk.STATE_NORMAL, read_color) # gtk.gdk.color_parse("white"))
         id = self.feed.getPreviousId(index)
         self.button_clicked(object, id, previous=True)
 
     def onArticleClosed(self, object, index):
         label = self.buttons[index].child
-        label.modify_font(pango.FontDescription(self.config.getReadFont()))
+        label.modify_font(FontDescription(self.config.getReadFont()))
         label.modify_fg(gtk.STATE_NORMAL, read_color) # gtk.gdk.color_parse("white"))
         self.buttons[index].show()
 
@@ -662,12 +655,13 @@ class DisplayFeed(hildon.StackableWindow):
         self.vbox.destroy()
         self.feed = self.listing.getFeed(self.key)
         self.displayFeed()
+        self.updateDbusHandler.ArticleCountUpdated()
         
     def buttonReadAllClicked(self, button):
         for index in self.feed.getIds():
             self.feed.setEntryRead(index)
             label = self.buttons[index].child
-            label.modify_font(pango.FontDescription(self.config.getReadFont()))
+            label.modify_font(FontDescription(self.config.getReadFont()))
             label.modify_fg(gtk.STATE_NORMAL, read_color) # gtk.gdk.color_parse("white"))
             self.buttons[index].show()
 
@@ -687,6 +681,11 @@ class FeedingIt:
         gobject.idle_add(self.createWindow)
         
     def createWindow(self):
+        self.app_lock = get_lock("app_lock")
+        if self.app_lock == None:
+            self.pannableListing.set_label("Update in progress, please wait.")
+            gobject.timeout_add_seconds(3, self.createWindow)
+            return False
         self.listing = Listing(CONFIGDIR)
         
         self.downloadDialog = False
@@ -739,6 +738,7 @@ class FeedingIt:
         
     def enableDbus(self):
         self.dbusHandler = ServerObject(self)
+        self.updateDbusHandler = UpdateServerObject(self)
 
     def button_markAll(self, button):
         for key in self.listing.getListOfFeeds():
@@ -778,6 +778,7 @@ class FeedingIt:
         
     def button_update_clicked(self, button, key):
         if not type(self.downloadDialog).__name__=="DownloadBar":
+            self.updateDbusHandler.UpdateStarted()
             self.downloadDialog = DownloadBar(self.window, self.listing, self.listing.getListOfFeeds(), self.config )
             self.downloadDialog.connect("download-done", self.onDownloadsDone)
             self.mainVbox.pack_end(self.downloadDialog, expand=False, fill=False)
@@ -789,7 +790,8 @@ class FeedingIt:
         self.downloadDialog = False
         #self.displayListing()
         self.refreshList()
-        self.dbusHandler.ArticleCountUpdated()
+        self.updateDbusHandler.UpdateFinished()
+        self.updateDbusHandler.ArticleCountUpdated()
 
     def button_preferences_clicked(self, button):
         dialog = self.config.createDialog()
@@ -851,18 +853,25 @@ class FeedingIt:
                 break
 
     def buttonFeedClicked(widget, button, self, window, key):
-        self.disp = DisplayFeed(self.listing, self.listing.getFeed(key), self.listing.getFeedTitle(key), key, self.config)
-        self.disp.connect("feed-closed", self.onFeedClosed)
+        try:
+            self.feed_lock
+        except:
+            # If feed_lock doesn't exist, we can open the feed, else we do nothing
+            self.feed_lock = get_lock(key)
+            self.disp = DisplayFeed(self.listing, self.listing.getFeed(key), self.listing.getFeedTitle(key), key, self.config)
+            self.disp.connect("feed-closed", self.onFeedClosed)
 
     def onFeedClosed(self, object, key):
         self.listing.saveConfig()
+        del self.feed_lock
         self.refreshList()
-        self.dbusHandler.ArticleCountUpdated()
+        self.updateDbusHandler.ArticleCountUpdated()
      
     def run(self):
         self.window.connect("destroy", gtk.main_quit)
         gtk.main()
         self.listing.saveConfig()
+        del self.app_lock
 
     def prefsClosed(self, *widget):
         self.orientation.set_mode(self.config.getOrientation())
@@ -891,6 +900,13 @@ class FeedingIt:
         self.button_update_clicked(None, None)
         return True
     
+    def stopUpdate(self):
+        # Not implemented in the app (see update_feeds.py)
+        try:
+            self.downloadDialog.listOfKeys = []
+        except:
+            pass
+    
     def getStatus(self):
         status = ""
         for key in self.listing.getListOfFeeds():
@@ -912,6 +928,7 @@ if __name__ == "__main__":
             mkdir(CONFIGDIR)
         except:
             print "Error: Can't create configuration directory"
-            sys.exit(1)
+            from sys import exit
+            exit(1)
     app = FeedingIt()
     app.run()
index 2e7f817..409f93e 100644 (file)
 # ============================================================================
 # Name        : FeedingIt.py
 # Author      : Yves Marcoz
-# Version     : 0.5.4
+# Version     : 0.6.1
 # Description : Simple RSS Reader
 # ============================================================================
 
 import gtk
 import hildon
-import ConfigParser
-import gobject
-import gconf
-import urllib2
+from ConfigParser import RawConfigParser
+from gobject import idle_add
+from gconf import client_get_default
+from urllib2 import ProxyHandler
 
-VERSION = "0.5.4"
+VERSION = "0.6.1"
 
 section = "FeedingIt"
 ranges = { "updateInterval":[0.5, 1, 2, 4, 12, 24], "expiry":[24, 48, 72], "fontSize":range(12,24), "orientation":["Automatic", "Landscape", "Portrait"], "artFontSize":[10, 12, 14, 16, 18, 20]}
@@ -65,7 +65,7 @@ class Config():
             vbox.pack_start(picker, expand=False)
         
         button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
-        button.set_label("Auto-update Enabled")
+        button.set_label("Auto-update Enabled.")
         button.set_active(self.config["autoupdate"])
         button.connect("toggled", self.button_toggled, "autoupdate")
         vbox.pack_start(button, expand=False)
@@ -76,6 +76,12 @@ class Config():
         button.connect("toggled", self.button_toggled, "imageCache")
         vbox.pack_start(button, expand=False)
         
+        button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
+        button.set_label("Proxy Support Enabled")
+        button.set_active(self.config["proxy"])
+        button.connect("toggled", self.button_toggled, "proxy")
+        vbox.pack_start(button, expand=False)
+        
         button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
         button.set_label("View Known Issues and Tips")
         button.connect("clicked", self.button_tips_clicked)
@@ -124,7 +130,7 @@ class Config():
     def loadConfig(self):
         self.config = {}
         try:
-            configParser = ConfigParser.RawConfigParser()
+            configParser = RawConfigParser()
             configParser.read(self.configFilename)
             self.config["fontSize"] = configParser.getint(section, "fontSize")
             self.config["artFontSize"] = configParser.getint(section, "artFontSize")
@@ -141,9 +147,13 @@ class Config():
             self.config["updateInterval"] = 4
             self.config["orientation"] = "Automatic"
             self.config["imageCache"] = False
+        try:
+            self.config["proxy"] = configParser.getboolean(section, "proxy")
+        except:
+            self.config["proxy"] = True
         
     def saveConfig(self):
-        configParser = ConfigParser.RawConfigParser()
+        configParser = RawConfigParser()
         configParser.add_section(section)
         configParser.set(section, 'fontSize', str(self.config["fontSize"]))
         configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
@@ -152,6 +162,7 @@ class Config():
         configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
         configParser.set(section, 'orientation', str(self.config["orientation"]))
         configParser.set(section, 'imageCache', str(self.config["imageCache"]))
+        configParser.set(section, 'proxy', str(self.config["proxy"]))
 
         # Writing our configuration file
         file = open(self.configFilename, 'wb')
@@ -191,9 +202,11 @@ class Config():
     def getImageCache(self):
         return self.config["imageCache"]
     def getProxy(self):
-        if gconf.client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
-            port = gconf.client_get_default().get_int('/system/http_proxy/port')
-            http = gconf.client_get_default().get_string('/system/http_proxy/host')
-            proxy = proxy = urllib2.ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
+        if self.config["proxy"] == False:
+            return (False, None)
+        if client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
+            port = client_get_default().get_int('/system/http_proxy/port')
+            http = client_get_default().get_string('/system/http_proxy/host')
+            proxy = ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
             return (True, proxy)
         return (False, None)
\ No newline at end of file
index 86c7613..5e3bece 100644 (file)
@@ -1,3 +1,3 @@
 [D-BUS Service]
 Name=org.maemo.feedingit
-Exec=/usr/bin/FeedingIt
\ No newline at end of file
+Exec=/usr/bin/FeedingIt
diff --git a/src/feedingit_status.desktop b/src/feedingit_status.desktop
new file mode 100644 (file)
index 0000000..8601e66
--- /dev/null
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Name=Example
+Type=python
+X-Path=feedingit_status
\ No newline at end of file
diff --git a/src/feedingit_status.py b/src/feedingit_status.py
new file mode 100644 (file)
index 0000000..744fab9
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python2.5
+# 
+# Copyright (c) 2007-2008 INdT.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# ============================================================================
+# Name        : FeedingIt.py
+# Author      : Yves Marcoz
+# Version     : 0.6.1
+# Description : Simple RSS Reader
+# ============================================================================
+
+import gtk
+import hildondesktop
+
+class FeedingItStatusPlugin(hildondesktop.StatusMenuItem):
+    def __init__(self):
+        hildondesktop.StatusMenuItem.__init__(self)
+
+        icon_theme = gtk.icon_theme_get_default()
+        pixbuf = icon_theme.load_icon("feedingit", 22, gtk.ICON_LOOKUP_NO_SVG)
+        self.set_status_area_icon(pixbuf)
+
+        label = gtk.Label("Example message")
+        self.add(label)
+        self.show_all()
+
+hd_plugin_type = FeedingItStatusPlugin
\ No newline at end of file
diff --git a/src/feedingit_status.service b/src/feedingit_status.service
new file mode 100644 (file)
index 0000000..9fc5897
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.marcoz.feedingit
+Exec=/usr/bin/FeedingIt dbus
index ed080b3..c6eeb78 100644 (file)
 # ============================================================================
 # Name        : FeedingIt.py
 # Author      : Yves Marcoz
-# Version     : 0.5.4
+# Version     : 0.6.0
 # Description : Simple RSS Reader
 # ============================================================================
 #import sys
-#sys.path.insert(0, '/opt/FeedingIt')
-#sys.path.insert(0, '/home/user/workspace/feedingit/src/')
 
 import gtk, pickle, gobject, dbus
 import hildondesktop, hildon
@@ -34,10 +32,23 @@ import hildondesktop, hildon
 import dbus
 from dbus.mainloop.glib import DBusGMainLoop
 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-bus = dbus.SessionBus()
+#bus = dbus.SessionBus()
+
+from os import environ
+bus = dbus.bus.BusConnection(environ["DBUS_SESSION_BUS_ADDRESS"])
+
+color_style = gtk.rc_get_style_by_paths(gtk.settings_get_default() , 'GtkButton', 'osso-logical-colors', gtk.Button)
+active_color = color_style.lookup_color('ActiveTextColor')
+default_color = color_style.lookup_color('DefaultTextColor')
+del color_style
 
 CONFIGDIR="/home/user/.feedingit/"
 
+#DBusConnection *hd_home_plugin_item_get_dbus_connection ( HDHomePluginItem *item, DBusBusType type, DBusError *error);
+#import ctypes
+#libc = ctypes.CDLL('libc.so.6')
+#libc.printf('Hello world!')
+
 class FeedingItHomePlugin(hildondesktop.HomePluginItem):
     def __init__(self):
       try:
@@ -45,13 +56,30 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
         self.set_settings(True)
         self.connect("show-settings", self.show_settings)
         self.feed_list = {}
+        self.total = 0
+        self.autoupdateID=False
         
         vbox = gtk.VBox(False, 0)
         
-        button = gtk.Button("Update")
-        button.connect("clicked", self.update_list)
-        button.show_all()
-        vbox.pack_start(button)        
+        #self.button = gtk.Button()
+        self.button = hildon.Button(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
+        self.button.set_text("FeedingIt","")
+        self.button.set_sensitive(False)
+        self.label1 = self.button.child.child.get_children()[0].get_children()[0]
+        self.label2 = self.button.child.child.get_children()[0].get_children()[1]
+        self.label1.modify_fg(gtk.STATE_INSENSITIVE, default_color)
+        self.label2.modify_fg(gtk.STATE_INSENSITIVE, active_color)
+        icon_theme = gtk.icon_theme_get_default()
+        pixbuf = icon_theme.load_icon("feedingit", 48, gtk.ICON_LOOKUP_USE_BUILTIN )
+        image = gtk.Image()
+        image.set_from_pixbuf(pixbuf)
+        self.button.set_image(image)
+        self.button.set_image_position(gtk.POS_LEFT)
+
+        #button = gtk.Button("Update")
+        self.button.connect("clicked", self.button_clicked)
+        #button.show_all()
+        vbox.pack_start(self.button, expand=False)        
         
         #for feed in ["Slashdot", "Engadget", "Cheez"]:
         #    self.treestore.append([feed, "0"])
@@ -67,12 +95,31 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
         self.add(vbox)
         self.treeview.connect("row-activated", self.row_activated)
         vbox.show_all()
-        #self.setupDbus()
-        gobject.timeout_add_seconds(30*60, self.update_list)
+        self.setupDbus()
+        #gobject.timeout_add_seconds(30*60, self.update_list)
       except:
           import traceback
-          file = open("/home/user/.feedingit/feedingit_widget.log", "w")
+          file = open("/home/user/.feedingit/feedingit_widget.log", "a")
           traceback.print_exc(file=file)
+          file.close()
+
+    def button_clicked(self, *widget):
+        self.button.set_sensitive(False)
+        self.label1.modify_fg(gtk.STATE_NORMAL, default_color)
+        self.label2.modify_fg(gtk.STATE_NORMAL, active_color)
+        self.update_label("Stopping")
+        remote_object = bus.get_object("org.marcoz.feedingit", # Connection name
+                               "/org/marcoz/feedingit/update" # Object's path
+                              )
+        iface = dbus.Interface(remote_object, 'org.marcoz.feedingit')
+        iface.StopUpdate()
+        
+    def update_label(self, title, value=None):
+        self.button.set_title(title)
+        if value != None:
+            self.button.set_value(value)
+        else:
+            self.button.set_value("")
 
     def row_activated(self, treeview, treepath, column):
         (model, iter) = self.treeview.get_selection().get_selected()
@@ -92,6 +139,8 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
             self.load_config()
 
         list = []
+        oldtotal = self.total
+        self.total = 0
         #for key in listOfFeeds["feedingit-order"]:
         for key in self.feed_list.keys():
             try:
@@ -103,6 +152,7 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
                     if readItems[id]==False:
                         countUnread = countUnread + 1
                 list.append([self.feed_list[key], countUnread, key])
+                self.total += countUnread
             except:
                 pass
         list = sorted(list, key=lambda item: item[1], reverse=True)
@@ -110,13 +160,54 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
             treestore.append(item)
         self.treeview.set_model(treestore)
         self.treeview.get_selection().unselect_all()
+        if self.total > oldtotal:
+            self.update_label("%s Unread" %str(self.total), "%s more articles" %str(self.total-oldtotal))
+        else:
+            self.update_label("%s Unread" %str(self.total))
         return True
+
+    def create_selector(self, choices, setting):
+        #self.pickerDialog = hildon.PickerDialog(self.parent)
+        selector = hildon.TouchSelector(text=True)
+        index = 0
+        for item in choices:
+            iter = selector.append_text(str(item))
+            if str(self.autoupdate) == str(item): 
+                selector.set_active(0, index)
+            index += 1
+        selector.connect("changed", self.selection_changed, setting)
+        #self.pickerDialog.set_selector(selector)
+        return selector
+        
+    def selection_changed(self, selector, button, setting):
+        tmp = selector.get_current_text()
+        if tmp == "Disabled":
+            self.autoupdate = 0
+        else:
+            self.autoupdate = tmp
+        #current_selection = selector.get_current_text()
+        #if current_selection:
+        #    self.config[setting] = current_selection
+        #gobject.idle_add(self.updateButton, setting)
+        #self.saveConfig()
+        
+    def create_autoupdate_picker(self):
+            picker = hildon.PickerButton(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
+            selector = self.create_selector(["Disabled", 0.02, 0.5, 1, 2, 4, 12, 24], "autoupdate")
+            picker.set_selector(selector)
+            picker.set_title("Frequency of updates from the widget")
+            picker.set_text("Setup Feed Auto-updates","Update every %s hours" %str(self.autoupdate) )
+            picker.set_name('HildonButton-finger')
+            picker.set_alignment(0,0,1,1)
+            #self.buttons[setting] = picker
+            #vbox.pack_start(picker, expand=False)
+            return picker
         
     def show_settings(self, widget):
         file = open(CONFIGDIR+"feeds.pickle")
         listOfFeeds = pickle.load(file)
         file.close()
-        dialog = gtk.Dialog("Settings", None, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
+        dialog = gtk.Dialog("Choose feeds to display", None, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
 
         self.pannableArea = hildon.PannableArea()
         
@@ -140,12 +231,16 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
         self.pannableArea.add(self.treeview_settings)
         self.pannableArea.show_all()
         dialog.set_default_size(-1, 600)
+        
+        dialog.action_area.pack_start(self.create_autoupdate_picker())
+        
         dialog.show_all()
         response = dialog.run()
-        print response
+
         if response == gtk.RESPONSE_ACCEPT:
             self.feed_list = self.getItems()
         dialog.destroy()
+        self.save_config()
         self.update_list()
         #self.treeview_settings.get_selection().select_all()
         
@@ -158,40 +253,69 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
         return list
         
     def setupDbus(self):
+        bus.add_signal_receiver(self.update_list, dbus_interface="org.marcoz.feedingit",
+                        signal_name="ArticleCountUpdated", path="/org/marcoz/feedingit/update")
+        bus.add_signal_receiver(self.update_started, dbus_interface="org.marcoz.feedingit",
+                        signal_name="UpdateStarted", path="/org/marcoz/feedingit/update")
+        bus.add_signal_receiver(self.update_finished, dbus_interface="org.marcoz.feedingit",
+                        signal_name="UpdateFinished", path="/org/marcoz/feedingit/update")
+
+    def update_started(self, *widget):
+        self.button.set_sensitive(True)
+        self.update_label("Updating...", "Click to stop update")
+
+    def update_finished(self, *widget):
+        self.button.set_sensitive(False)
+        self.update_label("Update done")
         
-        #from dbus.mainloop.glib import DBusGMainLoop
-        #dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-        #import gobject
-        #loop = gobject.MainLoop()
-        #bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
-        #bus = dbus.SessionBus(mainloop=loop)
-        #bus = dbus.Bus.get_system()
-        #bus = dbus.Bus.get_session(True)
-        #bus.set_exit_on_disconnect(False)
-        
-        remote_object = bus.get_object("org.maemo.feedingit", # Connection name
-                               "/org/maemo/feedingit" # Object's path
+    def start_update(self):
+        try:
+            if self.autoupdate >0:
+                import traceback
+                file = open("/home/user/.feedingit/feedingit_widget.log", "a")
+                from time import gmtime, strftime
+                file.write(strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()))
+                file.close()
+                remote_object = bus.get_object("org.marcoz.feedingit", # Connection name
+                              "/org/marcoz/feedingit/update" # Object's path
                               )
-        iface = dbus.Interface(remote_object, 'org.maemo.feedingit')
-        iface.connect_to_signal("ArticleCountUpdated", self.update_list)
+                iface = dbus.Interface(remote_object, 'org.marcoz.feedingit')
+                iface.UpdateAll()
+            return True
+        except:
+            import traceback
+            file = open("/home/user/.feedingit/feedingit_widget.log", "a")
+            traceback.print_exc(file=file)
+            file.close()
 
-        #bus.add_signal_receiver(self.update_list,
-        #                dbus_interface="org.maemo.feedingit",
-        #                signal_name="ArticleCountUpdated",
-        #                path="/org/maemo/feedingit")
-        
     def save_config(self):
+            from os.path import isdir
             if not isdir(CONFIGDIR):
+                from os import mkdir
                 mkdir(CONFIGDIR)
             file = open(CONFIGDIR+"widget", "w")
             pickle.dump(self.feed_list, file )
+            pickle.dump(self.autoupdate, file)
             file.close()
-            
+            self.setup_autoupdate()
+
+    def setup_autoupdate(self):
+        if (float(self.autoupdate) > 0):
+            if (not self.autoupdateID==False):
+                gobject.disconnect(self.autoupdateId)
+            self.autoupdateId = gobject.timeout_add_seconds(int(float(self.autoupdate)*3600), self.start_update)
+        else:
+            if (not self.autoupdateID==False):
+                gobject.disconnect(self.autoupdateId)
+                self.autoupdateID=False
+
     def load_config(self):
             try:
                 file = open(CONFIGDIR+"widget", "r")
                 self.feed_list = pickle.load( file )
+                self.autoupdate = pickle.load( file )
                 file.close()
+                self.setup_autoupdate()
             except:
                 file = open(CONFIGDIR+"feeds.pickle")
                 listOfFeeds = pickle.load(file)
@@ -201,6 +325,7 @@ class FeedingItHomePlugin(hildondesktop.HomePluginItem):
                 for key in listOfFeeds["feedingit-order"]:
                     self.feed_list[key] = listOfFeeds[key]["title"]
                 del listOfFeeds
+                self.autoupdate = 0
 
 
 hd_plugin_type = FeedingItHomePlugin
index 68d73d7..7081c41 100644 (file)
@@ -43,18 +43,8 @@ class ServerObject(dbus.service.Object):
     @dbus.service.method('org.maemo.feedingit')
     def GetStatus(self):
         return self.app.getStatus()
-    
-    @dbus.service.method('org.maemo.feedingit')
-    def Update(self):
-        self.app.automaticUpdate()
-        return "Done"
 
     @dbus.service.method('org.maemo.feedingit')
     def OpenFeed(self, key):
         self.app.buttonFeedClicked(None, self.app, None, key)
-        return "Done"    
-
-    # A signal that will be exported to dbus
-    @dbus.service.signal('org.maemo.feedingit', signature='')
-    def ArticleCountUpdated(self):
-        pass
+        return "Done"
index 8a30f7f..61e910b 100644 (file)
@@ -23,8 +23,7 @@
 # Description : Simple RSS Reader
 # ============================================================================
 
-from os.path import isfile
-from os.path import isdir
+from os.path import isfile, isdir
 from shutil import rmtree
 from os import mkdir, remove
 import pickle
@@ -40,20 +39,20 @@ from urlparse import urlparse
 def getId(string):
     return md5.new(string).hexdigest()
 
-def getProxy():
-    import gconf
-    if gconf.client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
-        port = gconf.client_get_default().get_int('/system/http_proxy/port')
-        http = gconf.client_get_default().get_string('/system/http_proxy/host')
-        proxy = proxy = urllib2.ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
-        return (True, proxy)
-    return (False, None)
+#def getProxy():
+#    import gconf
+#    if gconf.client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
+#        port = gconf.client_get_default().get_int('/system/http_proxy/port')
+#        http = gconf.client_get_default().get_string('/system/http_proxy/host')
+#        proxy = proxy = urllib2.ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
+#        return (True, proxy)
+#    return (False, None)
 
 # Enable proxy support for images and ArchivedArticles
-(proxy_support, proxy) = getProxy()
-if proxy_support:
-    opener = urllib2.build_opener(proxy)
-    urllib2.install_opener(opener)
+#(proxy_support, proxy) = getProxy()
+#if proxy_support:
+#    opener = urllib2.build_opener(proxy)
+#    urllib2.install_opener(opener)
 
 # Entry = {"title":XXX, "content":XXX, "date":XXX, "link":XXX, images = [] }
 
@@ -157,6 +156,14 @@ class Feed:
            tmpIds = []
            for entry in tmp["entries"]:
                (dateTuple, date) = self.extractDate(entry)
+               try:
+                   entry["title"]
+               except:
+                   entry["title"] = "No Title"
+               try:
+                   entry["link"]
+               except:
+                   entry["link"] = ""
                tmpEntry = {"title":entry["title"], "content":self.extractContent(entry),
                             "date":date, "dateTuple":dateTuple, "link":entry["link"], "images":[] }
                id = self.generateUniqueId(tmpEntry)
diff --git a/src/update_feeds.py b/src/update_feeds.py
new file mode 100644 (file)
index 0000000..29f4bb7
--- /dev/null
@@ -0,0 +1,134 @@
+#!/usr/bin/env python2.5
+
+# 
+# Copyright (c) 2007-2008 INdT.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# ============================================================================
+# Name        : update_feeds.py
+# Author      : Yves Marcoz
+# Version     : 0.6.1
+# Description : Simple RSS Reader
+# ============================================================================
+
+from rss import Listing
+from config import Config
+
+import threading
+import os
+import gobject
+
+CONFIGDIR="/home/user/.feedingit/"
+LOCK = CONFIGDIR + "update.lock"
+#DESKTOP_FILE = "/usr/share/applications/hildon-status-menu/feedingit_status.desktop"
+
+from updatedbus import UpdateServerObject, get_lock
+
+class Download(threading.Thread):
+    def __init__(self, listing, config, dbusHandler):
+        threading.Thread.__init__(self)
+        self.running = True
+        self.listing = listing
+        self.config = config
+        self.dbusHandler = dbusHandler
+        self.dbug = open(CONFIGDIR+"dbug.log", "w")
+        self.dbug.flush()
+        
+    def run(self):
+        self.dbug.write("Starting updates")
+        self.dbug.flush()
+        try:
+            self.dbusHandler.UpdateStarted()
+            (use_proxy, proxy) = self.config.getProxy()
+            for key in self.listing.getListOfFeeds():
+                self.dbug.write("updating %s\n" %key)
+                self.dbug.flush()
+                try:
+                    if use_proxy:
+                        from urllib2 import install_opener, build_opener
+                        install_opener(build_opener(proxy))
+                        self.listing.updateFeed(key, self.config.getExpiry(), proxy=proxy, imageCache=self.config.getImageCache() )
+                    else:
+                        self.listing.updateFeed(key, self.config.getExpiry(), imageCache=self.config.getImageCache() )
+                except:
+                    import traceback
+                    file = open("/home/user/.feedingit/feedingit_update.log", "a")
+                    traceback.print_exc(file=file)
+                    file.close()
+                if not self.running:
+                    self.dbug.write("received stopUpdate after %s\n" %key)
+                    self.dbug.flush()
+                    break
+            self.dbusHandler.UpdateFinished()
+            self.dbusHandler.ArticleCountUpdated()
+            self.dbug.write("Dbus ArticleCountUpdated signal sent\n")
+            self.dbug.flush()
+            try:
+                os.remove(LOCK)
+                #os.remove(DESKTOP_FILE)
+            except:
+                pass
+        except:
+            pass
+        self.listing.saveConfig()
+        self.dbug.write("About to main_quit\n")
+        self.dbug.flush()
+        mainloop.quit()
+        file.write("After main_quit\n")
+        self.dbug.flush()
+        self.dbug.close()
+
+class FeedUpdate():
+    def __init__(self):
+        self.listing = Listing(CONFIGDIR)
+        self.config = Config(self, CONFIGDIR+"config.ini")
+        self.dbusHandler = UpdateServerObject(self)
+        self.updateThread = False
+        
+    def automaticUpdate(self):
+        #self.listing.updateFeeds()
+        if self.updateThread == False:
+            self.updateThread = Download(self.listing, self.config, self.dbusHandler)
+            self.updateThread.start()
+        
+    def stopUpdate(self):
+        try:
+            self.updateThread.running = False
+        except:
+            pass
+
+import dbus.mainloop.glib
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+gobject.threads_init()
+mainloop = gobject.MainLoop()
+
+app_lock = get_lock("app_lock")
+
+if app_lock != None:
+    try:
+        feed = FeedUpdate()
+        mainloop.run()
+        del app_lock
+    except:
+        import traceback
+        file = open("/home/user/.feedingit/feedingit_update.log", "a")
+        traceback.print_exc(file=file)
+        file.close()
+else:
+    file = open("/home/user/.feedingit/feedingit_update.log", "a")
+    file.write("Update in progress")
+    file.close()
+    
diff --git a/src/updatedbus.py b/src/updatedbus.py
new file mode 100644 (file)
index 0000000..e712c7e
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/env python2.5
+
+# 
+# Copyright (c) 2007-2008 INdT.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# ============================================================================
+# Name        : FeedingIt.py
+# Author      : Yves Marcoz
+# Version     : 0.6.1
+# Description : Simple RSS Reader
+# ============================================================================
+
+import dbus
+import dbus.service
+
+def get_lock(key):
+    try:
+        bus_name = dbus.service.BusName('org.marcoz.feedingit.lock_%s' %key,bus=dbus.SessionBus(), do_not_queue=True)
+    except:
+        bus_name = None
+    return bus_name
+    
+
+class UpdateServerObject(dbus.service.Object):
+    def __init__(self, app):
+        # Here the service name
+        bus_name = dbus.service.BusName('org.marcoz.feedingit',bus=dbus.SessionBus())
+        # Here the object path
+        dbus.service.Object.__init__(self, bus_name, '/org/marcoz/feedingit/update')
+        self.app = app
+
+    @dbus.service.method('org.marcoz.feedingit')
+    def UpdateAll(self):
+        self.app.automaticUpdate()
+        return "Done"
+    
+    @dbus.service.method('org.marcoz.feedingit')
+    def StopUpdate(self):
+        self.app.stopUpdate()
+        return "Done"
+    
+    # A signal that will be exported to dbus
+    @dbus.service.signal('org.marcoz.feedingit', signature='')
+    def ArticleCountUpdated(self):
+        pass
+
+    # A signal that will be exported to dbus
+    @dbus.service.signal('org.marcoz.feedingit', signature='')
+    def UpdateStarted(self):
+        pass
+    
+    # A signal that will be exported to dbus
+    @dbus.service.signal('org.marcoz.feedingit', signature='')
+    def UpdateFinished(self):
+        pass
\ No newline at end of file