added support for fs-based mp3 player sync
git-svn-id: svn://svn.berlios.de/gpodder/trunk@220 b0d088ad-0a06-0410-aad2-9ed5178a7e87
This commit is contained in:
parent
d4fb8d2651
commit
60029079e5
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Sun, 17 Dec 2006 02:19:04 +0100 <thp@perli.net>
|
||||
* src/gpodder/libipodsync.py: Re-factor general sync method
|
||||
interface to "gPodderSyncMethod" and let gPodder_iPodSync
|
||||
and gPodder_FSSync implement the syncing (added class
|
||||
gPodder_FSSync that simply syncs to a specified folder)
|
||||
* src/gpodder/gpodder.py: Use new libipodsync + add support
|
||||
for filesystem-based MP3 players (please test this :)
|
||||
* TODO: fs-based mp3 player support seems to be working now
|
||||
* bin/gpodder: the usual version bumping
|
||||
|
||||
Sat, 16 Dec 2006 18:43:04 +0100 <thp@perli.net>
|
||||
* data/gpodder.glade: Re-structured the main menu
|
||||
* src/gpodder/gpodder.py: Added some code to make the main menu
|
||||
|
|
2
TODO
2
TODO
|
@ -1,7 +1,7 @@
|
|||
|
||||
=== Release Goals for gPodder 0.9.0 ===
|
||||
|
||||
[ ] Implement support for filesystem-based MP3 players
|
||||
[X] Implement support for filesystem-based MP3 players
|
||||
[X] Change "Download" button to "Play" on downloaded podcasts
|
||||
[ ] Add support for importing gPodder 0.8.0 downloaded episodes
|
||||
[ ] Re-structure main menu for better usability
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
# PLEASE DO NOT CHANGE FORMAT OF __version__ LINE (setup.py reads this)
|
||||
|
||||
__author__ = "Thomas Perl <thp@perli.net>"
|
||||
__version__ = "0.8.0+svn20061216"
|
||||
__version__ = "0.8.0+svn20061216-ik"
|
||||
__date__ = "2006-12-16"
|
||||
__copyright__ = "Copyright (c) 2005-2006 %s. All rights reserved." % __author__
|
||||
__licence__ = "GPL"
|
||||
|
|
|
@ -61,6 +61,7 @@ from liblocaldb import localDB
|
|||
from libplayers import UserAppsReader
|
||||
|
||||
from libipodsync import gPodder_iPodSync
|
||||
from libipodsync import gPodder_FSSync
|
||||
from libipodsync import ipod_supported
|
||||
|
||||
app_name = "gpodder"
|
||||
|
@ -338,7 +339,18 @@ class Gpodder(SimpleGladeApp):
|
|||
|
||||
for channel in self.ldb.channel_list:
|
||||
channel.set_metadata_from_localdb()
|
||||
sync.copy_channel_to_ipod( channel)
|
||||
sync.sync_channel( channel)
|
||||
|
||||
sync.close()
|
||||
|
||||
def sync_to_fs_proc( self, sync_win):
|
||||
gpl = gPodderLib()
|
||||
gpl.loadConfig()
|
||||
sync = gPodder_FSSync( destination = gpl.mp3_player_folder, callback_status = sync_win.set_status, callback_progress = sync_win.set_progress, callback_done = sync_win.close)
|
||||
|
||||
for channel in self.ldb.channel_list:
|
||||
channel.set_metadata_from_localdb()
|
||||
sync.sync_channel( channel)
|
||||
|
||||
sync.close()
|
||||
|
||||
|
@ -458,7 +470,12 @@ class Gpodder(SimpleGladeApp):
|
|||
thread = Thread( target = self.sync_to_ipod_proc, args = args)
|
||||
thread.start()
|
||||
elif gl.device_type == 'filesystem':
|
||||
self.showMessage( _('Sync to %s currently not supported.') % ( gl.mp3_player_folder, ))
|
||||
sync_win = Gpoddersync()
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration( False)
|
||||
args = ( sync_win, )
|
||||
thread = Thread( target = self.sync_to_fs_proc, args = args)
|
||||
thread.start()
|
||||
#-- Gpodder.on_sync_to_ipod_activate }
|
||||
|
||||
#-- Gpodder.on_cleanup_ipod_activate {
|
||||
|
|
|
@ -69,6 +69,8 @@ except:
|
|||
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import email.Utils
|
||||
|
@ -87,23 +89,66 @@ def ipod_supported():
|
|||
video_extensions = [ "mov", "mp4", "m4v" ]
|
||||
|
||||
|
||||
class gPodder_iPodSync(object):
|
||||
class gPodderSyncMethod:
|
||||
def __init__( self, callback_progress = None, callback_status = None, callback_done = None):
|
||||
self.callback_progress = callback_progress
|
||||
self.callback_status = callback_status
|
||||
self.callback_done = callback_done
|
||||
|
||||
def set_progress( self, pos, max):
|
||||
if self.callback_progress:
|
||||
gobject.idle_add( self.callback_progress, pos, max)
|
||||
|
||||
def set_status( self, episode = None, channel = None, progressbar_text = None):
|
||||
if self.callback_status:
|
||||
gobject.idle_add( self.callback_status, episode, channel, progressbar_text)
|
||||
|
||||
def set_done( self):
|
||||
if self.callback_done:
|
||||
gobject.idle_add( self.callback_done)
|
||||
|
||||
def sync_channel( self, channel):
|
||||
if not channel.sync_to_devices:
|
||||
return False
|
||||
|
||||
max = len( channel)
|
||||
pos = 1
|
||||
|
||||
for episode in channel:
|
||||
self.set_progress( pos, max)
|
||||
if channel.is_downloaded( episode):
|
||||
self.add_episode_from_channel( channel, episode)
|
||||
pos = pos + 1
|
||||
|
||||
self.set_status( '...', '...', _('Complete: %s') % channel.title)
|
||||
time.sleep(1)
|
||||
|
||||
return True
|
||||
|
||||
def add_episode_from_channel( self, channel, episode):
|
||||
channeltext = channel.title
|
||||
|
||||
if channel.is_music_channel:
|
||||
channeltext = _('%s (to "%s")') % ( channel.title, channel.device_playlist_name )
|
||||
|
||||
self.set_status( episode.title, channeltext)
|
||||
|
||||
def close( self):
|
||||
self.set_done()
|
||||
|
||||
|
||||
class gPodder_iPodSync( gPodderSyncMethod):
|
||||
itdb = None
|
||||
ipod_mount = '' # mountpoint for ipod
|
||||
playlist_name = 'gpodder' # name of playlist to sync to
|
||||
pl_master = None
|
||||
pl_podcasts = None
|
||||
callback_progress = None
|
||||
callback_status = None
|
||||
callback_done = None
|
||||
|
||||
def __init__( self, ipod_mount = '/media/ipod/', callback_progress = None, callback_status = None, callback_done = None):
|
||||
if not ipod_supported():
|
||||
log( '(ipodsync) iPod functions not supported. (libgpod + eyed3 needed)')
|
||||
self.ipod_mount = ipod_mount
|
||||
self.callback_progress = callback_progress
|
||||
self.callback_status = callback_status
|
||||
self.callback_done = callback_done
|
||||
gPodderSyncMethod.__init__( self, callback_progress, callback_status, callback_done)
|
||||
|
||||
def open( self):
|
||||
if not ipod_supported():
|
||||
|
@ -125,24 +170,20 @@ class gPodder_iPodSync(object):
|
|||
if not ipod_supported():
|
||||
return False
|
||||
if write_update:
|
||||
if self.callback_progress != None:
|
||||
gobject.idle_add( self.callback_progress, 100, 100)
|
||||
if self.callback_status != None:
|
||||
gobject.idle_add( self.callback_status, '...', '...', _('Saving iPod database...'))
|
||||
self.set_progress( 100, 100)
|
||||
self.set_status( '...', '...', _('Saving iPod database...'))
|
||||
if self.itdb:
|
||||
gpod.itdb_write( self.itdb, None)
|
||||
self.itdb = None
|
||||
if self.callback_done != None:
|
||||
time.sleep(1)
|
||||
gobject.idle_add( self.callback_done)
|
||||
time.sleep( 1)
|
||||
gPodderSyncMethod.close( self)
|
||||
return True
|
||||
|
||||
def remove_from_ipod( self, track, playlists):
|
||||
if not ipod_supported():
|
||||
return False
|
||||
log( '(ipodsync) Removing track from iPod: %s', track.title)
|
||||
if self.callback_status != None:
|
||||
gobject.idle_add( self.callback_status, track.title, track.artist)
|
||||
self.set_status( track.title, track.artist)
|
||||
fname = gpod.itdb_filename_on_ipod( track)
|
||||
for playlist in playlists:
|
||||
try:
|
||||
|
@ -196,24 +237,6 @@ class gPodder_iPodSync(object):
|
|||
log( '(ipodsync) Trying to remove: %s', track.title)
|
||||
self.remove_from_ipod( track, [ self.pl_podcasts ])
|
||||
|
||||
def copy_channel_to_ipod( self, channel):
|
||||
if not ipod_supported():
|
||||
return False
|
||||
if not channel.sync_to_devices:
|
||||
# we don't want to sync this..
|
||||
return False
|
||||
max = len( channel)
|
||||
i = 1
|
||||
for episode in channel:
|
||||
if self.callback_progress != None:
|
||||
gobject.idle_add( self.callback_progress, i, max)
|
||||
if channel.is_downloaded( episode):
|
||||
self.add_episode_from_channel( channel, episode)
|
||||
i=i+1
|
||||
if self.callback_status != None:
|
||||
gobject.idle_add( self.callback_status, '...', '...', _('Complete: %s') % channel.title)
|
||||
time.sleep(1)
|
||||
|
||||
def set_podcast_flags( self, track):
|
||||
if not ipod_supported():
|
||||
return False
|
||||
|
@ -262,14 +285,10 @@ class gPodder_iPodSync(object):
|
|||
def add_episode_from_channel( self, channel, episode):
|
||||
if not ipod_supported():
|
||||
return False
|
||||
if self.callback_status != None:
|
||||
channeltext = channel.title
|
||||
if channel.is_music_channel:
|
||||
channeltext = _('%s (to "%s")') % ( channel.title, channel.device_playlist_name )
|
||||
gobject.idle_add( self.callback_status, episode.title, channeltext)
|
||||
|
||||
gPodderSyncMethod.add_episode_from_channel( self, channel, episode)
|
||||
|
||||
if self.episode_is_on_ipod( channel, episode):
|
||||
# episode is already here :)
|
||||
return True
|
||||
|
||||
log( '(ipodsync) Adding item: %s from %s', episode.title, channel.title)
|
||||
|
@ -336,3 +355,36 @@ class gPodder_iPodSync(object):
|
|||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class gPodder_FSSync( gPodderSyncMethod):
|
||||
def __init__( self, destination = '/tmp/', callback_progress = None, callback_status = None, callback_done = None):
|
||||
self.destination = destination
|
||||
gPodderSyncMethod.__init__( self, callback_progress, callback_status, callback_done)
|
||||
|
||||
def add_episode_from_channel( self, channel, episode):
|
||||
gPodderSyncMethod.add_episode_from_channel( self, channel, episode)
|
||||
|
||||
folder = os.path.join( self.destination, channel.title)
|
||||
from_file = channel.getPodcastFilename( episode.url)
|
||||
to_file = episode.title + os.path.splitext( from_file)[1].lower()
|
||||
|
||||
for ch in ('/', '?', ':'):
|
||||
to_file = to_file.replace( ch, '-')
|
||||
|
||||
to_file = os.path.join( folder, to_file)
|
||||
|
||||
try:
|
||||
os.makedirs( folder)
|
||||
except:
|
||||
pass
|
||||
|
||||
if not os.path.exists( to_file):
|
||||
log( 'Copying: %s => %s', os.path.basename( from_file), to_file)
|
||||
shutil.copyfile( from_file, to_file)
|
||||
|
||||
try:
|
||||
os.system('sync')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
|
Loading…
Reference in New Issue