gPodder is a fine RSS enclosure downloader ('podcatcher'). However, it recently acquired the 'feature' of phoning home with your subscription list. If you would prefer that it not do this, here is a simple patch that rips all of that out. http://chkno.net/gpodder-privacy.html diff -Naur gpodder-2.9.orig/README gpodder-2.9/README --- gpodder-2.9.orig/README 2010-10-10 12:13:29.000000000 +0000 +++ gpodder-2.9/README 2010-11-11 06:56:51.000000000 +0000 @@ -32,7 +32,6 @@ * python (>= 2.5) with sqlite3 support * python-gtk2 (>= 2.12) * python-feedparser - * python-mygpoclient (>= 1.4; http://thpinfo.com/2010/mygpoclient/) * python-dbus (optional, but highly recommended) If your Python installation does not come with "sqlite3" support, diff -Naur gpodder-2.9.orig/src/gpodder/config.py gpodder-2.9/src/gpodder/config.py --- gpodder-2.9.orig/src/gpodder/config.py 2010-08-29 14:52:02.000000000 +0000 +++ gpodder-2.9/src/gpodder/config.py 2010-11-11 06:57:06.000000000 +0000 @@ -237,24 +237,6 @@ 'youtube_preferred_fmt_id': (int, 18, ('The preferred video format that should be downloaded from YouTube.')), - # gpodder.net general settings - 'mygpo_username': (str, '', - ("The user's gPodder web services username.")), - 'mygpo_password': (str, '', - ("The user's gPodder web services password.")), - 'mygpo_enabled': (bool, False, - ("Synchronize subscriptions with the web service.")), - 'mygpo_server': (str, 'gpodder.net', - ('The hostname of the mygpo server in use.')), - - # gpodder.net device-specific settings - 'mygpo_device_uid': (str, util.get_hostname(), - ("The UID that is assigned to this installation.")), - 'mygpo_device_caption': (str, _('gPodder on %s') % util.get_hostname(), - ("The human-readable name of this installation.")), - 'mygpo_device_type': (str, 'desktop', - ("The type of the device gPodder is running on.")), - # Paned position 'paned_position': ( int, 200, ("The width of the channel list.")), diff -Naur gpodder-2.9.orig/src/gpodder/gui.py gpodder-2.9/src/gpodder/gui.py --- gpodder-2.9.orig/src/gpodder/gui.py 2010-10-10 11:14:58.000000000 +0000 +++ gpodder-2.9/src/gpodder/gui.py 2010-11-11 10:27:29.000000000 +0000 @@ -70,7 +70,6 @@ from gpodder import util from gpodder import opml from gpodder import download -from gpodder import my from gpodder import youtube from gpodder import player from gpodder.liblogger import log @@ -122,7 +121,6 @@ from gpodder.gtkui.maemo.shownotes import gPodderShownotes from gpodder.gtkui.maemo.episodeselector import gPodderEpisodeSelector from gpodder.gtkui.maemo.podcastdirectory import gPodderPodcastDirectory - from gpodder.gtkui.maemo.mygpodder import MygPodderSettings from gpodder.gtkui.interface.progress import ProgressIndicator have_trayicon = False elif gpodder.ui.fremantle: @@ -466,9 +464,6 @@ if gpodder.ui.desktop: self.update_item_device() - # Set up the first instance of MygPoClient - self.mygpo_client = my.MygPoClient(self.config) - # Now, update the feed cache, when everything's in place if not gpodder.ui.fremantle: self.btnUpdateFeeds.show() @@ -565,9 +560,6 @@ self.main_window.set_title(_('gPodder')) hildon.hildon_gtk_window_take_screenshot(self.main_window, True) - # Do the initial sync with the web service - util.idle_add(self.mygpo_client.flush, True) - # First-time users should be asked if they want to see the OPML if not self.channels and not gpodder.ui.fremantle: util.idle_add(self.on_itemUpdate_activate) @@ -644,120 +636,6 @@ self.update_episode_list_icons([episode.url]) self.update_podcast_list_model([episode.channel.url]) - # Submit this action to the webservice - self.mygpo_client.on_playback_full(episode, \ - start, end, total) - - def on_add_remove_podcasts_mygpo(self): - actions = self.mygpo_client.get_received_actions() - if not actions: - return False - - existing_urls = [c.url for c in self.channels] - - # Columns for the episode selector window - just one... - columns = ( - ('description', None, None, _('Action')), - ) - - # A list of actions that have to be chosen from - changes = [] - - # Actions that are ignored (already carried out) - ignored = [] - - for action in actions: - if action.is_add and action.url not in existing_urls: - changes.append(my.Change(action)) - elif action.is_remove and action.url in existing_urls: - podcast_object = None - for podcast in self.channels: - if podcast.url == action.url: - podcast_object = podcast - break - changes.append(my.Change(action, podcast_object)) - else: - log('Ignoring action: %s', action, sender=self) - ignored.append(action) - - # Confirm all ignored changes - self.mygpo_client.confirm_received_actions(ignored) - - def execute_podcast_actions(selected): - add_list = [c.action.url for c in selected if c.action.is_add] - remove_list = [c.podcast for c in selected if c.action.is_remove] - - # Apply the accepted changes locally - self.add_podcast_list(add_list) - self.remove_podcast_list(remove_list, confirm=False) - - # All selected items are now confirmed - self.mygpo_client.confirm_received_actions(c.action for c in selected) - - # Revert the changes on the server - rejected = [c.action for c in changes if c not in selected] - self.mygpo_client.reject_received_actions(rejected) - - def ask(): - # We're abusing the Episode Selector again ;) -- thp - gPodderEpisodeSelector(self.main_window, \ - title=_('Confirm changes from gpodder.net'), \ - instructions=_('Select the actions you want to carry out.'), \ - episodes=changes, \ - columns=columns, \ - size_attribute=None, \ - stock_ok_button=gtk.STOCK_APPLY, \ - callback=execute_podcast_actions, \ - _config=self.config) - - # There are some actions that need the user's attention - if changes: - util.idle_add(ask) - return True - - # We have no remaining actions - no selection happens - return False - - def rewrite_urls_mygpo(self): - # Check if we have to rewrite URLs since the last add - rewritten_urls = self.mygpo_client.get_rewritten_urls() - - for rewritten_url in rewritten_urls: - if not rewritten_url.new_url: - continue - - for channel in self.channels: - if channel.url == rewritten_url.old_url: - log('Updating URL of %s to %s', channel, \ - rewritten_url.new_url, sender=self) - channel.url = rewritten_url.new_url - channel.save() - self.channel_list_changed = True - util.idle_add(self.update_episode_list_model) - break - - def on_send_full_subscriptions(self): - # Send the full subscription list to the gpodder.net client - # (this will overwrite the subscription list on the server) - indicator = ProgressIndicator(_('Uploading subscriptions'), \ - _('Your subscriptions are being uploaded to the server.'), \ - False, self.get_dialog_parent()) - - try: - self.mygpo_client.set_subscriptions([c.url for c in self.channels]) - util.idle_add(self.show_message, _('List uploaded successfully.')) - except Exception, e: - def show_error(e): - message = str(e) - if not message: - message = e.__class__.__name__ - self.show_message(message, \ - _('Error while uploading'), \ - important=True) - util.idle_add(show_error, e) - - util.idle_add(indicator.on_finished) - def on_podcast_selected(self, treeview, path, column): # for Maemo 5's UI model = treeview.get_model() @@ -2172,7 +2050,6 @@ (file_type == 'video' and not self.config.video_played_dbus): # Mark episode as played in the database episode.mark(is_played=True) - self.mygpo_client.on_playback([episode]) filename = episode.local_filename(create=False) if filename is None or not os.path.exists(filename): @@ -2286,9 +2163,6 @@ # Persist episode status changes to the database self.db.commit() - # Flush updated episode status - self.mygpo_client.flush() - def playback_episodes(self, episodes): # We need to create a list, because we run through it more than once episodes = list(PodcastEpisode.sort_by_pubdate(e for e in episodes if \ @@ -2592,14 +2466,8 @@ error_messages.get(url, _('Unknown')))) for url in failed) self.show_message(message, title, important=True) - # Upload subscription changes to gpodder.net - self.mygpo_client.on_subscribe(worked) - # If at least one podcast has been added, save and update all if self.channel_list_changed: - # Fix URLs if mygpo has rewritten them - self.rewrite_urls_mygpo() - self.save_channels_opml() # If only one podcast was added, select it after the update @@ -2698,64 +2566,12 @@ return None - def process_received_episode_actions(self, updated_urls): - """Process/merge episode actions from gpodder.net - - This function will merge all changes received from - the server to the local database and update the - status of the affected episodes as necessary. - """ - indicator = ProgressIndicator(_('Merging episode actions'), \ - _('Episode actions from gpodder.net are merged.'), \ - False, self.get_dialog_parent()) - - for idx, action in enumerate(self.mygpo_client.get_episode_actions(updated_urls)): - if action.action == 'play': - episode = self.find_episode(action.podcast_url, \ - action.episode_url) - - if episode is not None: - log('Play action for %s', episode.url, sender=self) - episode.mark(is_played=True) - - if action.timestamp > episode.current_position_updated and \ - action.position is not None: - log('Updating position for %s', episode.url, sender=self) - episode.current_position = action.position - episode.current_position_updated = action.timestamp - - if action.total: - log('Updating total time for %s', episode.url, sender=self) - episode.total_time = action.total - - episode.save() - elif action.action == 'delete': - episode = self.find_episode(action.podcast_url, \ - action.episode_url) - - if episode is not None: - if not episode.was_downloaded(and_exists=True): - # Set the episode to a "deleted" state - log('Marking as deleted: %s', episode.url, sender=self) - episode.delete_from_disk() - episode.save() - - indicator.on_message(N_('%d action processed', '%d actions processed', idx) % idx) - gtk.main_iteration(False) - - indicator.on_finished() - self.db.commit() - - def update_feed_cache_finish_callback(self, updated_urls=None, select_url_afterwards=None): self.db.commit() self.updating_feed_cache = False self.channels = PodcastChannel.load_from_db(self.db, self.config.download_dir) - # Process received episode actions for all updated URLs - self.process_received_episode_actions(updated_urls) - self.channel_list_changed = True self.update_podcast_list_model(select_url=select_url_afterwards) @@ -2941,9 +2757,6 @@ self.update_podcast_list_model(select_url=select_url_afterwards) return - # Fix URLs if mygpo has rewritten them - self.rewrite_urls_mygpo() - self.updating_feed_cache = True if channels is None: @@ -3043,7 +2856,7 @@ """ if self.channels: if self.save_channels_opml(): - pass # FIXME: Add mygpo synchronization here + pass else: self.show_message(_('Please check your permissions and free disk space.'), _('Error saving podcast list'), important=True) @@ -3146,10 +2959,6 @@ self.episode_shownotes_window.episode.url == episode.url: util.idle_add(self.episode_shownotes_window._download_status_changed, None) - # Notify the web service about the status update + upload - self.mygpo_client.on_delete(episodes_status_update) - self.mygpo_client.flush() - util.idle_add(finish_deletion, episode_urls, channel_urls) threading.Thread(target=thread_proc).start() @@ -3258,18 +3067,12 @@ self.update_feed_cache(channels=[self.active_channel]) def on_itemUpdate_activate(self, widget=None): - # Check if we have outstanding subscribe/unsubscribe actions - if self.on_add_remove_podcasts_mygpo(): - log('Update cancelled (received server changes)', sender=self) - return - if self.channels: self.update_feed_cache() else: gPodderWelcome(self.gPodder, center_on_widget=self.gPodder, - show_example_podcasts_callback=self.on_itemImportChannels_activate, - setup_my_gpodder_callback=self.on_download_subscriptions_from_mygpo) + show_example_podcasts_callback=self.on_itemImportChannels_activate) def download_episode_list_paused(self, episodes): self.download_episode_list(episodes, True) @@ -3303,7 +3106,6 @@ if add_paused: task.status = task.PAUSED else: - self.mygpo_client.on_download([task.episode]) self.download_queue_manager.add_task(task, force_start) self.download_status_model.register_task(task) @@ -3312,9 +3114,6 @@ if enable_update: self.enable_download_list_update() - # Flush updated episode status - self.mygpo_client.flush() - def cancel_task_list(self, tasks): if not tasks: return @@ -3484,9 +3283,7 @@ _config=self.config, \ callback_finished=self.properties_closed, \ user_apps_reader=self.user_apps_reader, \ - parent_window=self.main_window, \ - mygpo_client=self.mygpo_client, \ - on_send_full_subscriptions=self.on_send_full_subscriptions) + parent_window=self.main_window) # Initial message to relayout window (in case it's opened in portrait mode self.preferences_dialog.on_window_orientation_changed(self._last_orientation) @@ -3494,43 +3291,6 @@ def on_itemDependencies_activate(self, widget): gPodderDependencyManager(self.gPodder) - def on_goto_mygpo(self, widget): - self.mygpo_client.open_website() - - def on_download_subscriptions_from_mygpo(self, action=None): - title = _('Login to gpodder.net') - message = _('Please login to download your subscriptions.') - success, (username, password) = self.show_login_dialog(title, message, \ - self.config.mygpo_username, self.config.mygpo_password) - if not success: - return - - self.config.mygpo_username = username - self.config.mygpo_password = password - - dir = gPodderPodcastDirectory(self.gPodder, _config=self.config, \ - custom_title=_('Subscriptions on gpodder.net'), \ - add_urls_callback=self.add_podcast_list, \ - hide_url_entry=True) - - # TODO: Refactor this into "gpodder.my" or mygpoclient, so that - # we do not have to hardcode the URL here - OPML_URL = 'http://gpodder.net/subscriptions/%s.opml' % self.config.mygpo_username - url = util.url_add_authentication(OPML_URL, \ - self.config.mygpo_username, \ - self.config.mygpo_password) - dir.download_opml_file(url) - - def on_mygpo_settings_activate(self, action=None): - # This dialog is only used for Maemo 4 - if not gpodder.ui.diablo: - return - - settings = MygPodderSettings(self.main_window, \ - config=self.config, \ - mygpo_client=self.mygpo_client, \ - on_send_full_subscriptions=self.on_send_full_subscriptions) - def on_itemAddChannel_activate(self, widget=None): gPodderAddPodcast(self.gPodder, \ add_urls_callback=self.add_podcast_list) @@ -3585,9 +3345,6 @@ progress = ProgressIndicator(title, info, parent=self.get_dialog_parent()) def finish_deletion(select_url): - # Upload subscription list changes to the web service - self.mygpo_client.on_unsubscribe([c.url for c in channels]) - # Re-load the channels and select the desired new channel self.update_feed_cache(force_update=False, select_url_afterwards=select_url) progress.on_finished() @@ -3715,7 +3472,6 @@ self.config.opml_url, \ self.add_podcast_list, \ self.on_itemAddChannel_activate, \ - self.on_download_subscriptions_from_mygpo, \ self.show_text_edit_dialog) else: dir = gPodderPodcastDirectory(self.main_window, _config=self.config, \ @@ -3938,9 +3694,6 @@ log('Auto update timer fired.', sender=self) self.update_feed_cache(force_update=True) - # Ask web service for sub changes (if enabled) - self.mygpo_client.flush() - return True def on_treeDownloads_row_activated(self, widget, *args): @@ -4152,8 +3905,6 @@ elif gpodder.ui.fremantle: config.on_quit_ask = False - config.mygpo_device_type = util.detect_device_type() - gp = gPodder(bus_name, config) # Handle options diff -Naur gpodder-2.9.orig/src/gpodder/__init__.py gpodder-2.9/src/gpodder/__init__.py --- gpodder-2.9.orig/src/gpodder/__init__.py 2010-10-10 12:13:41.000000000 +0000 +++ gpodder-2.9/src/gpodder/__init__.py 2010-11-11 06:57:06.000000000 +0000 @@ -41,16 +41,6 @@ sys.exit(1) del feedparser -try: - import mygpoclient -except ImportError: - print """ - Error: Module "mygpoclient" not found. Please install "python-mygpoclient" - or download it from http://thpinfo.com/2010/mygpoclient/ -""" - sys.exit(1) -del mygpoclient - # The User-Agent string for downloads user_agent = 'gPodder/%s (+%s)' % (__version__, __url__) diff -Naur gpodder-2.9.orig/src/gpodder/my.py gpodder-2.9/src/gpodder/my.py --- gpodder-2.9.orig/src/gpodder/my.py 2010-08-05 13:30:17.000000000 +0000 +++ gpodder-2.9/src/gpodder/my.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,544 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# gPodder - A media aggregator and podcast client -# Copyright (c) 2005-2010 Thomas Perl and the gPodder Team -# -# gPodder is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# gPodder is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - - -# -# my.py -- mygpo Client Abstraction for gPodder -# Thomas Perl ; 2010-01-19 -# - -import gpodder -_ = gpodder.gettext - -import atexit -import datetime -import os -import sys -import threading -import time - -from gpodder.liblogger import log - -from gpodder import util -from gpodder import minidb - -# Append gPodder's user agent to mygpoclient's user agent -import mygpoclient -mygpoclient.user_agent += ' ' + gpodder.user_agent - -MYGPOCLIENT_REQUIRED = '1.4' - -if not hasattr(mygpoclient, 'require_version') or \ - not mygpoclient.require_version(MYGPOCLIENT_REQUIRED): - print >>sys.stderr, """ - Please upgrade your mygpoclient library. - See http://thpinfo.com/2010/mygpoclient/ - - Required version: %s - Installed version: %s - """ % (MYGPOCLIENT_REQUIRED, mygpoclient.__version__) - sys.exit(1) - -from mygpoclient import api - -from mygpoclient import util as mygpoutil - - -# Database model classes -class SinceValue(object): - __slots__ = {'host': str, 'device_id': str, 'category': int, 'since': int} - - # Possible values for the "category" field - PODCASTS, EPISODES = range(2) - - def __init__(self, host, device_id, category, since=0): - self.host = host - self.device_id = device_id - self.category = category - self.since = since - -class SubscribeAction(object): - __slots__ = {'action_type': int, 'url': str} - - # Possible values for the "action_type" field - ADD, REMOVE = range(2) - - def __init__(self, action_type, url): - self.action_type = action_type - self.url = url - - @property - def is_add(self): - return self.action_type == self.ADD - - @property - def is_remove(self): - return self.action_type == self.REMOVE - - @classmethod - def add(cls, url): - return cls(cls.ADD, url) - - @classmethod - def remove(cls, url): - return cls(cls.REMOVE, url) - - @classmethod - def undo(cls, action): - if action.is_add: - return cls(cls.REMOVE, action.url) - elif action.is_remove: - return cls(cls.ADD, action.url) - - raise ValueError('Cannot undo action: %r' % action) - -# New entity name for "received" actions -class ReceivedSubscribeAction(SubscribeAction): pass - -class UpdateDeviceAction(object): - __slots__ = {'device_id': str, 'caption': str, 'device_type': str} - - def __init__(self, device_id, caption, device_type): - self.device_id = device_id - self.caption = caption - self.device_type = device_type - -class EpisodeAction(object): - __slots__ = {'podcast_url': str, 'episode_url': str, 'device_id': str, - 'action': str, 'timestamp': int, - 'started': int, 'position': int, 'total': int} - - def __init__(self, podcast_url, episode_url, device_id, \ - action, timestamp, started, position, total): - self.podcast_url = podcast_url - self.episode_url = episode_url - self.device_id = device_id - self.action = action - self.timestamp = timestamp - self.started = started - self.position = position - self.total = total - -# New entity name for "received" actions -class ReceivedEpisodeAction(EpisodeAction): pass - -class RewrittenUrl(object): - __slots__ = {'old_url': str, 'new_url': str} - - def __init__(self, old_url, new_url): - self.old_url = old_url - self.new_url = new_url -# End Database model classes - - - -# Helper class for displaying changes in the UI -class Change(object): - def __init__(self, action, podcast=None): - self.action = action - self.podcast = podcast - - @property - def description(self): - if self.action.is_add: - return _('Add %s') % self.action.url - else: - return _('Remove %s') % self.podcast.title - - -class MygPoClient(object): - STORE_FILE = 'mygpo.queue.sqlite' - FLUSH_TIMEOUT = 60 - FLUSH_RETRIES = 3 - - def __init__(self, config): - self._store = minidb.Store(os.path.join(gpodder.home, self.STORE_FILE)) - - self._config = config - self._client = None - - # Initialize the _client attribute and register with config - self.on_config_changed() - assert self._client is not None - - self._config.add_observer(self.on_config_changed) - - self._worker_thread = None - atexit.register(self._at_exit) - - def create_device(self): - """Uploads the device changes to the server - - This should be called when device settings change - or when the mygpo client functionality is enabled. - """ - # Remove all previous device update actions - self._store.remove(self._store.load(UpdateDeviceAction)) - - # Insert our new update action - action = UpdateDeviceAction(self.device_id, \ - self._config.mygpo_device_caption, \ - self._config.mygpo_device_type) - self._store.save(action) - - def get_rewritten_urls(self): - """Returns a list of rewritten URLs for uploads - - This should be called regularly. Every object returned - should be merged into the database, and the old_url - should be updated to new_url in every podcdast. - """ - rewritten_urls = self._store.load(RewrittenUrl) - self._store.remove(rewritten_urls) - return rewritten_urls - - def get_episode_actions(self, updated_urls): - for podcast_url in updated_urls: - for action in self._store.load(ReceivedEpisodeAction, \ - podcast_url=podcast_url): - yield action - - # Remove all episode actions belonging to this URL - self._store.delete(ReceivedEpisodeAction, \ - podcast_url=podcast_url) - self._store.commit() - - def get_received_actions(self): - """Returns a list of ReceivedSubscribeAction objects - - The list might be empty. All these actions have to - be processed. The user should confirm which of these - actions should be taken, the reest should be rejected. - - Use confirm_received_actions and reject_received_actions - to return and finalize the actions received by this - method in order to not receive duplicate actions. - """ - return self._store.load(ReceivedSubscribeAction) - - def confirm_received_actions(self, actions): - """Confirm that a list of actions has been processed - - The UI should call this with a list of actions that - have been accepted by the user and processed by the - podcast backend. - """ - # Simply remove the received actions from the queue - self._store.remove(actions) - - def reject_received_actions(self, actions): - """Reject (undo) a list of ReceivedSubscribeAction objects - - The UI should call this with a list of actions that - have been rejected by the user. A reversed set of - actions will be uploaded to the server so that the - state on the server matches the state on the client. - """ - # Create "undo" actions for received subscriptions - self._store.save(SubscribeAction.undo(a) for a in actions) - self.flush() - - # After we've handled the reverse-actions, clean up - self._store.remove(actions) - - @property - def host(self): - return self._config.mygpo_server - - @property - def device_id(self): - return self._config.mygpo_device_uid - - def can_access_webservice(self): - return self._config.mygpo_enabled and self._config.mygpo_device_uid - - def set_subscriptions(self, urls): - if self.can_access_webservice(): - log('Uploading (overwriting) subscriptions...') - self._client.put_subscriptions(self.device_id, urls) - log('Subscription upload done.') - else: - raise Exception('Webservice access not enabled') - - def _convert_played_episode(self, episode, start, end, total): - return EpisodeAction(episode.channel.url, \ - episode.url, self.device_id, 'play', \ - int(time.time()), start, end, total) - - def _convert_episode(self, episode, action): - return EpisodeAction(episode.channel.url, \ - episode.url, self.device_id, action, \ - int(time.time()), None, None, None) - - def on_delete(self, episodes): - log('Storing %d episode delete actions', len(episodes), sender=self) - self._store.save(self._convert_episode(e, 'delete') for e in episodes) - - def on_download(self, episodes): - log('Storing %d episode download actions', len(episodes), sender=self) - self._store.save(self._convert_episode(e, 'download') for e in episodes) - - def on_playback_full(self, episode, start, end, total): - log('Storing full episode playback action', sender=self) - self._store.save(self._convert_played_episode(episode, start, end, total)) - - def on_playback(self, episodes): - log('Storing %d episode playback actions', len(episodes), sender=self) - self._store.save(self._convert_episode(e, 'play') for e in episodes) - - def on_subscribe(self, urls): - # Cancel previously-inserted "remove" actions - self._store.remove(SubscribeAction.remove(url) for url in urls) - - # Insert new "add" actions - self._store.save(SubscribeAction.add(url) for url in urls) - - self.flush() - - def on_unsubscribe(self, urls): - # Cancel previously-inserted "add" actions - self._store.remove(SubscribeAction.add(url) for url in urls) - - # Insert new "remove" actions - self._store.save(SubscribeAction.remove(url) for url in urls) - - self.flush() - - def _at_exit(self): - self._worker_proc(forced=True) - self._store.commit() - self._store.close() - - def _worker_proc(self, forced=False): - if not forced: - # Store the current contents of the queue database - self._store.commit() - - log('Worker thread waiting for timeout', sender=self) - time.sleep(self.FLUSH_TIMEOUT) - - # Only work when enabled, UID set and allowed to work - if self.can_access_webservice() and \ - (self._worker_thread is not None or forced): - self._worker_thread = None - - log('Worker thread starting to work...', sender=self) - for retry in range(self.FLUSH_RETRIES): - must_retry = False - - if retry: - log('Retrying flush queue...', sender=self) - - # Update the device first, so it can be created if new - for action in self._store.load(UpdateDeviceAction): - if self.update_device(action): - self._store.remove(action) - else: - must_retry = True - - # Upload podcast subscription actions - actions = self._store.load(SubscribeAction) - if self.synchronize_subscriptions(actions): - self._store.remove(actions) - else: - must_retry = True - - # Upload episode actions - actions = self._store.load(EpisodeAction) - if self.synchronize_episodes(actions): - self._store.remove(actions) - else: - must_retry = True - - if not must_retry: - # No more pending actions. Ready to quit. - break - - log('Worker thread finished.', sender=self) - else: - log('Worker thread may not execute (disabled).', sender=self) - - # Store the current contents of the queue database - self._store.commit() - - def flush(self, now=False): - if not self.can_access_webservice(): - log('Flush requested, but sync disabled.', sender=self) - return - - if self._worker_thread is None or now: - if now: - log('Flushing NOW.', sender=self) - else: - log('Flush requested.', sender=self) - self._worker_thread = threading.Thread(target=self._worker_proc, args=[now]) - self._worker_thread.setDaemon(True) - self._worker_thread.start() - else: - log('Flush requested, already waiting.', sender=self) - - def on_config_changed(self, name=None, old_value=None, new_value=None): - if name in ('mygpo_username', 'mygpo_password', 'mygpo_server') \ - or self._client is None: - self._client = api.MygPodderClient(self._config.mygpo_username, - self._config.mygpo_password, self._config.mygpo_server) - log('Reloading settings.', sender=self) - elif name.startswith('mygpo_device_'): - # Update or create the device - self.create_device() - - def synchronize_episodes(self, actions): - log('Starting episode status sync.', sender=self) - - def convert_to_api(action): - dt = datetime.datetime.fromtimestamp(action.timestamp) - since = mygpoutil.datetime_to_iso8601(dt) - return api.EpisodeAction(action.podcast_url, \ - action.episode_url, action.action, \ - action.device_id, since, \ - action.started, action.position, action.total) - - def convert_from_api(action): - dt = mygpoutil.iso8601_to_datetime(action.timestamp) - since = int(dt.strftime('%s')) - return ReceivedEpisodeAction(action.podcast, \ - action.episode, action.device, \ - action.action, since, \ - action.started, action.position, action.total) - - try: - # Load the "since" value from the database - since_o = self._store.get(SinceValue, host=self.host, \ - device_id=self.device_id, \ - category=SinceValue.EPISODES) - - # Use a default since object for the first-time case - if since_o is None: - since_o = SinceValue(self.host, self.device_id, SinceValue.EPISODES) - - # Step 1: Download Episode actions - try: - changes = self._client.download_episode_actions(since_o.since) - - received_actions = [convert_from_api(a) for a in changes.actions] - log('Received %d episode actions', len(received_actions), \ - sender=self) - self._store.save(received_actions) - - # Save the "since" value for later use - self._store.update(since_o, since=changes.since) - except Exception, e: - log('Exception while polling for episodes.', sender=self, traceback=True) - - # Step 2: Upload Episode actions - - # Convert actions to the mygpoclient format for uploading - episode_actions = [convert_to_api(a) for a in actions] - - # Upload the episode actions - self._client.upload_episode_actions(episode_actions) - - # Actions have been uploaded to the server - remove them - self._store.remove(actions) - log('Episode actions have been uploaded to the server.', sender=self) - return True - except Exception, e: - log('Cannot upload episode actions: %s', str(e), sender=self, traceback=True) - return False - - def synchronize_subscriptions(self, actions): - log('Starting subscription sync.', sender=self) - try: - # Load the "since" value from the database - since_o = self._store.get(SinceValue, host=self.host, \ - device_id=self.device_id, \ - category=SinceValue.PODCASTS) - - # Use a default since object for the first-time case - if since_o is None: - since_o = SinceValue(self.host, self.device_id, SinceValue.PODCASTS) - - # Step 1: Pull updates from the server and notify the frontend - result = self._client.pull_subscriptions(self.device_id, since_o.since) - - # Update the "since" value in the database - self._store.update(since_o, since=result.since) - - # Store received actions for later retrieval (and in case we - # have outdated actions in the database, simply remove them) - for url in result.add: - log('Received add action: %s', url, sender=self) - self._store.remove(ReceivedSubscribeAction.remove(url)) - self._store.remove(ReceivedSubscribeAction.add(url)) - self._store.save(ReceivedSubscribeAction.add(url)) - for url in result.remove: - log('Received remove action: %s', url, sender=self) - self._store.remove(ReceivedSubscribeAction.add(url)) - self._store.remove(ReceivedSubscribeAction.remove(url)) - self._store.save(ReceivedSubscribeAction.remove(url)) - - # Step 2: Push updates to the server and rewrite URLs (if any) - actions = self._store.load(SubscribeAction) - - add = [a.url for a in actions if a.is_add] - remove = [a.url for a in actions if a.is_remove] - - if add or remove: - log('Uploading: +%d / -%d', len(add), len(remove), sender=self) - # Only do a push request if something has changed - result = self._client.update_subscriptions(self.device_id, add, remove) - - # Update the "since" value in the database - self._store.update(since_o, since=result.since) - - # Store URL rewrites for later retrieval by GUI - for old_url, new_url in result.update_urls: - if new_url: - log('Rewritten URL: %s', new_url, sender=self) - self._store.save(RewrittenUrl(old_url, new_url)) - - # Actions have been uploaded to the server - remove them - self._store.remove(actions) - log('All actions have been uploaded to the server.', sender=self) - return True - except Exception, e: - log('Cannot upload subscriptions: %s', str(e), sender=self, traceback=True) - return False - - def update_device(self, action): - try: - log('Uploading device settings...', sender=self) - self._client.update_device_settings(action.device_id, \ - action.caption, action.device_type) - log('Device settings uploaded.', sender=self) - return True - except Exception, e: - log('Cannot update device %s: %s', self.device_id, str(e), sender=self, traceback=True) - return False - - def get_devices(self): - result = [] - for d in self._client.get_devices(): - result.append((d.device_id, d.caption, d.type)) - return result - - def open_website(self): - util.open_website('http://' + self._config.mygpo_server) - diff -Naur gpodder-2.9.orig/src/gpodder/util.py gpodder-2.9/src/gpodder/util.py --- gpodder-2.9.orig/src/gpodder/util.py 2010-10-10 11:55:50.000000000 +0000 +++ gpodder-2.9/src/gpodder/util.py 2010-11-11 07:03:18.000000000 +0000 @@ -1493,24 +1493,6 @@ # Fallback - but can this give us "localhost"? return socket.gethostname() -def detect_device_type(): - """Device type detection for gpodder.net - - This function tries to detect on which - kind of device gPodder is running on. - - Possible return values: - desktop, laptop, mobile, server, other - """ - if gpodder.ui.maemo: - return 'mobile' - elif glob.glob('/proc/acpi/battery/*'): - # Linux: If we have a battery, assume Laptop - return 'laptop' - - return 'desktop' - - def write_m3u_playlist(m3u_filename, episodes, extm3u=True): """Create an M3U playlist from a episode list diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/desktop/podcastdirectory.py gpodder-2.9/src/gpodder/gtkui/desktop/podcastdirectory.py --- gpodder-2.9.orig/src/gpodder/gtkui/desktop/podcastdirectory.py 2010-08-29 14:52:03.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/desktop/podcastdirectory.py 2010-11-11 07:13:54.000000000 +0000 @@ -116,8 +116,6 @@ self.notification(_('There are no YouTube channels that would match this query.'), _('No channels found')) else: url = self.entryURL.get_text() - if '://' not in url: - url = 'http://gpodder.net/search.opml?q=' + urllib.quote(url) model = OpmlListModel(opml.Importer(url)) if len(model) == 0: self.notification(_('The specified URL does not provide any valid OPML podcast items.'), _('No feeds found')) diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/desktop/preferences.py gpodder-2.9/src/gpodder/gtkui/desktop/preferences.py --- gpodder-2.9.orig/src/gpodder/gtkui/desktop/preferences.py 2010-09-26 22:26:26.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/desktop/preferences.py 2010-11-11 06:57:06.000000000 +0000 @@ -194,24 +194,7 @@ self._config.connect_gtk_togglebutton('only_sync_not_played', self.checkbutton_only_sync_not_played) - # Initialize the UI state with configuration settings - self.checkbutton_enable.set_active(self._config.mygpo_enabled) - self.entry_username.set_text(self._config.mygpo_username) - self.entry_password.set_text(self._config.mygpo_password) - self.entry_caption.set_text(self._config.mygpo_device_caption) - - # Disable mygpo sync while the dialog is open - self._enable_mygpo = self._config.mygpo_enabled - self._config.mygpo_enabled = False - def on_dialog_destroy(self, widget): - # Re-enable mygpo sync if the user has selected it - self._config.mygpo_enabled = self._enable_mygpo - # Make sure the device is successfully created/updated - self.mygpo_client.create_device() - # Flush settings for mygpo client now - self.mygpo_client.flush(now=True) - if self.callback_finished: self.callback_finished() @@ -329,27 +312,3 @@ self._config.episode_old_age = value self.checkbutton_expiration_unplayed.set_sensitive(value > 0) - - def on_enabled_toggled(self, widget): - # Only update indirectly (see on_dialog_destroy) - self._enable_mygpo = widget.get_active() - - def on_username_changed(self, widget): - self._config.mygpo_username = widget.get_text() - - def on_password_changed(self, widget): - self._config.mygpo_password = widget.get_text() - - def on_device_caption_changed(self, widget): - self._config.mygpo_device_caption = widget.get_text() - - def on_button_overwrite_clicked(self, button): - title = _('Replace subscription list on server') - message = _('Remote podcasts that have not been added locally will be removed on the server. Continue?') - if self.show_confirmation(message, title): - def thread_proc(): - self._config.mygpo_enabled = True - self.on_send_full_subscriptions() - self._config.mygpo_enabled = False - threading.Thread(target=thread_proc).start() - diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/frmntl/hints.py gpodder-2.9/src/gpodder/gtkui/frmntl/hints.py --- gpodder-2.9.orig/src/gpodder/gtkui/frmntl/hints.py 2010-10-05 10:38:08.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/frmntl/hints.py 2010-11-11 07:14:52.000000000 +0000 @@ -22,19 +22,16 @@ _ = gpodder.gettext HINT_STRINGS = ( - _("Sign up for gpodder.net to synchronize (and backup) your subscriptions to the cloud."), _("Bulk-deleting episodes is possible from the main window menu."), _("To save power, automatic updates are only enabled while gPodder is running."), _("Subscribe to YouTube users and download their videos to your device."), _("Use the shortcut URL yt: to quickly subscribe to a YouTube user."), - _("Search for your fields of interest in the gpodder.net directory to find interesting content."), _("Longpress on an episode to access a menu with useful episode-related functions."), _("Longpress on an episode in 'New episodes available' to display its shownotes."), _("Use the hardware keyboard to filter down lists - simply start typing in the podcast or episode list."), _("The top row of the menu in each list window lets you set the filter for it."), _("Use fb: as a shorthand for Feedburner URLs (feeds.feedburner.com/)"), _("Episodes marked as 'Keep episode' will never be displayed in the 'Delete episodes' list."), - _("Use gpodder.net to share your subscription list with friends via a private or public URL."), _("Found a problem? Report it at bugs.maemo.org (Extras / gPodder), so we can fix it in the next release."), _("Got a feature request? Let us know at bugs.maemo.org (Extras / gPodder)!"), _("Want to support gPodder? Use the 'donate' button in the about dialog."), diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/frmntl/podcastdirectory.py gpodder-2.9/src/gpodder/gtkui/frmntl/podcastdirectory.py --- gpodder-2.9.orig/src/gpodder/gtkui/frmntl/podcastdirectory.py 2010-08-29 14:52:03.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/frmntl/podcastdirectory.py 2010-11-11 07:10:47.000000000 +0000 @@ -86,7 +86,7 @@ @classmethod def show_add_podcast_picker(cls, parent, toplist_url, opml_url, \ add_urls_callback, subscribe_to_url_callback, \ - my_gpodder_callback, show_text_edit_dialog): + show_text_edit_dialog): dialog = gtk.Dialog(_('Select a source'), parent) pannable_area = hildon.PannableArea() pannable_area.set_size_request_policy(hildon.SIZE_REQUEST_CHILDREN) @@ -109,15 +109,6 @@ _('URL:'), is_url=True, affirmative_text=_('Load')) load_opml_from_url(url) - def choice_search_mygpo(widget): - dialog.destroy() - search_term = show_text_edit_dialog(\ - _('Search on gpodder.net'), \ - _('Search for:'), affirmative_text=_('Search')) - if search_term is not None: - url = 'http://gpodder.net/search.opml?q=%s' % (urllib.quote(search_term),) - load_opml_from_url(url) - def choice_load_opml_from_file(widget): dialog.destroy() dlg = gobject.new(hildon.FileChooserDialog, \ @@ -147,19 +138,13 @@ url = 'youtube://%s' % (search_term,) load_opml_from_url(url) - def choice_mygpodder(widget): - dialog.destroy() - my_gpodder_callback() - choices = ( (_('Podcast feed/website URL'), choice_enter_feed_url), (_('OPML file from the web'), choice_load_opml_from_url), - (_('Search on gpodder.net'), choice_search_mygpo), (_('Open OPML file'), choice_load_opml_from_file), (_('Example podcasts'), choice_load_examples), (_('Podcast Top 50'), choice_load_toplist), (_('Search YouTube users'), choice_search_youtube), - (_('Download from gpodder.net'), choice_mygpodder), ) for caption, handler in choices: diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/frmntl/preferences.py gpodder-2.9/src/gpodder/gtkui/frmntl/preferences.py --- gpodder-2.9.orig/src/gpodder/gtkui/frmntl/preferences.py 2010-08-29 14:52:03.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/frmntl/preferences.py 2010-11-11 06:57:06.000000000 +0000 @@ -150,27 +150,12 @@ child = button.get_child() child.set_padding(0, 0, 12, 0) - self.button_enable_mygpo.set_name('HildonCheckButton-finger') - self.check_view_all_episodes = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT) self.check_view_all_episodes.set_label(_('Show "All episodes" view')) self.check_view_all_episodes.set_active(self._config.podcast_list_view_all) self.pannable_vbox.add(self.check_view_all_episodes) self.pannable_vbox.reorder_child(self.check_view_all_episodes, 2) - # Disable capitalization word completion - self.entry_mygpo_username.set_property('hildon-input-mode', \ - gtk.HILDON_GTK_INPUT_MODE_FULL) - self.entry_mygpo_password.set_property('hildon-input-mode', \ - gtk.HILDON_GTK_INPUT_MODE_FULL) - - self.entry_mygpo_password.set_visibility(False) - - self.button_enable_mygpo.set_active(self._config.mygpo_enabled) - self.entry_mygpo_username.set_text(self._config.mygpo_username) - self.entry_mygpo_password.set_text(self._config.mygpo_password) - self.entry_mygpo_device.set_text(self._config.mygpo_device_caption) - self.gPodderPreferences.show_all() def on_picker_orientation_value_changed(self, *args): @@ -209,15 +194,6 @@ self._config.restore_backup(self._config_backup) else: self._config.podcast_list_view_all = self.check_view_all_episodes.get_active() - self._config.mygpo_enabled = self.button_enable_mygpo.get_active() - self._config.mygpo_username = self.entry_mygpo_username.get_text() - self._config.mygpo_password = self.entry_mygpo_password.get_text() - self._config.mygpo_device_caption = self.entry_mygpo_device.get_text() - - # Make sure the device is successfully created/updated - self.mygpo_client.create_device() - # Flush settings for mygpo client now - self.mygpo_client.flush(now=True) self.callback_finished() diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/interface/welcome.py gpodder-2.9/src/gpodder/gtkui/interface/welcome.py --- gpodder-2.9.orig/src/gpodder/gtkui/interface/welcome.py 2010-03-29 09:18:47.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/interface/welcome.py 2010-11-11 06:57:06.000000000 +0000 @@ -26,10 +26,10 @@ from gpodder.gtkui.interface.common import BuilderWidget class gPodderWelcome(BuilderWidget): - finger_friendly_widgets = ['btnOPML', 'btnMygPodder', 'btnCancel'] + finger_friendly_widgets = ['btnOPML', 'btnCancel'] def new(self): - for widget in (self.btnOPML, self.btnMygPodder): + for widget in (self.btnOPML): for child in widget.get_children(): if isinstance(child, gtk.Alignment): child.set_padding(20, 20, 20, 20) @@ -38,7 +38,6 @@ if gpodder.ui.fremantle: self.btnOPML.set_name('HildonButton-thumb') - self.btnMygPodder.set_name('HildonButton-thumb') self.gPodderWelcome.show() @@ -46,10 +45,6 @@ self.gPodderWelcome.destroy() self.show_example_podcasts_callback(None) - def on_setup_my_gpodder(self, gpodder): - self.gPodderWelcome.destroy() - self.setup_my_gpodder_callback(None) - def on_btnCancel_clicked(self, button): self.gPodderWelcome.destroy() diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/maemo/mygpodder.py gpodder-2.9/src/gpodder/gtkui/maemo/mygpodder.py --- gpodder-2.9.orig/src/gpodder/gtkui/maemo/mygpodder.py 2010-08-05 13:30:17.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/maemo/mygpodder.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -# -# gPodder - A media aggregator and podcast client -# Copyright (c) 2005-2010 Thomas Perl and the gPodder Team -# -# gPodder is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# gPodder is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -# gpodder.gtkui.mygpodder- UI code for gpodder.net settings -# Thomas Perl ; 2010-01-19 - -import threading - -import gpodder - -_ = gpodder.gettext - -from gpodder.gtkui.interface.common import BuilderWidget - - -class MygPodderSettings(BuilderWidget): - # Columns IDs for the combo box model - C_ID, C_CAPTION = range(2) - - def new(self): - # We need to have a MygPoClient instance available - assert getattr(self, 'mygpo_client', None) is not None - - active_index = 0 - - # Initialize the UI state with configuration settings - self.checkbutton_enable.set_active(self.config.mygpo_enabled) - self.entry_username.set_text(self.config.mygpo_username) - self.entry_password.set_text(self.config.mygpo_password) - #self.label_uid_value.set_label(self.config.mygpo_device_uid) - self.entry_caption.set_text(self.config.mygpo_device_caption) - - # Disable input capitalization for the login fields - self.entry_username.set_property('hildon-input-mode', \ - 'HILDON_GTK_INPUT_MODE_FULL') - self.entry_password.set_property('hildon-input-mode', \ - 'HILDON_GTK_INPUT_MODE_FULL') - self.entry_password.set_visibility(False) - - # Disable mygpo sync while the dialog is open - self._enable_mygpo = self.config.mygpo_enabled - self.config.mygpo_enabled = False - - def on_enabled_toggled(self, widget): - # Only update indirectly (see on_delete_event) - self._enable_mygpo = widget.get_active() - - def on_username_changed(self, widget): - self.config.mygpo_username = widget.get_text() - - def on_password_changed(self, widget): - self.config.mygpo_password = widget.get_text() - - def on_device_caption_changed(self, widget): - self.config.mygpo_device_caption = widget.get_text() - - def on_button_overwrite_clicked(self, button): - title = _('Replace subscription list on server') - message = _('Remote podcasts that have not been added locally will be removed on the server. Continue?') - if self.show_confirmation(message, title): - def thread_proc(): - self.config.mygpo_enabled = True - self.on_send_full_subscriptions() - self.config.mygpo_enabled = False - threading.Thread(target=thread_proc).start() - - def on_delete_event(self, widget, event): - # Re-enable mygpo sync if the user has selected it - self.config.mygpo_enabled = self._enable_mygpo - # Make sure the device is successfully created/updated - self.mygpo_client.create_device() - # Flush settings for mygpo client now - self.mygpo_client.flush(now=True) - - def on_button_close_clicked(self, button): - self.on_delete_event(self.main_window, None) - self.main_window.destroy() - diff -Naur gpodder-2.9.orig/src/gpodder/gtkui/maemo/podcastdirectory.py gpodder-2.9/src/gpodder/gtkui/maemo/podcastdirectory.py --- gpodder-2.9.orig/src/gpodder/gtkui/maemo/podcastdirectory.py 2010-08-29 14:52:03.000000000 +0000 +++ gpodder-2.9/src/gpodder/gtkui/maemo/podcastdirectory.py 2010-11-11 07:09:59.000000000 +0000 @@ -63,7 +63,6 @@ submenu = gtk.Menu() submenu.append(self.action_load_opml.create_menu_item()) submenu.append(self.action_load_toplist.create_menu_item()) - submenu.append(self.action_search_mygpo.create_menu_item()) submenu.append(self.action_load_youtube.create_menu_item()) item.set_submenu(submenu) menu.append(item) @@ -111,14 +110,6 @@ def on_load_toplist_button_clicked(self, widget): self.download_opml_file(self._config.toplist_url) - def on_search_mygpo_button_clicked(self, widget): - search_term = self.show_text_edit_dialog(\ - _('Search on gpodder.net'), \ - _('Search for:')) - if search_term is not None: - self.download_opml_file('http://gpodder.net/search.opml?q=%s' % ( \ - urllib.quote(search_term),)) - def on_load_youtube_button_clicked(self, widget): search_term = self.show_text_edit_dialog(\ _('Search YouTube user channels'), \ diff -Naur gpodder-2.9.orig/data/ui/desktop/gpodderpreferences.ui gpodder-2.9/data/ui/desktop/gpodderpreferences.ui --- gpodder-2.9.orig/data/ui/desktop/gpodderpreferences.ui 2010-08-05 13:30:16.000000000 +0000 +++ gpodder-2.9/data/ui/desktop/gpodderpreferences.ui 2010-11-11 06:57:06.000000000 +0000 @@ -175,118 +175,6 @@ General - - - 6 - 6 - 3 - 7 - 6 - True - - - Synchronize subscriptions and episode actions - True - - - - 2 - 3 - 1 - - - - - Username: - True - 1.0 - - - 3 - 2 - fill - - - - - Password: - True - 1.0 - - - 4 - 3 - fill - - - - - Replace list on server with local subscriptions - True - - - - 6 - 3 - 5 - - - - - Device name: - True - 1.0 - - - 5 - 4 - fill - - - - - True - - - - 3 - 1 - 3 - 2 - - - - - False - True - True - - - - 4 - 1 - 3 - 3 - - - - - True - - - - 5 - 1 - 3 - 4 - - - - - gpodder.net - 1 - - diff -Naur gpodder-2.9.orig/data/ui/desktop/gpodder.ui gpodder-2.9/data/ui/desktop/gpodder.ui --- gpodder-2.9.orig/data/ui/desktop/gpodder.ui 2010-08-29 14:52:02.000000000 +0000 +++ gpodder-2.9/data/ui/desktop/gpodder.ui 2010-11-11 06:57:06.000000000 +0000 @@ -157,12 +157,6 @@ - - Go to gpodder.net - - - - menuChannels _Episodes @@ -449,7 +443,6 @@ - diff -Naur gpodder-2.9.orig/data/ui/frmntl/gpodderpreferences.ui gpodder-2.9/data/ui/frmntl/gpodderpreferences.ui --- gpodder-2.9.orig/data/ui/frmntl/gpodderpreferences.ui 2010-08-29 14:52:02.000000000 +0000 +++ gpodder-2.9/data/ui/frmntl/gpodderpreferences.ui 2010-11-11 07:16:09.000000000 +0000 @@ -67,96 +67,8 @@ True - - - gpodder.net Synchronization - True - - - - - Synchronize with gpodder.net - True - HILDON_SIZE_FINGER_HEIGHT - - - - - 6 - 2 - 3 - 6 - True - - - Username: - True - 1.0 - - - fill - - - - - Password: - True - 1.0 - - - 2 - 1 - fill - - - - - Device name: - True - 1.0 - - - 3 - 2 - fill - - - - - True - - - 1 - 2 - - - - - True - - - 2 - 1 - 2 - 1 - - - - - True - - - 3 - 1 - 2 - 2 - - - - - True diff -Naur gpodder-2.9.orig/data/ui/frmntl/gpodderwelcome.ui gpodder-2.9/data/ui/frmntl/gpodderwelcome.ui --- gpodder-2.9.orig/data/ui/frmntl/gpodderwelcome.ui 2010-08-05 13:30:16.000000000 +0000 +++ gpodder-2.9/data/ui/frmntl/gpodderwelcome.ui 2010-11-11 06:57:06.000000000 +0000 @@ -21,14 +21,6 @@ - - - Download my list from gpodder.net - True - HILDON_SIZE_THUMB_HEIGHT - - - diff -Naur gpodder-2.9.orig/data/ui/gpodderwelcome.ui gpodder-2.9/data/ui/gpodderwelcome.ui --- gpodder-2.9.orig/data/ui/gpodderwelcome.ui 2010-08-05 13:30:16.000000000 +0000 +++ gpodder-2.9/data/ui/gpodderwelcome.ui 2010-11-11 06:57:06.000000000 +0000 @@ -79,16 +79,6 @@ - - - Download my subscriptions from gpodder.net - True - - - - 1 - - 1 diff -Naur gpodder-2.9.orig/data/ui/maemo/gpodderpodcastdirectory.ui gpodder-2.9/data/ui/maemo/gpodderpodcastdirectory.ui --- gpodder-2.9.orig/data/ui/maemo/gpodderpodcastdirectory.ui 2010-08-29 14:52:02.000000000 +0000 +++ gpodder-2.9/data/ui/maemo/gpodderpodcastdirectory.ui 2010-11-11 07:06:05.000000000 +0000 @@ -100,10 +100,6 @@ gtk-about - - Search on gpodder.net - - YouTube user channel diff -Naur gpodder-2.9.orig/data/ui/maemo/gpodder.ui gpodder-2.9/data/ui/maemo/gpodder.ui --- gpodder-2.9.orig/data/ui/maemo/gpodder.ui 2010-08-29 14:52:02.000000000 +0000 +++ gpodder-2.9/data/ui/maemo/gpodder.ui 2010-11-11 06:57:06.000000000 +0000 @@ -158,19 +158,6 @@ - - item_mygpo_settings - gpodder.net Settings - - - - - - Go to gpodder.net - - - - menuChannels _Episodes @@ -385,8 +372,6 @@ - - @@ -413,7 +398,6 @@ - diff -Naur gpodder-2.9.orig/data/ui/maemo/mygpoddersettings.ui gpodder-2.9/data/ui/maemo/mygpoddersettings.ui --- gpodder-2.9.orig/data/ui/maemo/mygpoddersettings.ui 2010-08-05 13:30:16.000000000 +0000 +++ gpodder-2.9/data/ui/maemo/mygpoddersettings.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ - - - - - 320 - My gpodder.net account - dialog - True - True - - - - 2 - True - - - 6 - 6 - 3 - 7 - 6 - True - - - Synchronize subscriptions and episode actions - True - - - - 2 - 3 - 1 - - - - - Username: - True - 1.0 - - - 3 - 2 - fill - - - - - Password: - True - 1.0 - - - 4 - 3 - fill - - - - - Replace list on server with local subscriptions - True - - - - 6 - 3 - 5 - - - - - Device name: - True - 1.0 - - - 5 - 4 - fill - - - - - True - - - - 3 - 1 - 3 - 2 - - - - - False - True - True - - - - 4 - 1 - 3 - 3 - - - - - True - - - - 5 - 1 - 3 - 4 - - - - - 2 - - - - - 5 - end - 6 - True - - - gtk-close - True - True - - - - True - True - - - - - False - end - - - - - -