summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntti Ajanki <antti.ajanki@iki.fi>2011-03-26 17:35:41 +0200
committerAntti Ajanki <antti.ajanki@iki.fi>2011-03-26 17:35:41 +0200
commitbf656b5de4cf87badfcdfeb5e1923466ccce2ed1 (patch)
treeda058f248faecd9086e4c4aff8fb2a6c6f034ade
parent3dc970ba835f29895fa52af809c33d9eb8969dde (diff)
downloadvdr-plugin-webvideo-bf656b5de4cf87badfcdfeb5e1923466ccce2ed1.tar.gz
vdr-plugin-webvideo-bf656b5de4cf87badfcdfeb5e1923466ccce2ed1.tar.bz2
--vfat parameter (plugin, webvi)
-rw-r--r--src/unittest/testwebvi.py2
-rw-r--r--src/vdr-plugin/common.c15
-rw-r--r--src/vdr-plugin/common.h10
-rw-r--r--src/vdr-plugin/config.c10
-rw-r--r--src/vdr-plugin/config.h4
-rw-r--r--src/vdr-plugin/request.c2
-rw-r--r--src/vdr-plugin/webvideo.c11
-rw-r--r--src/webvicli/webvicli/client.py30
8 files changed, 68 insertions, 16 deletions
diff --git a/src/unittest/testwebvi.py b/src/unittest/testwebvi.py
index 3257046..34452e2 100644
--- a/src/unittest/testwebvi.py
+++ b/src/unittest/testwebvi.py
@@ -44,7 +44,7 @@ class TestServiceModules(unittest.TestCase):
def setUp(self):
webvi.api.set_config(WebviConfig.TEMPLATE_PATH, '../../templates')
- self.client = client.WVClient([], {}, {})
+ self.client = client.WVClient([], {}, {}, False)
def getLinks(self, menuobj):
links = []
diff --git a/src/vdr-plugin/common.c b/src/vdr-plugin/common.c
index 5ad2747..17a73b0 100644
--- a/src/vdr-plugin/common.c
+++ b/src/vdr-plugin/common.c
@@ -194,9 +194,20 @@ char *URLdecode(const char *s) {
return res;
}
-char *safeFilename(char *filename) {
+char *safeFilename(char *filename, bool vfatnames) {
if (filename) {
- strreplace(filename, '/', '!');
+ strreplace(filename, '/', '_');
+
+ if (vfatnames) {
+ strreplace(filename, '\\', '_');
+ strreplace(filename, '"', '_');
+ strreplace(filename, '*', '_');
+ strreplace(filename, ':', '_');
+ strreplace(filename, '<', '_');
+ strreplace(filename, '>', '_');
+ strreplace(filename, '?', '_');
+ strreplace(filename, '|', '_');
+ }
char *p = filename;
while ((*p == '.') || isspace(*p)) {
diff --git a/src/vdr-plugin/common.h b/src/vdr-plugin/common.h
index 90dfb5f..8443081 100644
--- a/src/vdr-plugin/common.h
+++ b/src/vdr-plugin/common.h
@@ -36,10 +36,12 @@ char *URLencode(const char *s);
// Remove URL encoding from s. The called must free the returned
// memory.
char *URLdecode(const char *s);
-// Return a "safe" version of filename. Remove path (replace '/' with
-// '!') and dots from the beginning. The string is modified in-place,
-// i.e. returns the pointer filename that was passed as argument.
-char *safeFilename(char *filename);
+// Return a "safe" version of filename. Replace '/' with '_' and
+// remove dots from the beginning. If vfatnames is true, replace also
+// other characters which are not allowed on VFAT. The string is
+// modified in-place, i.e. returns the pointer filename that was
+// passed as argument.
+char *safeFilename(char *filename, bool vfatnames);
// Escape s so that it can be passed as parameter to a shell command.
cString shellEscape(const char *s);
// Convert string s to lower case
diff --git a/src/vdr-plugin/config.c b/src/vdr-plugin/config.c
index 81bdb3e..8bc3fde 100644
--- a/src/vdr-plugin/config.c
+++ b/src/vdr-plugin/config.c
@@ -64,6 +64,7 @@ cWebvideoConfig::cWebvideoConfig() {
templatePath = NULL;
preferXine = true;
postProcessCmd = NULL;
+ vfatNames = false;
}
cWebvideoConfig::~cWebvideoConfig() {
@@ -216,3 +217,12 @@ void cWebvideoConfig::SetPostProcessCmd(const char *cmd) {
const char *cWebvideoConfig::GetPostProcessCmd() {
return postProcessCmd;
}
+
+void cWebvideoConfig::SetUseVFATNames(bool vfat) {
+ vfatNames = vfat;
+}
+
+bool cWebvideoConfig::GetUseVFATNames() {
+ return vfatNames;
+}
+
diff --git a/src/vdr-plugin/config.h b/src/vdr-plugin/config.h
index fd541b3..ccda574 100644
--- a/src/vdr-plugin/config.h
+++ b/src/vdr-plugin/config.h
@@ -36,6 +36,7 @@ private:
char *templatePath;
char *postProcessCmd;
bool preferXine;
+ bool vfatNames;
cList<cDownloadQuality> downloadLimits;
cList<cDownloadQuality> streamLimits;
@@ -56,6 +57,9 @@ public:
void SetPreferXineliboutput(bool pref);
bool GetPreferXineliboutput();
+ void SetUseVFATNames(bool vfat);
+ bool GetUseVFATNames();
+
const char *GetMinQuality(const char *site, eRequestType type);
const char *GetMaxQuality(const char *site, eRequestType type);
diff --git a/src/vdr-plugin/request.c b/src/vdr-plugin/request.c
index 00297f7..0d1abf1 100644
--- a/src/vdr-plugin/request.c
+++ b/src/vdr-plugin/request.c
@@ -320,7 +320,7 @@ bool cFileDownloadRequest::OpenDestFile() {
const char *destdir = webvideoConfig->GetDownloadPath();
char *basename = strdup(title ? title : "???");
- basename = safeFilename(basename);
+ basename = safeFilename(basename, webvideoConfig->GetUseVFATNames());
i = 1;
filename = cString::sprintf("%s/%s%s", destdir, basename, ext);
diff --git a/src/vdr-plugin/webvideo.c b/src/vdr-plugin/webvideo.c
index 02f007a..0f985fc 100644
--- a/src/vdr-plugin/webvideo.c
+++ b/src/vdr-plugin/webvideo.c
@@ -39,6 +39,7 @@ private:
cString conffile;
cString postprocesscmd;
bool prefermplayer;
+ bool vfatnames;
static int nextMenuID;
@@ -79,6 +80,7 @@ cPluginWebvideo::cPluginWebvideo(void)
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
prefermplayer = false;
+ vfatnames = false;
}
cPluginWebvideo::~cPluginWebvideo()
@@ -94,6 +96,7 @@ const char *cPluginWebvideo::CommandLineHelp(void)
" -t DIR, --templatedir=DIR Read video site templates from DIR\n" \
" -c FILE, --conf=FILE Load settings from FILE\n" \
" -p CMD, --postprocess=CMD Execute CMD after downloading\n" \
+ " --vfat Generate Windows compatible filenames\n" \
" -m, --prefermplayer Prefer mplayer over xineliboutput when streaming\n";
}
@@ -106,11 +109,12 @@ bool cPluginWebvideo::ProcessArgs(int argc, char *argv[])
{ "conf", required_argument, NULL, 'c' },
{ "postprocess", required_argument, NULL, 'p' },
{ "prefermplayer", no_argument, NULL, 'm' },
+ { "vfat", no_argument, NULL, 'v' },
{ NULL }
};
int c;
- while ((c = getopt_long(argc, argv, "d:t:c:p:m", long_options, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "d:t:c:p:mv", long_options, NULL)) != -1) {
switch (c) {
case 'd':
destdir = cString(optarg);
@@ -127,6 +131,9 @@ bool cPluginWebvideo::ProcessArgs(int argc, char *argv[])
case 'm':
prefermplayer = true;
break;
+ case 'v':
+ vfatnames = true;
+ break;
default:
return false;
}
@@ -157,6 +164,8 @@ bool cPluginWebvideo::Initialize(void)
webvideoConfig->SetPostProcessCmd(postprocesscmd);
if (prefermplayer)
webvideoConfig->SetPreferXineliboutput(false);
+ if (vfatnames)
+ webvideoConfig->SetUseVFATNames(vfatnames);
cString mymimetypes = AddDirectory(ConfigDirectory(Name()), "mime.types");
const char *mimefiles [] = {"/etc/mime.types", (const char *)mymimetypes, NULL};
diff --git a/src/webvicli/webvicli/client.py b/src/webvicli/webvicli/client.py
index 6f40a2e..a8fd6d7 100644
--- a/src/webvicli/webvicli/client.py
+++ b/src/webvicli/webvicli/client.py
@@ -49,11 +49,19 @@ mimetypes.init()
mimetypes.add_type('video/flv', '.flv')
mimetypes.add_type('video/x-flv', '.flv')
-def safe_filename(name):
- """Sanitize a filename. No paths (replace '/' -> '!') and no
- names starting with a dot."""
- res = name.replace('/', '!').lstrip('.')
+def safe_filename(name, vfat):
+ """Sanitize a filename. If vfat is False, replace '/' with '_', if
+ vfat is True, replace also other characters that are illegal on
+ VFAT. Remove dots from the beginning of the filename."""
+ if vfat:
+ excludechars = r'[\\"*/:<>?|]'
+ else:
+ excludechars = r'[/]'
+
+ res = re.sub(excludechars, '_', name)
+ res = res.lstrip('.')
res = res.encode(sys.getfilesystemencoding(), 'ignore')
+
return res
class DownloadData:
@@ -173,12 +181,13 @@ class ProgressMeter:
class WVClient:
- def __init__(self, streamplayers, downloadlimits, streamlimits):
+ def __init__(self, streamplayers, downloadlimits, streamlimits, vfatfilenames):
self.streamplayers = streamplayers
self.history = []
self.history_pointer = 0
self.quality_limits = {'download': downloadlimits,
'stream': streamlimits}
+ self.vfatfilenames = vfatfilenames
def parse_page(self, page):
if page is None:
@@ -335,7 +344,9 @@ class WVClient:
contentlength = webvi.api.get_info(dldata.handle, WebviInfo.CONTENT_LENGTH)[1]
url = webvi.api.get_info(dldata.handle, WebviInfo.URL)[1]
ext = self.guess_extension(contenttype, url)
- destfilename = self.next_available_file_name(safe_filename(title), ext)
+
+ safename = safe_filename(title, self.vfatfilenames)
+ destfilename = self.next_available_file_name(safename, ext)
try:
destfile = open(destfilename, 'w')
@@ -721,12 +732,16 @@ def parse_command_line(cmdlineargs, options):
default=None)
parser.add_option('-v', '--verbose', action='store_const', const=1,
dest='verbose', help='debug output', default=0)
+ parser.add_option('--vfat', action='store_true',
+ dest='vfat', default=False,
+ help='generate Windows compatible filenames')
cmdlineopt = parser.parse_args(cmdlineargs)[0]
if cmdlineopt.templatepath is not None:
options['templatepath'] = cmdlineopt.templatepath
if cmdlineopt.verbose > 0:
options['verbose'] = cmdlineopt.verbose
+ options['vfat'] = cmdlineopt.vfat
return options
@@ -764,7 +779,8 @@ def main(argv):
shell = WVShell(WVClient(player_list(options),
options.get('download-limits', {}),
- options.get('stream-limits', {})))
+ options.get('stream-limits', {}),
+ options.get('vfat', False)))
shell.cmdloop()
if __name__ == '__main__':