remove old, disabled mtp support
This commit is contained in:
parent
e2a512a34c
commit
b6d5836827
|
@ -667,10 +667,6 @@ class gPodderPreferences(BuilderWidget):
|
|||
label = children.pop()
|
||||
label.set_alignment(0., .5)
|
||||
|
||||
else:
|
||||
# TODO: Add support for iPod and MTP devices
|
||||
pass
|
||||
|
||||
def on_btn_device_mountpoint_clicked(self, widget):
|
||||
fs = Gtk.FileChooserDialog(title=_('Select folder for mount point'),
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
|
|
|
@ -42,24 +42,12 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
_ = gpodder.gettext
|
||||
|
||||
#
|
||||
# TODO: Re-enable iPod and MTP sync support
|
||||
#
|
||||
|
||||
pymtp_available = False
|
||||
gpod_available = True
|
||||
try:
|
||||
import gpod
|
||||
except:
|
||||
gpod_available = False
|
||||
|
||||
# pymtp_available = True
|
||||
# try:
|
||||
# import gpodder.gpopymtp as pymtp
|
||||
# except:
|
||||
# pymtp_available = False
|
||||
# logger.warning('Could not load gpopymtp (libmtp not installed?).')
|
||||
|
||||
mplayer_available = True if util.find_command('mplayer') is not None else False
|
||||
|
||||
eyed3mp3_available = True
|
||||
|
@ -69,52 +57,6 @@ except:
|
|||
eyed3mp3_available = False
|
||||
|
||||
|
||||
if pymtp_available:
|
||||
class MTP(pymtp.MTP):
|
||||
sep = os.path.sep
|
||||
|
||||
def __init__(self):
|
||||
pymtp.MTP.__init__(self)
|
||||
self.folders = {}
|
||||
|
||||
def connect(self):
|
||||
pymtp.MTP.connect(self)
|
||||
self.folders = self.unfold(self.mtp.LIBMTP_Get_Folder_List(self.device))
|
||||
|
||||
def get_folder_list(self):
|
||||
return self.folders
|
||||
|
||||
def unfold(self, folder, path=''):
|
||||
result = {}
|
||||
while folder:
|
||||
folder = folder.contents
|
||||
name = self.sep.join([path, folder.name]).lstrip(self.sep)
|
||||
result[name] = folder.folder_id
|
||||
if folder.get_child():
|
||||
result.update(self.unfold(folder.get_child(), name))
|
||||
folder = folder.sibling
|
||||
return result
|
||||
|
||||
def mkdir(self, path):
|
||||
folder_id = 0
|
||||
prefix = []
|
||||
parts = path.split(self.sep)
|
||||
while parts:
|
||||
prefix.append(parts[0])
|
||||
tmpath = self.sep.join(prefix)
|
||||
if tmpath in self.folders:
|
||||
folder_id = self.folders[tmpath]
|
||||
else:
|
||||
folder_id = self.create_folder(parts[0], parent=folder_id)
|
||||
# logger.info('Creating subfolder %s in %s (id=%u)' % (parts[0], self.sep.join(prefix), folder_id))
|
||||
tmpath = self.sep.join(prefix + [parts[0]])
|
||||
self.folders[tmpath] = folder_id
|
||||
# logger.info(">>> %s = %s" % (tmpath, folder_id))
|
||||
del parts[0]
|
||||
# logger.info('MTP.mkdir: %s = %u' % (path, folder_id))
|
||||
return folder_id
|
||||
|
||||
|
||||
def open_device(gui):
|
||||
config = gui._config
|
||||
device_type = gui._config.device_sync.device_type
|
||||
|
@ -756,235 +698,6 @@ class MP3PlayerDevice(Device):
|
|||
return False
|
||||
return True
|
||||
|
||||
class MTPDevice(Device):
|
||||
def __init__(self, config):
|
||||
Device.__init__(self, config)
|
||||
self.__model_name = None
|
||||
try:
|
||||
self.__MTPDevice = MTP()
|
||||
except NameError as e:
|
||||
# pymtp not available / not installed (see bug 924)
|
||||
logger.error('pymtp not found: %s', str(e))
|
||||
self.__MTPDevice = None
|
||||
|
||||
def __callback(self, sent, total):
|
||||
if self.cancelled:
|
||||
return -1
|
||||
percentage = round(sent / total * 100)
|
||||
text = ('%i%%' % percentage)
|
||||
self.notify('progress', sent, total, text)
|
||||
|
||||
def __date_to_mtp(self, date):
|
||||
"""
|
||||
this function format the given date and time to a string representation
|
||||
according to MTP specifications: YYYYMMDDThhmmss.s
|
||||
|
||||
return
|
||||
the string representation od the given date
|
||||
"""
|
||||
if not date:
|
||||
return ""
|
||||
try:
|
||||
d = time.gmtime(date)
|
||||
return time.strftime("%Y%m%d-%H%M%S.0Z", d)
|
||||
except Exception as exc:
|
||||
logger.error('ERROR: An error has happend while trying to convert date to an mtp string')
|
||||
return None
|
||||
|
||||
def __mtp_to_date(self, mtp):
|
||||
"""
|
||||
this parse the mtp's string representation for date
|
||||
according to specifications (YYYYMMDDThhmmss.s) to
|
||||
a python time object
|
||||
"""
|
||||
if not mtp:
|
||||
return None
|
||||
|
||||
try:
|
||||
mtp = mtp.replace(" ", "0")
|
||||
# replace blank with 0 to fix some invalid string
|
||||
d = time.strptime(mtp[:8] + mtp[9:13], "%Y%m%d%H%M%S")
|
||||
_date = calendar.timegm(d)
|
||||
if len(mtp) == 20:
|
||||
# TIME ZONE SHIFTING: the string contains a hour/min shift relative to a time zone
|
||||
try:
|
||||
shift_direction = mtp[15]
|
||||
hour_shift = int(mtp[16:18])
|
||||
minute_shift = int(mtp[18:20])
|
||||
shift_in_sec = hour_shift * 3600 + minute_shift * 60
|
||||
if shift_direction == "+":
|
||||
_date += shift_in_sec
|
||||
elif shift_direction == "-":
|
||||
_date -= shift_in_sec
|
||||
else:
|
||||
raise ValueError("Expected + or -")
|
||||
except Exception as exc:
|
||||
logger.warning('WARNING: ignoring invalid time zone information for %s (%s)')
|
||||
return max(0, _date)
|
||||
except Exception as exc:
|
||||
logger.warning('WARNING: the mtp date "%s" can not be parsed against mtp specification (%s)')
|
||||
return None
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
this function try to find a nice name for the device.
|
||||
First, it tries to find a friendly (user assigned) name
|
||||
(this name can be set by other application and is stored on the device).
|
||||
if no friendly name was assign, it tries to get the model name (given by the vendor).
|
||||
If no name is found at all, a generic one is returned.
|
||||
|
||||
Once found, the name is cached internaly to prevent reading again the device
|
||||
|
||||
return
|
||||
the name of the device
|
||||
"""
|
||||
|
||||
if self.__model_name:
|
||||
return self.__model_name
|
||||
|
||||
if self.__MTPDevice is None:
|
||||
return _('MTP device')
|
||||
|
||||
self.__model_name = self.__MTPDevice.get_devicename()
|
||||
# actually libmtp.Get_Friendlyname
|
||||
if not self.__model_name or self.__model_name == "?????":
|
||||
self.__model_name = self.__MTPDevice.get_modelname()
|
||||
if not self.__model_name:
|
||||
self.__model_name = _('MTP device')
|
||||
|
||||
return self.__model_name
|
||||
|
||||
def open(self):
|
||||
Device.open(self)
|
||||
logger.info("opening the MTP device")
|
||||
self.notify('status', _('Opening the MTP device'), )
|
||||
|
||||
try:
|
||||
self.__MTPDevice.connect()
|
||||
# build the initial tracks_list
|
||||
self.tracks_list = self.get_all_tracks()
|
||||
except Exception as exc:
|
||||
logger.error('unable to find an MTP device (%s)')
|
||||
return False
|
||||
|
||||
self.notify('status', _('%s opened') % self.get_name())
|
||||
return True
|
||||
|
||||
def close(self):
|
||||
logger.info("closing %s", self.get_name())
|
||||
self.notify('status', _('Closing %s') % self.get_name())
|
||||
|
||||
try:
|
||||
self.__MTPDevice.disconnect()
|
||||
except Exception as exc:
|
||||
logger.error('unable to close %s (%s)', self.get_name())
|
||||
return False
|
||||
|
||||
self.notify('status', _('%s closed') % self.get_name())
|
||||
Device.close(self)
|
||||
return True
|
||||
|
||||
def add_track(self, episode):
|
||||
self.notify('status', _('Adding %s...') % episode.title)
|
||||
filename = str(self.convert_track(episode))
|
||||
logger.info("sending %s (%s).", filename, episode.title)
|
||||
|
||||
try:
|
||||
# verify free space
|
||||
needed = util.calculate_size(filename)
|
||||
free = self.get_free_space()
|
||||
if needed > free:
|
||||
logger.error('Not enough space on device %s: %s available, but '
|
||||
'need at least %s',
|
||||
self.get_name(),
|
||||
util.format_filesize(free),
|
||||
util.format_filesize(needed))
|
||||
self.cancelled = True
|
||||
return False
|
||||
|
||||
# fill metadata
|
||||
metadata = pymtp.LIBMTP_Track()
|
||||
metadata.title = str(episode.title)
|
||||
metadata.artist = str(episode.channel.title)
|
||||
metadata.album = str(episode.channel.title)
|
||||
metadata.genre = "podcast"
|
||||
metadata.date = self.__date_to_mtp(episode.published)
|
||||
metadata.duration = get_track_length(str(filename))
|
||||
|
||||
folder_name = ''
|
||||
if episode.mimetype.startswith('audio/') and self._config.mtp_audio_folder:
|
||||
folder_name = self._config.mtp_audio_folder
|
||||
if episode.mimetype.startswith('video/') and self._config.mtp_video_folder:
|
||||
folder_name = self._config.mtp_video_folder
|
||||
if episode.mimetype.startswith('image/') and self._config.mtp_image_folder:
|
||||
folder_name = self._config.mtp_image_folder
|
||||
|
||||
if folder_name != '' and self._config.mtp_podcast_folders:
|
||||
folder_name += os.path.sep + str(episode.channel.title)
|
||||
|
||||
# log('Target MTP folder: %s' % folder_name)
|
||||
|
||||
if folder_name == '':
|
||||
folder_id = 0
|
||||
else:
|
||||
folder_id = self.__MTPDevice.mkdir(folder_name)
|
||||
|
||||
# send the file
|
||||
to_file = util.sanitize_filename(metadata.title) + episode.extension()
|
||||
self.__MTPDevice.send_track_from_file(filename, to_file,
|
||||
metadata, folder_id, callback=self.__callback)
|
||||
if gpodder.user_hooks is not None:
|
||||
gpodder.user_hooks.on_file_copied_to_mtp(self, filename, to_file)
|
||||
except:
|
||||
logger.error('unable to add episode %s', episode.title)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def remove_track(self, sync_track):
|
||||
self.notify('status', _('Removing %s') % sync_track.mtptrack.title)
|
||||
logger.info("removing %s", sync_track.mtptrack.title)
|
||||
|
||||
try:
|
||||
self.__MTPDevice.delete_object(sync_track.mtptrack.item_id)
|
||||
except Exception as exc:
|
||||
logger.error('unable remove file %s (%s)', sync_track.mtptrack.filename)
|
||||
|
||||
logger.info('%s removed', sync_track.mtptrack.title)
|
||||
|
||||
def get_all_tracks(self):
|
||||
try:
|
||||
listing = self.__MTPDevice.get_tracklisting(callback=self.__callback)
|
||||
except Exception as exc:
|
||||
logger.error('unable to get file listing %s (%s)')
|
||||
|
||||
tracks = []
|
||||
for track in listing:
|
||||
title = track.title
|
||||
if not title or title == "": title = track.filename
|
||||
if len(title) > 50: title = title[0:49] + '...'
|
||||
artist = track.artist
|
||||
if artist and len(artist) > 50: artist = artist[0:49] + '...'
|
||||
length = track.filesize
|
||||
age_in_days = 0
|
||||
date = self.__mtp_to_date(track.date)
|
||||
if not date:
|
||||
modified = track.date # not a valid mtp date. Display what mtp gave anyway
|
||||
modified_sort = -1 # no idea how to sort invalid date
|
||||
else:
|
||||
modified = util.format_date(date)
|
||||
modified_sort = date
|
||||
|
||||
t = SyncTrack(title, length, modified, modified_sort=modified_sort, mtptrack=track, podcast=artist)
|
||||
tracks.append(t)
|
||||
return tracks
|
||||
|
||||
def get_free_space(self):
|
||||
if self.__MTPDevice is not None:
|
||||
return self.__MTPDevice.get_freespace()
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
class SyncCancelledException(Exception): pass
|
||||
|
||||
|
|
Loading…
Reference in New Issue