/* * Copyright (C) 2009 Jens Georg . * Copyright (C) 2010 Nokia Corporation. * * Authors: Jens Georg * Zeeshan Ali (Khattak) * * * 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. */ using Gee; internal class Rygel.HTTPItemURI : Object { public string item_id; public int thumbnail_index; public int subtitle_index; public string? transcode_target; public unowned HTTPServer http_server; private string real_extension; public string extension { owned get { if (this.real_extension != "") { return "." + this.real_extension; } return ""; } set { this.real_extension = value; } } public static HashMap mime_to_ext; public HTTPItemURI (MediaItem item, HTTPServer http_server, int thumbnail_index = -1, int subtitle_index = -1, string? transcode_target = null) { this.item_id = item.id; this.thumbnail_index = thumbnail_index; this.subtitle_index = subtitle_index; this.transcode_target = transcode_target; this.http_server = http_server; this.extension = ""; if (thumbnail_index > -1) { if (item is VisualItem) { var thumbnails = (item as VisualItem).thumbnails; if (thumbnails.size > thumbnail_index) { this.extension = thumbnails[thumbnail_index].file_extension; } } else if (item is MusicItem) { var album_art = (item as MusicItem).album_art; if (album_art != null) { this.extension = album_art.file_extension; } } } else if (subtitle_index > -1) { if (item is VideoItem) { var subtitles = (item as VideoItem).subtitles; if (subtitles.size > subtitle_index) { this.extension = subtitles[subtitle_index].caption_type; } } } else if (transcode_target != null) { try { var tc = this.http_server.get_transcoder (transcode_target); this.extension = tc.extension; } catch (Error error) {} } if (this.extension == "") { string uri_extension = ""; foreach (string uri_string in item.uris) { string basename = Path.get_basename (uri_string); int dot_index = basename.last_index_of("."); if (dot_index > -1) { uri_extension = basename.substring (dot_index + 1); break; } } if (uri_extension == "") { this.extension = this.ext_from_mime_type (item.mime_type); } else { this.extension = uri_extension; } } } public HTTPItemURI.from_string (string uri, HTTPServer http_server) throws HTTPRequestError { // do not decode the path here as it may contain encoded slashes this.thumbnail_index = -1; this.subtitle_index = -1; this.transcode_target = null; this.http_server = http_server; this.extension = ""; var request_uri = uri.replace (http_server.path_root, ""); var parts = request_uri.split ("/"); if (parts.length < 2 || parts.length % 2 == 0) { throw new HTTPRequestError.BAD_REQUEST (_("Invalid URI '%s'"), request_uri); } string last_part = parts[parts.length - 1]; int dot_index = last_part.last_index_of ("."); if (dot_index > -1) { this.extension = last_part.substring (dot_index + 1); parts[parts.length - 1] = last_part.substring (0, dot_index); } for (int i = 1; i < parts.length - 1; i += 2) { switch (parts[i]) { case "i": var data = Base64.decode (Soup.URI.decode (parts[i + 1])); StringBuilder builder = new StringBuilder (); builder.append ((string) data); this.item_id = builder.str; break; case "tr": this.transcode_target = Soup.URI.decode (parts[i + 1]); break; case "th": this.thumbnail_index = int.parse (parts[i + 1]); break; case "sub": this.subtitle_index = int.parse (parts[i + 1]); break; default: break; } } if (this.item_id == null) { throw new HTTPRequestError.NOT_FOUND (_("Not Found")); } } public string to_string() { // there seems to be a problem converting strings properly to arrays // you need to call to_utf8() and assign it to a variable to make it // work properly var data = this.item_id.to_utf8 (); var escaped = Uri.escape_string (Base64.encode ((uchar[]) data), "", true); string path = "/i/" + escaped; if (this.transcode_target != null) { escaped = Uri.escape_string (this.transcode_target, "", true); path += "/tr/" + escaped; } else if (this.thumbnail_index >= 0) { path += "/th/" + this.thumbnail_index.to_string (); } else if (this.subtitle_index >= 0) { path += "/sub/" + this.subtitle_index.to_string (); } path += this.extension; return this.create_uri_for_path (path); } private string create_uri_for_path (string path) { return "http://%s:%u%s%s".printf (this.http_server.context.host_ip, this.http_server.context.port, this.http_server.path_root, path); } private string ext_from_mime_type (string mime_type) { if (mime_to_ext == null) { mime_to_ext = new HashMap (); // videos string[] videos = {"mpeg", "webm", "ogg"}; foreach (string video in videos) { mime_to_ext.set ("video/" + video, video); } mime_to_ext.set ("video/x-matroska", "mkv"); // audios mime_to_ext.set ("audio/x-wav", "wav"); mime_to_ext.set ("audio/x-matroska", "mka"); // images string[] images = {"jpeg", "png"}; foreach (string image in images) { mime_to_ext.set ("image/" + image, image); } // texts mime_to_ext.set ("text/srt", "srt"); // applications? (can be either video or audio?); mime_to_ext.set ("application/ogg", "ogg"); } if (HTTPItemURI.mime_to_ext.has_key (mime_type)) { return mime_to_ext.get (mime_type); } return ""; } }