66
61
log('(gpodder.sync) Could not find Python Imaging Library (PIL)')
68
63
# Register our dependencies for the synchronization module
69
services.dependency_manager.depend_on(_('iPod synchronization'), _('Support synchronization of podcasts to Apple iPod devices via libgpod.'), ['gpod', 'mad', 'eyeD3'], [])
70
services.dependency_manager.depend_on(_('MTP device synchronization'), _('Support synchronization of podcasts to devices using the Media Transfer Protocol via pymtp.'), ['pymtp'], [])
64
services.dependency_manager.depend_on(_('iPod synchronization'), _('Support synchronization of podcasts to Apple iPod devices via libgpod.'), ['gpod', 'gst'], [])
71
65
services.dependency_manager.depend_on(_('iPod OGG converter'), _('Convert OGG podcasts to MP3 files on synchronization to iPods using oggdec and LAME.'), [], ['oggdec', 'lame'])
72
66
services.dependency_manager.depend_on(_('iPod video podcasts'), _('Detect video lengths via MPlayer, to synchronize video podcasts to iPods.'), [], ['mplayer'])
73
67
services.dependency_manager.depend_on(_('Rockbox cover art support'), _('Copy podcast cover art to filesystem-based MP3 players running Rockbox.org firmware. Needs Python Imaging.'), ['Image'], [])
79
pymtp.MTP.__init__(self)
83
pymtp.MTP.connect(self)
84
self.folders = self.unfold(self.mtp.LIBMTP_Get_Folder_List(self.device))
86
def get_folder_list(self):
89
def unfold(self, folder, path=''):
92
folder = folder.contents
93
name = self.sep.join([path, folder.name]).lstrip(self.sep)
94
result[name] = folder.folder_id
96
result.update(self.unfold(folder.child, name))
97
folder = folder.sibling
100
def mkdir(self, path):
103
parts = path.split(self.sep)
105
prefix.append(parts[0])
106
tmpath = self.sep.join(prefix)
107
if self.folders.has_key(tmpath):
108
folder_id = self.folders[tmpath]
110
folder_id = self.create_folder(parts[0], parent=folder_id)
111
# log('Creating subfolder %s in %s (id=%u)' % (parts[0], self.sep.join(prefix), folder_id))
112
tmpath = self.sep.join(prefix + [parts[0]])
113
self.folders[tmpath] = folder_id
114
# log(">>> %s = %s" % (tmpath, folder_id))
116
# log('MTP.mkdir: %s = %u' % (path, folder_id))
81
119
def open_device(config):
82
120
device_type = config.device_type
104
142
log('Please install MPlayer for track length detection.')
107
mad_info = mad.MadFile(filename)
108
return int(mad_info.total_time())
113
145
eyed3_info = eyeD3.Mp3AudioFile(filename)
114
146
return int(eyed3_info.getPlayTime()*1000)
306
337
gpod.itdb_write(self.itdb, None)
340
if self._config.ipod_write_gtkpod_extended:
341
self.notify('status', _('Writing extended gtkpod database'))
342
ext_filename = os.path.join(self.mountpoint, 'iPod_Control', 'iTunes', 'iTunesDB.ext')
343
idb_filename = os.path.join(self.mountpoint, 'iPod_Control', 'iTunes', 'iTunesDB')
344
if os.path.exists(ext_filename) and os.path.exists(idb_filename):
346
db = gpod.ipod.Database(self.mountpoint)
347
gpod.gtkpod.parse(ext_filename, db, idb_filename)
348
gpod.gtkpod.write(ext_filename, db, idb_filename)
351
log('Error when writing iTunesDB.ext', sender=self, traceback=True)
353
log('I could not find %s or %s. Will not update extended gtkpod DB.', ext_filename, idb_filename, sender=self)
355
log('Not writing extended gtkpod DB. Set "ipod_write_gpod_extended" to True if I should write it.', sender=self)
309
358
Device.close(self)
440
489
gpod.itdb_track_add(self.itdb, track, -1)
441
490
gpod.itdb_playlist_add_track(self.master_playlist, track, -1)
442
491
gpod.itdb_playlist_add_track(self.podcasts_playlist, track, -1)
443
gpod.itdb_cp_track_to_ipod(track, str(local_filename), None)
492
copied = gpod.itdb_cp_track_to_ipod(track, str(local_filename), None)
494
if copied and gpodder.user_hooks is not None:
495
gpodder.user_hooks.on_file_copied_to_ipod(self, local_filename)
445
497
# If the file has been converted, delete the temporary file here
446
498
if local_filename != original_filename:
552
604
folder = self.destination
606
folder = util.sanitize_encoding(folder)
554
608
from_file = util.sanitize_encoding(self.convert_track(episode))
555
609
filename_base = util.sanitize_filename(episode.sync_filename(self._config.custom_sync_name_enabled, self._config.custom_sync_name), self._config.mp3_player_max_filename_length)
562
616
if os.path.splitext(to_file)[0] == '':
563
617
to_file = os.path.basename(from_file)
565
to_file = os.path.join(folder, to_file)
619
to_file = util.sanitize_encoding(os.path.join(folder, to_file))
567
621
if not os.path.exists(folder):
596
650
if not os.path.exists(to_file):
597
651
log('Copying %s => %s', os.path.basename(from_file), to_file.decode(util.encoding), sender=self)
598
return self.copy_file_progress(from_file, to_file)
652
copied = self.copy_file_progress(from_file, to_file)
653
if copied and gpodder.user_hooks is not None:
654
gpodder.user_hooks.on_file_copied_to_filesystem(self, from_file, to_file)
775
832
Device.__init__(self, config)
776
833
self.__model_name = None
778
self.__MTPDevice = pymtp.MTP()
835
self.__MTPDevice = MTP()
779
836
except NameError, e:
780
837
# pymtp not available / not installed (see bug 924)
781
838
log('pymtp not found: %s', str(e), sender=self)
900
957
def add_track(self, episode):
901
958
self.notify('status', _('Adding %s...') % episode.title)
902
959
filename = str(self.convert_track(episode))
903
log("sending " + filename + " (" + episode.title + ").", sender=self)
960
log("sending %s (%s).", filename, episode.title, sender=self)
906
963
# verify free space
920
977
metadata.date = self.__date_to_mtp(episode.pubDate)
921
978
metadata.duration = get_track_length(str(filename))
981
if episode.mimetype.startswith('audio/') and self._config.mtp_audio_folder:
982
folder_name = self._config.mtp_audio_folder
983
if episode.mimetype.startswith('video/') and self._config.mtp_video_folder:
984
folder_name = self._config.mtp_video_folder
985
if episode.mimetype.startswith('image/') and self._config.mtp_image_folder:
986
folder_name = self._config.mtp_image_folder
988
if folder_name != '' and self._config.mtp_podcast_folders:
989
folder_name += os.path.sep + str(episode.channel.title)
991
# log('Target MTP folder: %s' % folder_name)
993
if folder_name == '':
996
folder_id = self.__MTPDevice.mkdir(folder_name)
924
self.__MTPDevice.send_track_from_file(filename,
925
util.sanitize_filename(metadata.title)+episode.extension(),
926
metadata, 0, callback=self.__callback)
999
to_file = util.sanitize_filename(metadata.title) + episode.extension()
1000
self.__MTPDevice.send_track_from_file(filename, to_file,
1001
metadata, folder_id, callback=self.__callback)
1002
if gpodder.user_hooks is not None:
1003
gpodder.user_hooks.on_file_copied_to_mtp(self, filename, to_file)
928
1005
log('unable to add episode %s', episode.title, sender=self, traceback=True)