~walkerlee/totem/pre-interview

« back to all changes in this revision

Viewing changes to src/plugins/autoload-subtitles/totem-autoload-subtitles.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-05-26 00:07:51 UTC
  • mfrom: (1.6.1) (24.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20130526000751-kv8ap3x1di4qq8j2
Tags: 3.8.2-0ubuntu1
* Sync with Debian. Remaining changes: 
* debian/control.in:
  - Drop build-depends on libepc-ui-dev and libgrilo-0.2-dev (in universe)
  - Drop libxtst-dev build-depends so that the (redundant) fake key presses
    for inhibiting the screensaver are disabled (LP: #1007438)
  - Build-depend on libzeitgeist-dev
  - Suggest rather than recommend gstreamer components in universe
  - Add totem-plugins-extra
  - Add XB-Npp-Description and XB-Npp-Filename header to the 
    totem-mozilla package to improve ubufox/ubuntu plugin db integration 
  - Refer to Firefox in totem-mozilla description instead of Iceweasel
  - Don't have totem-mozilla recommend any particular browser
  - Drop obsolete python library dependencies since iplayer is no longer
    included
* debian/totem-common.install, debian/source_totem.py:
  - Install Ubuntu apport debugging hook
* debian/totem-plugins-extra.install:
  - Universe plugins split out of totem-plugins (currently only gromit)
* debian/totem-plugins.install:    
  - Skip the plugins split to -extra and add the zeitgeist plugin
* debian/rules:
  - Build with --fail-missing, to ensure we install everything. 
    + Ignore libtotem.{,l}a since we delibrately don't install these.
  - Re-enable hardening, make sure both PIE and BINDNOW are used
    by setting hardening=+all. (LP: #1039604)
* debian/patches/91_quicklist_entries.patch:
  - Add static quicklist
* debian/patches/92_gst-plugins-good.patch:
  - Build without unnecessary gstreamer1.0-bad dependency
* debian/patches/93_grilo_optional.patch:
  - Allow building without grilo while grilo MIR is still pending
* debian/patches/correct_desktop_mimetypes.patch:
  - Don't list the mimetypes after the unity lists
* debian/patches/revert_shell_menu.patch: 
  - revert the use of a shell menu until indicator-appmenu can handle
    the mixed shell/traditional menus itself
* New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2012 Bastien Nocera <hadess@hadess.net>
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 
17
 *
 
18
 *
 
19
 * The Totem project hereby grant permission for non-gpl compatible GStreamer
 
20
 * plugins to be used and distributed together with GStreamer and Totem. This
 
21
 * permission are above and beyond the permissions granted by the GPL license
 
22
 * Totem is covered by.
 
23
 *
 
24
 * Monday 7th February 2005: Christian Schaller: Add exception clause.
 
25
 * See license_change file for details.
 
26
 *
 
27
 */
 
28
 
 
29
 
 
30
#include "config.h"
 
31
 
 
32
#include <glib-object.h>
 
33
#include <string.h>
 
34
 
 
35
#include "totem-plugin.h"
 
36
#include "totem.h"
 
37
 
 
38
#define TOTEM_TYPE_AUTOLOAD_SUBTITLES_PLUGIN    (totem_autoload_subtitles_plugin_get_type ())
 
39
#define TOTEM_AUTOLOAD_SUBTITLES_PLUGIN(o)              (G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_AUTOLOAD_SUBTITLES_PLUGIN, TotemAutoloadSubtitlesPlugin))
 
40
 
 
41
typedef struct {
 
42
        guint signal_id;
 
43
        TotemObject *totem;
 
44
        GSettings *settings;
 
45
        gboolean autoload_subs;
 
46
} TotemAutoloadSubtitlesPluginPrivate;
 
47
 
 
48
TOTEM_PLUGIN_REGISTER(TOTEM_TYPE_AUTOLOAD_SUBTITLES_PLUGIN, TotemAutoloadSubtitlesPlugin, totem_autoload_subtitles_plugin)
 
49
 
 
50
/* List from xine-lib's demux_sputext.c.
 
51
 * Keep in sync with the list in totem_setup_file_filters() in this file.
 
52
 * Don't add .txt extensions, as there are too many false positives. */
 
53
static const char subtitle_ext[][4] = {
 
54
        "sub",
 
55
        "srt",
 
56
        "smi",
 
57
        "ssa",
 
58
        "ass",
 
59
        "asc"
 
60
};
 
61
 
 
62
static gboolean
 
63
totem_uri_exists (const char *uri)
 
64
{
 
65
        GFile *file = g_file_new_for_uri (uri);
 
66
        if (file != NULL) {
 
67
                if (g_file_query_exists (file, NULL)) {
 
68
                        g_object_unref (file);
 
69
                        return TRUE;
 
70
                }
 
71
                g_object_unref (file);
 
72
        }
 
73
        return FALSE;
 
74
}
 
75
 
 
76
static char *
 
77
totem_uri_get_subtitle_for_uri (const char *uri)
 
78
{
 
79
        char *subtitle;
 
80
        guint len, i;
 
81
        gint suffix;
 
82
 
 
83
        g_return_val_if_fail (uri != NULL, NULL);
 
84
 
 
85
        /* Find the filename suffix delimiter */
 
86
        len = strlen (uri);
 
87
        for (suffix = len - 1; suffix > 0; suffix--) {
 
88
                if (uri[suffix] == G_DIR_SEPARATOR ||
 
89
                    (uri[suffix] == '/')) {
 
90
                        /* This filename has no extension; we'll need to add one */
 
91
                        suffix = len;
 
92
                        break;
 
93
                }
 
94
                if (uri[suffix] == '.') {
 
95
                        /* Found our extension marker */
 
96
                        break;
 
97
                }
 
98
        }
 
99
        if (suffix < 0)
 
100
                return NULL;
 
101
 
 
102
        /* Generate a subtitle string with room at the end to store the
 
103
         * 3 character extensions for which we want to search */
 
104
        subtitle = g_malloc0 (suffix + 4 + 1);
 
105
        g_return_val_if_fail (subtitle != NULL, NULL);
 
106
        g_strlcpy (subtitle, uri, suffix + 4 + 1);
 
107
        g_strlcpy (subtitle + suffix, ".???", 5);
 
108
 
 
109
        /* Search for any files with one of our known subtitle extensions */
 
110
        for (i = 0; i < G_N_ELEMENTS (subtitle_ext) ; i++) {
 
111
                char *subtitle_ext_upper;
 
112
                memcpy (subtitle + suffix + 1, subtitle_ext[i], 3);
 
113
 
 
114
                if (totem_uri_exists (subtitle))
 
115
                        return subtitle;
 
116
 
 
117
                /* Check with upper-cased extension */
 
118
                subtitle_ext_upper = g_ascii_strup (subtitle_ext[i], -1);
 
119
                memcpy (subtitle + suffix + 1, subtitle_ext_upper, 3);
 
120
                g_free (subtitle_ext_upper);
 
121
 
 
122
                if (totem_uri_exists (subtitle))
 
123
                        return subtitle;
 
124
        }
 
125
        g_free (subtitle);
 
126
        return NULL;
 
127
}
 
128
 
 
129
static char *
 
130
totem_uri_get_subtitle_in_subdir (GFile *file, const char *subdir)
 
131
{
 
132
        char *filename, *subtitle, *full_path_str;
 
133
        GFile *parent, *full_path, *directory;
 
134
 
 
135
        /* Get the sibling directory @subdir of the file @file */
 
136
        parent = g_file_get_parent (file);
 
137
        directory = g_file_get_child (parent, subdir);
 
138
        g_object_unref (parent);
 
139
 
 
140
        /* Get the file of the same name as @file in the @subdir directory */
 
141
        filename = g_file_get_basename (file);
 
142
        full_path = g_file_get_child (directory, filename);
 
143
        g_object_unref (directory);
 
144
        g_free (filename);
 
145
 
 
146
        /* Get the subtitles from that URI */
 
147
        full_path_str = g_file_get_uri (full_path);
 
148
        g_object_unref (full_path);
 
149
        subtitle = totem_uri_get_subtitle_for_uri (full_path_str);
 
150
        g_free (full_path_str);
 
151
 
 
152
        return subtitle;
 
153
}
 
154
 
 
155
static char *
 
156
totem_uri_get_cached_subtitle_for_uri (const char *uri)
 
157
{
 
158
        char *filename, *basename, *fake_filename, *fake_uri, *ret;
 
159
 
 
160
        filename = g_filename_from_uri (uri, NULL, NULL);
 
161
        if (filename == NULL)
 
162
                return NULL;
 
163
 
 
164
        basename = g_path_get_basename (filename);
 
165
        g_free (filename);
 
166
        if (basename == NULL || strcmp (basename, ".") == 0) {
 
167
                g_free (basename);
 
168
                return NULL;
 
169
        }
 
170
 
 
171
        fake_filename = g_build_filename (g_get_user_cache_dir (),
 
172
                                "totem",
 
173
                                "subtitles",
 
174
                                basename,
 
175
                                NULL);
 
176
        g_free (basename);
 
177
        fake_uri = g_filename_to_uri (fake_filename, NULL, NULL);
 
178
        g_free (fake_filename);
 
179
 
 
180
        ret = totem_uri_get_subtitle_for_uri (fake_uri);
 
181
        g_free (fake_uri);
 
182
 
 
183
        return ret;
 
184
}
 
185
 
 
186
static char *
 
187
totem_uri_get_subtitle_uri (const char *uri)
 
188
{
 
189
        GFile *file;
 
190
        char *subtitle;
 
191
 
 
192
        if (g_str_has_prefix (uri, "http") != FALSE ||
 
193
            g_str_has_prefix (uri, "rtsp") != FALSE ||
 
194
            g_str_has_prefix (uri, "rtmp") != FALSE)
 
195
                return NULL;
 
196
 
 
197
        /* Has the user specified a subtitle file manually? */
 
198
        if (strstr (uri, "#subtitle:") != NULL)
 
199
                return NULL;
 
200
 
 
201
        /* Does the file exist? */
 
202
        file = g_file_new_for_uri (uri);
 
203
        if (g_file_query_exists (file, NULL) != TRUE) {
 
204
                g_object_unref (file);
 
205
                return NULL;
 
206
        }
 
207
 
 
208
        /* Try in the cached subtitles directory */
 
209
        subtitle = totem_uri_get_cached_subtitle_for_uri (uri);
 
210
        if (subtitle != NULL) {
 
211
                g_object_unref (file);
 
212
                return subtitle;
 
213
        }
 
214
 
 
215
        /* Try in the current directory */
 
216
        subtitle = totem_uri_get_subtitle_for_uri (uri);
 
217
        if (subtitle != NULL) {
 
218
                g_object_unref (file);
 
219
                return subtitle;
 
220
        }
 
221
 
 
222
        subtitle = totem_uri_get_subtitle_in_subdir (file, "subtitles");
 
223
        g_object_unref (file);
 
224
 
 
225
        return subtitle;
 
226
}
 
227
 
 
228
 
 
229
 
 
230
static char *
 
231
get_text_subtitle_cb (TotemObject                  *totem,
 
232
                      const char                   *mrl,
 
233
                      TotemAutoloadSubtitlesPlugin *pi)
 
234
{
 
235
        char *sub;
 
236
 
 
237
        if (pi->priv->autoload_subs == FALSE)
 
238
                return NULL;
 
239
 
 
240
        sub = totem_uri_get_subtitle_uri (mrl);
 
241
 
 
242
        return sub;
 
243
}
 
244
 
 
245
static void
 
246
autoload_subs_changed (GSettings                *settings,
 
247
                       char                     *key,
 
248
                       TotemAutoloadSubtitlesPlugin *pi)
 
249
{
 
250
        pi->priv->autoload_subs = g_settings_get_boolean (settings, "autoload-subtitles");
 
251
}
 
252
 
 
253
static void
 
254
impl_activate (PeasActivatable *plugin)
 
255
{
 
256
        TotemAutoloadSubtitlesPlugin *pi = TOTEM_AUTOLOAD_SUBTITLES_PLUGIN (plugin);
 
257
 
 
258
        pi->priv->totem = g_object_ref (g_object_get_data (G_OBJECT (plugin), "object"));
 
259
        pi->priv->settings = g_settings_new ("org.gnome.totem");
 
260
        pi->priv->autoload_subs = g_settings_get_boolean (pi->priv->settings, "autoload-subtitles");
 
261
        g_signal_connect (pi->priv->settings, "changed::autoload-subtitles",
 
262
                          G_CALLBACK (autoload_subs_changed), pi);
 
263
        pi->priv->signal_id = g_signal_connect (G_OBJECT (pi->priv->totem), "get-text-subtitle",
 
264
                                                G_CALLBACK (get_text_subtitle_cb), pi);
 
265
}
 
266
 
 
267
static void
 
268
impl_deactivate (PeasActivatable *plugin)
 
269
{
 
270
        TotemAutoloadSubtitlesPlugin *pi = TOTEM_AUTOLOAD_SUBTITLES_PLUGIN (plugin);
 
271
 
 
272
        if (pi->priv->signal_id) {
 
273
                g_signal_handler_disconnect (pi->priv->totem, pi->priv->signal_id);
 
274
                pi->priv->signal_id = 0;
 
275
        }
 
276
        if (pi->priv->totem) {
 
277
                g_object_unref (pi->priv->totem);
 
278
                pi->priv->totem = NULL;
 
279
        }
 
280
        if (pi->priv->settings) {
 
281
                g_object_unref (pi->priv->settings);
 
282
                pi->priv->settings = NULL;
 
283
        }
 
284
}