Fri, 13 Jun 2008 16:08:16 +0200 <thp@perli.net>
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
This commit is contained in:
parent
ed11f1eef9
commit
0aec290ec2
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
Fri, 13 Jun 2008 16:08:16 +0200 <thp@perli.net>
|
||||
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)
|
||||
|
||||
Fri, 13 Jun 2008 14:27:30 +0200 <thp@perli.net>
|
||||
Merge patch from Justin Forest to speed up pubDate detection
|
||||
|
||||
|
@ -7,6 +28,7 @@ Merge patch from Justin Forest to speed up pubDate detection
|
|||
* src/gpodder/libpodcasts.py: Merge patch from Justin Forest to speed
|
||||
up the newest_pubdate_downloaded() function by caching its value
|
||||
instead of re-calculating it on every call
|
||||
(Closes: http://bugs.gpodder.org/show_bug.cgi?id=124)
|
||||
|
||||
Fri, 13 Jun 2008 09:37:45 +0200 <thp@perli.net>
|
||||
Merge patch from Nick to add support for deleting played files on sync
|
||||
|
|
|
@ -112,6 +112,7 @@ gPodderSettings = {
|
|||
'maemo_allow_custom_player': (bool, False),
|
||||
'rockbox_copy_coverart' : (bool, False),
|
||||
'rockbox_coverart_size' : (int, 100),
|
||||
'experimental_file_naming': (bool, False),
|
||||
|
||||
# Hide the cover/pill from the podcast sidebar when it gets too small
|
||||
'podcast_sidebar_save_space': (bool, True),
|
||||
|
|
|
@ -721,8 +721,25 @@ class podcastItem(object):
|
|||
log('Cannot delete episode from disk: %s', self.title, traceback=True, sender=self)
|
||||
|
||||
def local_filename( self):
|
||||
extension = util.file_extension_from_url( self.url)
|
||||
return os.path.join( self.channel.save_dir, md5.new( self.url).hexdigest() + extension)
|
||||
ext = util.file_extension_from_url(self.url)
|
||||
|
||||
# For compatibility with already-downloaded episodes,
|
||||
# we accept md5 filenames if they are downloaded now.
|
||||
md5_filename = os.path.join(self.channel.save_dir, md5.new(self.url).hexdigest()+ext)
|
||||
if os.path.exists(md5_filename) or not gl.config.experimental_file_naming:
|
||||
return md5_filename
|
||||
|
||||
# If the md5 filename does not exist,
|
||||
episode = util.file_extension_from_url(self.url, complete_filename=True)
|
||||
episode = util.sanitize_filename(episode)
|
||||
|
||||
# If the episode filename looks suspicious,
|
||||
# we still return the md5 filename to be on
|
||||
# the safe side of the fence ;)
|
||||
if len(episode) == 0 or episode.startswith('redirect.'):
|
||||
return md5_filename
|
||||
filename = os.path.join(self.channel.save_dir, episode)
|
||||
return filename
|
||||
|
||||
def sync_filename( self):
|
||||
if gl.config.custom_sync_name_enabled:
|
||||
|
|
|
@ -431,7 +431,6 @@ class MP3PlayerDevice(Device):
|
|||
|
||||
def __init__(self):
|
||||
Device.__init__(self)
|
||||
self.enc = util.detect_os_encoding()
|
||||
self.destination = gl.config.mp3_player_folder
|
||||
self.buffer_size = 1024*1024 # 1 MiB
|
||||
self.scrobbler_log = []
|
||||
|
@ -495,7 +494,7 @@ class MP3PlayerDevice(Device):
|
|||
self.copy_rockbox_cover_art(folder, from_file)
|
||||
|
||||
if not os.path.exists(to_file):
|
||||
log('Copying %s => %s', os.path.basename(from_file), to_file.decode(self.enc), sender=self)
|
||||
log('Copying %s => %s', os.path.basename(from_file), to_file.decode(util.encoding), sender=self)
|
||||
return self.copy_file_progress(from_file, to_file)
|
||||
|
||||
return True
|
||||
|
|
|
@ -61,6 +61,20 @@ import StringIO
|
|||
import xml.dom.minidom
|
||||
|
||||
|
||||
# Try to detect OS encoding (by Leonid Ponomarev)
|
||||
encoding = 'iso-8859-15'
|
||||
if 'LANG' in os.environ and '.' in os.environ['LANG']:
|
||||
lang = os.environ['LANG']
|
||||
(language, encoding) = lang.rsplit('.', 1)
|
||||
log('Detected encoding: %s', encoding)
|
||||
enc = encoding
|
||||
else:
|
||||
# Using iso-8859-15 here as (hopefully) sane default
|
||||
# see http://en.wikipedia.org/wiki/ISO/IEC_8859-1
|
||||
log('Using ISO-8859-15 as encoding. If this')
|
||||
log('is incorrect, please set your $LANG variable.')
|
||||
|
||||
|
||||
if gpodder.interface == gpodder.GUI:
|
||||
ICON_UNPLAYED = gtk.STOCK_YES
|
||||
ICON_LOCKED = 'emblem-nowrite'
|
||||
|
@ -388,7 +402,7 @@ def torrent_filename( filename):
|
|||
return None
|
||||
|
||||
|
||||
def file_extension_from_url( url):
|
||||
def file_extension_from_url(url, complete_filename=False):
|
||||
"""
|
||||
Extracts the (lowercase) file name extension (with dot)
|
||||
from a URL, e.g. http://server.com/file.MP3?download=yes
|
||||
|
@ -400,16 +414,26 @@ def file_extension_from_url( url):
|
|||
into the query string to find better matches, if the
|
||||
original extension does not resolve to a known type.
|
||||
|
||||
If the optional parameter "complete_filename" is set to
|
||||
True, this will not return the extension, but the
|
||||
complete filename (basename) of the found media file.
|
||||
|
||||
http://my.net/redirect.php?my.net/file.ogg => ".ogg"
|
||||
http://server/get.jsp?file=/episode0815.MOV => ".mov"
|
||||
http://s/redirect.mp4?http://serv2/test.mp4 => ".mp4"
|
||||
"""
|
||||
(scheme, netloc, path, para, query, fragid) = urlparse.urlparse(url)
|
||||
filename = os.path.basename( urllib.unquote(path))
|
||||
(filename, extension) = os.path.splitext(filename)
|
||||
(tmp, extension) = os.path.splitext(filename)
|
||||
|
||||
if file_type_by_extension(extension) is not None:
|
||||
if file_type_by_extension(extension) is not None and not \
|
||||
query.startswith(scheme+'://'):
|
||||
# We have found a valid extension (audio, video, torrent)
|
||||
return extension.lower()
|
||||
# and the query string doesn't look like a URL
|
||||
if complete_filename:
|
||||
return filename
|
||||
else:
|
||||
return extension.lower()
|
||||
|
||||
# If the query string looks like a possible URL, try that first
|
||||
if len(query.strip()) > 0 and query.find('/') != -1:
|
||||
|
@ -417,10 +441,16 @@ def file_extension_from_url( url):
|
|||
query_extension = file_extension_from_url(query_url)
|
||||
|
||||
if file_type_by_extension(query_extension) is not None:
|
||||
return query_extension
|
||||
if complete_filename:
|
||||
return os.path.basename(query_url)
|
||||
else:
|
||||
return query_extension
|
||||
|
||||
# No exact match found, simply return the original extension
|
||||
return extension.lower()
|
||||
if complete_filename:
|
||||
return filename
|
||||
else:
|
||||
return extension.lower()
|
||||
|
||||
|
||||
def file_type_by_extension( extension):
|
||||
|
@ -891,7 +921,7 @@ def gui_open(filename):
|
|||
# FIXME: Win32-specific "open" code needed here
|
||||
# as fallback when xdg-open not available
|
||||
except:
|
||||
log('Cannot open file/folder: "%s"', folder, sender=self, traceback=True)
|
||||
log('Cannot open file/folder: "%s"', filename, sender=self, traceback=True)
|
||||
|
||||
|
||||
def open_website(url):
|
||||
|
@ -902,20 +932,6 @@ def open_website(url):
|
|||
"""
|
||||
threading.Thread(target=webbrowser.open, args=(url,)).start()
|
||||
|
||||
def detect_os_encoding():
|
||||
# Try to detect OS encoding (by Leonid Ponomarev)
|
||||
if 'LANG' in os.environ and '.' in os.environ['LANG']:
|
||||
lang = os.environ['LANG']
|
||||
(language, encoding) = lang.rsplit('.', 1)
|
||||
log('Detected encoding: %s', encoding)
|
||||
enc = encoding
|
||||
else:
|
||||
# Using iso-8859-15 here as (hopefully) sane default
|
||||
# see http://en.wikipedia.org/wiki/ISO/IEC_8859-1
|
||||
log('Using ISO-8859-15 as encoding. If this')
|
||||
log('is incorrect, please set your $LANG variable.')
|
||||
enc = 'iso-8859-15'
|
||||
return enc
|
||||
|
||||
def sanitize_filename(filename, max_length=0):
|
||||
"""
|
||||
|
@ -928,7 +944,8 @@ def sanitize_filename(filename, max_length=0):
|
|||
log('Limiting file/folder name "%s" to %d characters.', filename, max_length, sender=self)
|
||||
filename = filename[:max_length]
|
||||
|
||||
return re.sub('[/|?*<>:+\[\]\"\\\]', '_', filename.strip().encode(detect_os_encoding(), 'ignore'))
|
||||
global encoding
|
||||
return re.sub('[/|?*<>:+\[\]\"\\\]', '_', filename.strip().encode(encoding, 'ignore'))
|
||||
|
||||
|
||||
def find_mount_point(directory):
|
||||
|
|
Loading…
Reference in a new issue