diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/plugins/media-export/Makefile.am | 3 | ||||
-rw-r--r-- | src/plugins/media-export/rygel-media-export-dvd-parser.vala | 89 | ||||
-rw-r--r-- | src/plugins/media-export/rygel-media-export-extract.vala | 19 | ||||
-rw-r--r-- | src/plugins/media-export/rygel-media-export-harvester.vala | 4 | ||||
-rw-r--r-- | src/plugins/media-export/rygel-media-export-info-serializer.vala | 2 |
6 files changed, 109 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac index c71a7017..89557c35 100644 --- a/configure.ac +++ b/configure.ac @@ -260,6 +260,7 @@ AS_IF([test "x$with_media_engine" = "xgstreamer"], gstreamer-pbutils-1.0 >= $GSTPBU_REQUIRED libsoup-2.4 >= $LIBSOUP_REQUIRED sqlite3 >= $LIBSQLITE3_REQUIRED + libxml-2.0 >= $LIBXML_REQUIRED libmediaart-2.0 >= $MEDIAART_REQUIRED]) RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gupnp-dlna-2.0 --pkg gupnp-dlna-gst-2.0 --pkg gstreamer-tag-1.0 --pkg gstreamer-app-1.0 --pkg gstreamer-pbutils-1.0 --pkg sqlite3 --pkg libmediaart-2.0" AC_SUBST([RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS]) diff --git a/src/plugins/media-export/Makefile.am b/src/plugins/media-export/Makefile.am index f77fa8a2..37c720eb 100644 --- a/src/plugins/media-export/Makefile.am +++ b/src/plugins/media-export/Makefile.am @@ -10,7 +10,8 @@ include $(top_srcdir)/common.am pkglibexec_PROGRAMS = mx-extract mx_extract_SOURCES = \ rygel-media-export-extract.vala \ - rygel-media-export-info-serializer.vala + rygel-media-export-info-serializer.vala \ + rygel-media-export-dvd-parser.vala mx_extract_VALAFLAGS = \ --enable-experimental \ diff --git a/src/plugins/media-export/rygel-media-export-dvd-parser.vala b/src/plugins/media-export/rygel-media-export-dvd-parser.vala new file mode 100644 index 00000000..522c9cd3 --- /dev/null +++ b/src/plugins/media-export/rygel-media-export-dvd-parser.vala @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2013,2015 Jens Georg <mail@jensge.org>. + * + * Author: Jens Georg <mail@jensge.org> + * + * This file is part of Rygel. + * + * Rygel is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rygel is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +internal errordomain DVDParserError { + GENERAL; +} + +internal class Rygel.DVDParser : GLib.Object { + /// URI to the image / toplevel directory + public File file { public get; construct; } + + private File cache_file; + private string id; + + public DVDParser (File file) { + Object (file : file); + } + + public override void constructed () { + unowned string user_cache = Environment.get_user_cache_dir (); + this.id = this.get_id (this.file); + var cache_folder = Path.build_filename (user_cache, + "rygel", + "dvd-content"); + DirUtils.create_with_parents (cache_folder, 0700); + var cache_path = Path.build_filename (cache_folder, this.id); + + this.cache_file = File.new_for_path (cache_path); + } + + public async void run () throws Error { + var doc = yield this.get_information (); + if (doc != null) { + doc->children; + } + } + + public async Xml.Doc* get_information () throws Error { + if (!this.cache_file.query_exists ()) { + var launcher = new SubprocessLauncher (SubprocessFlags.STDERR_SILENCE); + launcher.set_stdout_file_path (this.cache_file.get_path ()); + string[] args = { + "/usr/bin/lsdvd", + "-Ox", + "-x", + "-q", + this.file.get_path (), + null + }; + + var process = launcher.spawnv (args); + yield process.wait_async (); + + if (!(process.get_if_exited () && + process.get_exit_status () == 0)) { + throw new DVDParserError.GENERAL ("lsdvd did die or file is not a DVD"); + } + } + + return Xml.Parser.read_file (this.cache_file.get_path (), + null, + Xml.ParserOption.NOERROR | + Xml.ParserOption.NOWARNING); + } + + private string get_id (File file) { + return Checksum.compute_for_string (ChecksumType.MD5, + file.get_uri ()); + } +} diff --git a/src/plugins/media-export/rygel-media-export-extract.vala b/src/plugins/media-export/rygel-media-export-extract.vala index 2022a347..0410bac5 100644 --- a/src/plugins/media-export/rygel-media-export-extract.vala +++ b/src/plugins/media-export/rygel-media-export-extract.vala @@ -33,6 +33,7 @@ const string UPNP_CLASS_PHOTO = "object.item.imageItem.photo"; const string UPNP_CLASS_MUSIC = "object.item.audioItem.musicTrack"; const string UPNP_CLASS_VIDEO = "object.item.videoItem"; const string UPNP_CLASS_PLAYLIST = "object.item.playlistItem"; +const string UPNP_CLASS_PLAYLIST_CONTAINER = "object.container.playlistContainer"; const string STATUS_LINE_TEMPLATE = "RESULT|%s|%" + size_t.FORMAT + "|%s\n"; const string ERROR_LINE_TEMPLATE = "ERROR|%s|%d|%s\n"; @@ -101,12 +102,18 @@ async void run () { GLib.Memory.copy (last_uri.data, (void *) parts[0], parts[0].length); - var is_text = parts[1].has_prefix ("text/") || - parts[1].has_suffix ("xml"); - if (metadata && !is_text) { - info = discoverer.discover_uri (parts[0]); - - debug ("Finished discover on URI %s", parts[0]); + if (metadata) { + var is_text = parts[1].has_prefix ("text/") || + parts[1].has_suffix ("xml"); + if (parts[1] == "application/x-cd-image") { + var file = File.new_for_uri (parts[0]); + var parser = new Rygel.DVDParser (file); + yield parser.run (); + } else if (!is_text) { + info = discoverer.discover_uri (parts[0]); + + debug ("Finished discover on URI %s", parts[0]); + } } yield process_meta_data (parts[0], info); } catch (Error error) { diff --git a/src/plugins/media-export/rygel-media-export-harvester.vala b/src/plugins/media-export/rygel-media-export-harvester.vala index f7107f0a..a4f20d49 100644 --- a/src/plugins/media-export/rygel-media-export-harvester.vala +++ b/src/plugins/media-export/rygel-media-export-harvester.vala @@ -74,8 +74,8 @@ internal class Rygel.MediaExport.Harvester : GLib.Object { info.get_content_type () == "application/ogg" || info.get_content_type () == "application/xml" || info.get_content_type () == "text/xml" || - info.get_content_type () == "text/plain"; - + info.get_content_type () == "text/plain" || + info.get_content_type () == "application/x-cd-image"; var cache = MediaCache.get_default (); var is_blacklisted = cache.is_blacklisted (file); diff --git a/src/plugins/media-export/rygel-media-export-info-serializer.vala b/src/plugins/media-export/rygel-media-export-info-serializer.vala index 796086f4..b24a556e 100644 --- a/src/plugins/media-export/rygel-media-export-info-serializer.vala +++ b/src/plugins/media-export/rygel-media-export-info-serializer.vala @@ -87,6 +87,8 @@ internal class Rygel.InfoSerializer : GLib.Object { upnp_class = UPNP_CLASS_MUSIC; } else if (mime.has_suffix ("/xml")) { // application/xml or text/xml upnp_class = UPNP_CLASS_PLAYLIST; + } else if (mime == "application/x-cd-image") { + upnp_class = UPNP_CLASS_PLAYLIST_CONTAINER; } else { debug ("Unsupported content-type %s, skipping %s…", mime, |