This patch merges all the win32-specific changes that
have been done to gPodder so far and also adds some
generic bugfixes that will benefit other versions of
gPodder, too.
Thanks to Stefan Koegl and David Greenbaum for testing.
Do not install gettext globally, but have a gettext
function in the gpodder module and import it from all
dependent modules.
Remove the --local command line option and instead
automatically detect if the gpodder script is called
from a source folder (determined by the existence of
"src" and "data" in the parent folder and by the fact
that prefix does not start with '/usr').
Clean up setup.py and use metadata from the module.
We want to get rid of gPodderLib in the end, so move
the utility function out of gPodderLib and correct
its uses accordingly. Also add a unittest for it.
Make sure to always decode non-unicode strings in
these functions, so to not get an UnicodeDecodeError
when trying to decode/encode strings to/from unicode.
Thanks to Andy Owen for reporting this bug.
Add doctests for the username/password from URL
function and raise a ValueError when the input
data is invalid (wrong type or format - see below).
Had a look at RFC1738 (Section 3.1) how username
and password are specified in URLs. According to
that RFC, "@", ":" and "/" have to be encoded in
the username and password field.
Add doctests for the find_mount_point() utility method
and make it more robust while finding shortcomings of
the current implementation by unexpected behaviour that
has been checked with the doctest and mock objects.
Note the unittest requirements (minimock + coverage) in
the README file and rm the ".coverage" file on "make clean".
New module "gpodder.unittests" that will run all
unit tests and doctests (currently only gpodder.util)
for gPodder. The tests can easily be run with a
make unittest
in the source tree or with the following command
when gPodder is installed onto the system:
python -m gpodder.unittests
Also added a (currently unused) helper function to
gpodder.util that already has unittests prepared.
I've search a little and it seems that it comes
from podcasts that are on my iPod and that don't
have a released date.
I've just attached my version of util.py. I've
added a try/except, so if the timestamp is not None,
but is incorrect, the exception is catched and None
is returned. It works for me.
This patch finishes off the proper filename support, so
remove the "experimental_file_naming" configuration option.
Also add download resuming based on this new code. The
resuming function currently works like this: All active
and queued downloads will not be deleted when gPodder is
closed, and gPodder will ask the user if she wants to
continue downloading at next startup (if not, the partial
files are deleted).
These two changes are very suspicious of breaking some weird
feeds (for proper filenames) and servers (for resuming).
Report any bugs that you encounter. Enjoy! :)
Improve M3U writing (metadata, Windows-style line
breaks when using the Windows-style pathnames) and
really generate "relative to m3u" filenames instead
of "relative to root" filenames.
Thanks to Ville-Pekka Vainio for reporting and testing.
Allow URL schemes like "Http://" and show better error
messages when adding URLs with unknown schemes.
Thanks to R. Bell for reporting this error on garage.maemo.org.
Remove the preferences UI for bluetooth sending, make
sure Bluetooth support is automatically activated when
the necessary tools are available.
Keep advanced configuration options for Bluetooth.
With the configuration option "enable_streaming" enabled,
gPodder will now allow you to stream podcasts from the
server instead of downloading it locally first.
Streamed episodes will look as if they have been
downloaded and afterwards deleted. "Played" status is now
display on deleted episodes, too for this reason.
Let the Desktop Environment / the default BitTorrent
client handle torrent downloads. We just use the default
handler for .torrent files to "open" a torrent file after
download has completed.
Discussed on the mailing list in the following thread:
https://lists.berlios.de/pipermail/gpodder-devel/2008-November/002256.html
In addition to selecting audio and video players, we
now support "default" as a way of having a good default
that we can pass to a utility function that can later
be made cross-platform more easily.
Also cleaned up some UI issues with the video player,
so the label of the custom command is shown and the
combo box has the correct size.
For text/html content types, try to discover the correct
RSS/Atom feed URL by looking at the <link> meta elements
and getting the feed URL from that. If that fails, or if
there are not <link> meta elements, make sure that the UI
code can display the "This URL is a website" message box
that will allow the user to open a web browser window to
search for the feed URL manually.
Based on a patch by Justin Forest.
I have encountered another piece of code, which hangs the
sync process due to incompatibility with my legacy non-UTF8
locale. So I've added one more function to gpodder.util
which just cleans strings from possible further errors.
Merge patch to fix bug #122 (Day of week Released date not computed correctly)
* src/gpodder/libpodcasts.py: use rfc822.mktime_tz() to convert
timestamps from feedparser's _parse_date() function to seconds from
the epoch (in UTC instead of the local timezone)
* src/gpodder/util.py: fix util.format_date() so that when it reports
'Today', it means the timestamp is from after 00:00 local time
git-svn-id: svn://svn.berlios.de/gpodder/trunk@770 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Don't warn the user when timestamp is None
* src/gpodder/util.py: Don't warn the user when timestamp is None in
gpodder.util.format_date; Thanks to Bernd Schlapsi for reporting this
bug (Closes: http://bugs.gpodder.org/show_bug.cgi?id=148)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@762 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Small bugfixes
* src/gpodder/gui.py: for bluetooth file transfer make sure
episode.sync_filename() doesn't contain any troublesome characters
eg. some episodes include / in the title
* src/gpodder/libpodcasts.py: comment out mimetype logging, it gets
annoying after a while...
* src/gpodder/util.py: remove "path = os.path.dirname(path)" from
get_free_disk_space(path), this prevented the real free disk space
from being reported
git-svn-id: svn://svn.berlios.de/gpodder/trunk@759 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Better file extension detection using feed items' mimetypes
* src/gpodder/gui.py: Use episode.file_type() instead of
util.file_type_by_extension(util.file_extension_from_url(url))
* src/gpodder/libgpodder.py: Use episode.file_type() instead of
util.file_type_by_extension(util.file_extension_from_url(url))
* src/gpodder/libpodcasts.py: Add new column to the channel list
gtk.ListStore for holding the file extension. Add extension()
function to podcastItem which makes use mimetype in the event that
filename_from_url()[1] returns None
* src/gpodder/util.py: file_extension_from_url is renamed to
filename_from_url and returns (filename, extension)
Added extension_from_mimetype(mimetype)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@752 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Merge patch from Justin Forest and Thomas Perl:
- Use SQLite instead of cPickle to store all data, including feed summary
and entries, download and play history.
- Migration assistant to import the old cPickle files in to the SQLite DB
* src/gpodder/cache.py: SQLite-related accomodations
* src/gpodder/console.py: SQLite-related accomodations
* src/gpodder/dbsqlite.py: New file, SQLite interface for gPodder
* src/gpodder/gui.py: Lots of changes to accomodate the new SQLite
DB + new migration assistant code
* src/gpodder/libgpodder.py: Added gPodderLib.migrate_to_sqlite().
HistoryStore and ChannelSettings are marked as DEPRECATED
* src/gpodder/libpodcasts.py: SQLite-related accomodations and new
code for setting/determining episode state
* src/gpodder/sync.py: SQLite-related accomodations
* src/gpodder/trayicon.py: Use episode.was_downloaded() instead
of episode.is_downloaded()
* src/gpodder/util.py: SQLite-related accomodations
git-svn-id: svn://svn.berlios.de/gpodder/trunk@750 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Support tooltips for the episode list; improve tooltip appearance
* src/gpodder/gui.py: Add tooltips to treeAvailable (episode list);
avoid showing tooltips while the context menu of the treeChannels and
treeAvailable is open, so the tooltip doesn't appear over the context
menu; add Sebastian Krause to list of bug reporters
* src/gpodder/util.py: Try to convert some HTML tags to text-only
characters (<br> to newline, <li> to a "*", etc..) so the description
of an episode is easier to read and looks more structured; also,
convert more than two subsequent newlines to maximum two newlines
(Closes: http://bugs.gpodder.org/show_bug.cgi?id=126)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@742 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Improve performance related to pubDate parsing; Download button; update feeds
* src/gpodder/gui.py: Notify user when we are building the list of
channels instead of staying at "updating [last feed]".; Make the "OK"
button of the gPodderEpisodeSelector a "Downlaod" button, because
that's what the button does when clicking it - downloading episodes
* src/gpodder/libpodcasts.py: pubDate is now an Unix timestamp
everywhere and not a string, which has to be parsed quite often; Fix
up and improve the creation of the channel list model
* src/gpodder/sync.py: Customizations for the new pubDate code
* src/gpodder/util.py: Remove updated_parsed_to_rfc2822, because we
don't need it anymore with the new pubDate code
git-svn-id: svn://svn.berlios.de/gpodder/trunk@740 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Make things less verbose and fix a problem with cover art handling
* src/gpodder/gui.py: Fix problem when trying to remove a non-existent
podcast cover art from the cache; make things less verbose
* src/gpodder/*.py: Make things less verbose
git-svn-id: svn://svn.berlios.de/gpodder/trunk@739 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Automatically download channel cover file; improve channel cover handling
* data/gpodder.glade: Simplify and clean-up the podcast editor dialog,
especially with respect to the cover art stuff
* src/gpodder/config.py: Add configuration option
"podcast_list_icon_size" that determines the pixel size of the cover
art displayed in the podcast list
* src/gpodder/gui.py: Add cover cache, register with the cover
downloader service in the main window, handle messages from the cover
downloader (removed and download finished); request covers for
channels when refreshing the channel list; make sure drag'n'drop of
image files to the channel list works directly and sets the
corresponding channel cover; Rework cover download handling and add an
open dialog as suggested by the May 2008 Usability Evaluation
* src/gpodder/libgpodder.py: Remove old, attic image downloading code
from gPodderLib, because it now has its own service class
* src/gpodder/libpodcasts.py: Remove unneeded get_cover_pixbuf helper
function for podcastChannel; improve channels_to_model to take
advantage of the new cover downloader service
* src/gpodder/services.py: Add CoverDownloader service that acts as a
central hub for all downloading and modifying of channel cover art,
including notification of observers (through ObservableService)
* src/gpodder/util.py: Add resize_pixbuf_keep_ratio helper function to
resize a gtk pixbuf while keeping the aspect radio (with optional
caching support through a dictionary parameter)
(Closes: http://bugs.gpodder.org/show_bug.cgi?id=88)
Fri, 13 Jun 2008 20:10:13 +0200 <thp@perli.net>
Fix a bug in the experimental file naming support
* src/gpodder/util.py: Fix bug that stopped the experimental file
naming patch from working; thanks to Shane Donohoe for reporting
git-svn-id: svn://svn.berlios.de/gpodder/trunk@737 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Merge patch to add experimental support for "normal" file naming
* src/gpodder/config.py: New option "experimental_file_naming" that
defaults to False and enables the new (but experimental!) normal file
naming mode in which the downloaded podcast episodes get their name
not from the md5sum of the download URL, but from the basename of the
download URL, which makes filenames more human-readable
* src/gpodder/libpodcasts.py: Change local_filename() in podcastItem
to decide if we use md5sums or the "new" file naming mode for creating
the local file name of an episode
* src/gpodder/sync.py: Change usage of the "encoding" detection in
gpodder.util (from detect_os_encoding() to simply encoding)
* src/gpodder/util.py: Only detect the filename encoding once (at
program start) and then make it accessible via a global "encoding"
variable in the gpodder.util module; add improvements to
file_extension_from_url() to be able to return the complete filename
and to support more creative URL schemes as implemented by podcast
feed authors (this hopefully makes more feeds work in a proper way)
(Closes: http://bugs.gpodder.org/show_bug.cgi?id=57)
Add line to the previous ChangeLog entry (which I forgot initially):
(Closes: http://bugs.gpodder.org/show_bug.cgi?id=124)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@736 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Merge patch from Nick to add support for deleting played files on sync
* data/gpodder.glade: Add check button for "Delete episodes on device
that have been marked played in gPodder"
* src/gpodder/config.py: Add two new config options:
"mp3_player_delete_played" and "mp3_player_max_filename_length"
* src/gpodder/gui.py:
* src/gpodder/libpodcasts.py: Add "is_deleted()" convenience function
for a podcast episode
* src/gpodder/sync.py: Clean-up and simplify parts of the code to make
it better-structured and avoid code duplication; use the configuration
variable for the MAX_FILENAME_LENGTH instead of hard-coding it to 100
* src/gpodder/util.py: Split sanitize_filename() into two functions,
detect_os_encoding() and sanitize_filename() for better code re-use
(Closes: http://bugs.gpodder.org/show_bug.cgi?id=56; code written by
Nick (nikosapi) and initial idea by Shane Donohoe, see the bug page)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@734 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Fix a crasher with ExpatError when trying to parse an invalid itms:// URL
* src/gpodder/gui.py: Give an error message when adding a channel that
doesn't result in a valid URL being returned
* src/gpodder/util.py: Improve handling of itms:// URLs that are not
valid iTunes Podcast links, so they don't crash; thanks to Ralph on
Launchpad for reporting this bug
(Closes: https://bugs.launchpad.net/ubuntu/+source/gpodder/+bug/214113)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@713 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Fix bugs in the calculate_size utility function
* src/gpodder/util.py: Fix problem when accessing files or folders is
not possible in calculate_size(); thanks to Scott Wegner for reporting
this bug on Launchpad
* src/gpodder/gui.py: Add Scott Wegner to list of bug reporters
(Closes: https://bugs.launchpad.net/ubuntu/+source/gpodder/+bug/201276)
git-svn-id: svn://svn.berlios.de/gpodder/trunk@711 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Logging traceback is enabled by default (needs to be disabled on demand)
* src/gpodder/*.py: Remove "traceback=True" from logging calls
* src/gpodder/liblogger.py: Always print a traceback if it's
available; if not, do not print it out; this can be disabled by
passing "traceback=False" to the log() function
* src/gpodder/sync.py: Also add "traceback=False" for optional imports
git-svn-id: svn://svn.berlios.de/gpodder/trunk@682 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Additional fields for the device remove episodes dialog; refactoring
* src/gpodder/gui.py: Add "Podcast" and "Released" columns to the
episode selector; hide all columns in our "delete from device" episode
selector that have all rows set to "None"; make the first text column
of the gPodderEpisodeSelector bigger, so the episode selector is
easier to read when there are many columns
* src/gpodder/libpodcasts.py: Use util.format_date() for
cute_pubdate() in podcastItem
* src/gpodder/sync.py: Document SyncTrack a bit better, add
needed/possible keyword arguments that are used in the UI; default
some values to None in case they are not provided; get "released" date
from iPod's iTunesDB and get podcast name from MP3 player's sync
folder (if this feature has been activated)
* src/gpodder/util.py: Add format_date() function that converts a Unix
timestamp to a good representation for a date (either Today,
Yesterday, a weekday or the locale's appropriate representation); the
code has been re-factored from podcastItem's cute_pubdate() function
in gpodder.libpodcasts and is now used from there
git-svn-id: svn://svn.berlios.de/gpodder/trunk@677 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Makre sure we can re-set the locale after changing it
* src/gpodder/util.py: Make sure we can re-set the locale after
changing it, and if we cannot, only print a warning, but don't throw
the exception outside of the function
git-svn-id: svn://svn.berlios.de/gpodder/trunk@659 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Initial upstream support for the Maemo platform (Nokia Internet Tablets)
* bin/gpodder: Add "--maemo/-m" option to enable running as a Maemo
application (this is only useful on Nokia Internet Tablets or in the
Maemo SDK environment); determine interface type and set the correct
variables on startup (gpodder.interface)
* data/gpodder.glade: Increase the default size of some widgets to
better fit the screens on Maemo (it won't do any harm on the "big"
Desktop screen
* data/icons/26/gpodder.png: Added
* data/icons/40/gpodder.png: Added
* data/maemo/gpodder.desktop: Added
* Makefile: Help2man variable; new "make mtest" target that runs
gPodder in Maemo scratchbox (probably useless for all other things);
update the command descriptions; don't run the "generators" target
from the "install" target; don't run "gen_graphics" from the
"generators" target, but make it depend on the 24-pixel logo, which
itself depends on the 22-pixel logo; this way, all should work out
well when trying to install on systems without ImageMagick installed;
remove *.pyo files on "make clean"
* setup.py: Support for build targets; use "TARGET=maemo" to enable
Maemo-specific installation options and files
* src/gpodder/config.py: Increase the WRITE_TO_DISK_TIMEOUT to 60
seconds, so we don't unnecessarily stress memory cards (on ITs);
modify default path variables on Maemo (/media/mmc2)
* src/gpodder/gui.py: Maemo-specific changes; clean-up the main window
a bit and make message and confirmation dialogs Hildon-compatible
* src/gpodder/__init__.py: Add enums for interface types: CLI, GUI and
MAEMO; remove the "interface_is_gui" variable and replace with
"interface", which is now used to determine where we are running
* src/gpodder/libgpodder.py: Use /media/mmc2/gpodder/ as configuration
folder on Maemo; use Nokia's Media player to playback files on Maemo
* src/gpodder/libpodcasts.py: Icon name changes (Maemo-specific)
* src/gpodder/trayicon.py: Maemo support; swap popup menu on Maemo;
Add support for hildon banners instead of pynotify on Maemo
* src/gpodder/util.py: Icon name changes (Maemo-specific); use new
gpodder.interface variable in idle_add
git-svn-id: svn://svn.berlios.de/gpodder/trunk@654 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Project management updates (authors, contributors and copyright)
* AUTHORS: Removed (was outdated); content now in gui.py (AboutDialog)
* bin/gpodder, data/po/Makefile, doc/dev/copyright_notice,
doc/dev/win32/setup-win32.py, INSTALL, Makefile, README,
setup.py: Updated Copyright and old website URL to include 2008, the
gPodder team and www.gpodder.org
* src/gpodder/*.py: Updated Copyright years
* src/gpodder/gui.py: Add list of contributors from AUTHORS file and
from the content on the website's news page (please mail me if I
forgot to mention you as a contributor, I surely have missed a few);
make the AboutDialog's application name "gPodder" (from gpodder) and
add an URL hook function to the AboutDialog, so the website is opened
in the user's default web browser
git-svn-id: svn://svn.berlios.de/gpodder/trunk@648 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Report errors in parsing/loading an already-added channel in the navigator
* src/gpodder/gui.py: Show the error from feedparser in the channel's
tooltip if there has been an error loading the channel
* src/gpodder/libpodcasts.py: Make sure we can load a default title
when using get_by_url(); save the parse_error variable for each
channel (it defaults to None if there is no error); mark the
description text for the channel navigator in red color if there has
been a parser error and add the parse_error variable to the liststore
model
* src/gpodder/util.py: Strip whitespace before and after the string in
remove_html_tags()
git-svn-id: svn://svn.berlios.de/gpodder/trunk@647 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Add support for Rockbox' AudioScrobbler logfile to update played status
* src/gpodder/config.py: Add "mp3_player_use_scrobbler_log"
configuration option (defaulting to False) which controls if we are
going to try and find a ".scrobbler.log" file that contains
information on which tracks have been played; for this to work, you
also have to enable the "Updated tags after download" option
* src/gpodder/sync.py: Support for finding the .scrobbler.log file and
updating the played status of episodes in the MP3 player sync code
* src/gpodder/util.py: Add "find_mount_point()" function that tries to
determine the mount point on which the given directory (or file) lies
and returns the mount point or "/" if the directory/file resides on
the root filesystem.
This whole patch has been contributed by Nick <nikosapi.org> - thanks!
git-svn-id: svn://svn.berlios.de/gpodder/trunk@646 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Make sure we ignore the updated_parsed of a channel if it's None
* src/gpodder/libpodcasts.py: Only try to convert the "updated_parsed"
field if it's not "None"
* src/gpodder/util.py: Make sure we receive a valid 9-tuple when
converting dates from updated_parsed; if we receive a None value or
some value that isn't "9" in length, return None
Thanks to Chris Arnold <carnold@electrichendrix.com> for reporting
this bug on the gpodder-devel mailing list
git-svn-id: svn://svn.berlios.de/gpodder/trunk@644 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Add "3gp" to the list of video file extensions, so we detect these files
* src/gpodder/util.py: Add the .3gp video file extension to the list
of known video file extensions, so we can detect that these are video
files and act accordingly (in the UI and on sync); thanks to Atte
André Jensen for reporting this bug on the gpodder-devel mailing list
git-svn-id: svn://svn.berlios.de/gpodder/trunk@634 b0d088ad-0a06-0410-aad2-9ed5178a7e87
Performance-improving patch from Nick (nikosapi) to html entity replacement
* src/gpodder/util.py: Merge patch from Nick (nikosapi.org) to really
improve performance of the HTML tag stripper/entity replacement code
by using regular expressions and some more intelligent code for
converting numeric entities to Unicode characters
git-svn-id: svn://svn.berlios.de/gpodder/trunk@618 b0d088ad-0a06-0410-aad2-9ed5178a7e87