TotemPlParserResult totem_pl_parser_add_ram (TotemPlParser *parser, GFile *file, TotemPlParseData *parse_data, gpointer data) { gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED; char *contents, **lines; gsize size; guint i; if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE) return TOTEM_PL_PARSER_RESULT_ERROR; lines = g_strsplit_set (contents, "\r\n", 0); g_free (contents); for (i = 0; lines[i] != NULL; i++) { /* Empty line */ if (totem_pl_parser_line_is_empty (lines[i]) != FALSE) continue; retval = TOTEM_PL_PARSER_RESULT_SUCCESS; /* Either it's a URI, or it has a proper path ... */ if (strstr(lines[i], "://") != NULL || lines[i][0] == G_DIR_SEPARATOR) { GFile *line_file; line_file = g_file_new_for_uri (lines[i]); /* .ram files can contain .smil entries */ if (totem_pl_parser_parse_internal (parser, line_file, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS) totem_pl_parser_parse_ram_uri (parser, lines[i]); g_object_unref (line_file); } else if (strcmp (lines[i], "--stop--") == 0) { /* For Real Media playlists, handle the stop command */ break; } else { //FIXME #if 0 char *base; /* Try with a base */ base = totem_pl_parser_base_uri (uri); if (totem_pl_parser_parse_internal (parser, lines[i], base) != TOTEM_PL_PARSER_RESULT_SUCCESS) { char *fullpath; fullpath = g_strdup_printf ("%s/%s", base, lines[i]); totem_pl_parser_parse_ram_uri (parser, fullpath); g_free (fullpath); } g_free (base); #endif } } g_strfreev (lines); return retval; }
TotemPlParserResult totem_pl_parser_add_desktop (TotemPlParser *parser, GFile *file, GFile *base_file, TotemPlParseData *parse_data, gpointer data) { char *contents, **lines; const char *path, *display_name, *type; GFile *target; gsize size; TotemPlParserResult res = TOTEM_PL_PARSER_RESULT_ERROR; if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE) return res; lines = g_strsplit (contents, "\n", 0); g_free (contents); type = totem_pl_parser_read_ini_line_string (lines, "Type"); if (type == NULL) goto bail; if (g_ascii_strcasecmp (type, "Link") != 0 && g_ascii_strcasecmp (type, "FSDevice") != 0) { goto bail; } path = totem_pl_parser_read_ini_line_string (lines, "URL"); if (path == NULL) goto bail; target = g_file_new_for_uri (path); display_name = totem_pl_parser_read_ini_line_string (lines, "Name"); if (totem_pl_parser_ignore (parser, path) == FALSE && g_ascii_strcasecmp (type, "FSDevice") != 0) { totem_pl_parser_add_one_file (parser, target, display_name); } else { if (totem_pl_parser_parse_internal (parser, target, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS) totem_pl_parser_add_one_file (parser, target, display_name); } res = TOTEM_PL_PARSER_RESULT_SUCCESS; bail: g_strfreev (lines); return res; }
TotemPlParserResult totem_pl_parser_add_m3u (TotemPlParser *parser, GFile *file, GFile *base_file, TotemPlParseData *parse_data, gpointer data) { TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_UNHANDLED; char *contents, **lines; gsize size; guint i, num_lines; gboolean dos_mode = FALSE; const char *extinfo, *extvlcopt_audiotrack; char *pl_uri; if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE) { DEBUG (file, g_print ("Failed to load '%s'\n", uri)); return TOTEM_PL_PARSER_RESULT_ERROR; } /* .pls files with a .m3u extension, the nasties */ if (g_str_has_prefix (contents, "[playlist]") != FALSE || g_str_has_prefix (contents, "[Playlist]") != FALSE || g_str_has_prefix (contents, "[PLAYLIST]") != FALSE) { DEBUG (file, g_print ("Parsing '%s' playlist as PLS\n", uri)); retval = totem_pl_parser_add_pls_with_contents (parser, file, base_file, contents, parse_data); g_free (contents); return retval; } if (strstr (contents, EXTINF_HLS) || strstr (contents, EXTINF_HLS2)) { DEBUG (file, g_print ("Unhandled HLS playlist '%s', should be passed to player\n", uri)); g_free (contents); return retval; } /* Try to use ISO-8859-1 if we don't have valid UTF-8, * try to parse anyway if it's not ISO-8859-1 */ if (g_utf8_validate (contents, -1, NULL) == FALSE) { char *fixed; fixed = g_convert (contents, -1, "UTF-8", "ISO8859-1", NULL, NULL, NULL); if (fixed != NULL) { g_free (contents); contents = fixed; } } /* is non-NULL if there's an EXTINF on a preceding line */ extinfo = NULL; extvlcopt_audiotrack = NULL; /* figure out whether we're a unix m3u or dos m3u */ if (strstr(contents, "\x0d")) { dos_mode = TRUE; } lines = g_strsplit_set (contents, "\r\n", 0); g_free (contents); num_lines = g_strv_length (lines); /* We don't count the terminating NULL */ num_lines--; /* Send out the playlist start and get crackin' */ pl_uri = g_file_get_uri (file); totem_pl_parser_add_uri (parser, TOTEM_PL_PARSER_FIELD_IS_PLAYLIST, TRUE, TOTEM_PL_PARSER_FIELD_URI, pl_uri, TOTEM_PL_PARSER_FIELD_CONTENT_TYPE, "audio/x-mpegurl", NULL); for (i = 0; lines[i] != NULL; i++) { const char *line; char *length; gint64 length_num = 0; char *audio_track; line = lines[i]; if (line[0] == '\0') continue; retval = TOTEM_PL_PARSER_RESULT_SUCCESS; /* Ignore leading spaces */ for (; g_ascii_isspace (line[0]); line++) ; /* Ignore comments, but mark it if we have extra info */ if (line[0] == '#') { if (extinfo == NULL && g_str_has_prefix (line, EXTINF) != FALSE) extinfo = line; if (extvlcopt_audiotrack == NULL && g_str_has_prefix (line, EXTVLCOPT_AUDIOTRACK) != FALSE) extvlcopt_audiotrack = line; continue; } length = totem_pl_parser_get_extinfo_length (extinfo); if (length != NULL) length_num = totem_pl_parser_parse_duration (length, totem_pl_parser_is_debugging_enabled (parser)); g_free (length); audio_track = totem_pl_parser_get_extvlcopt_audio_track (extvlcopt_audiotrack); /* Either it's a URI, or it has a proper path ... */ if (strstr(line, "://") != NULL || line[0] == G_DIR_SEPARATOR) { GFile *uri; uri = g_file_new_for_commandline_arg (line); if (length_num < 0 || totem_pl_parser_parse_internal (parser, uri, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS) { totem_pl_parser_add_uri (parser, TOTEM_PL_PARSER_FIELD_URI, line, TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo), TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track, NULL); } g_object_unref (uri); } else if (g_ascii_isalpha (line[0]) != FALSE && g_str_has_prefix (line + 1, ":\\")) { /* Path relative to a drive on Windows, we need to use * the base that was passed to us */ GFile *uri; lines[i] = g_strdelimit (lines[i], "\\", '/'); /* + 2, skip drive letter */ uri = g_file_get_child (base_file, line + 2); totem_pl_parser_add_uri (parser, TOTEM_PL_PARSER_FIELD_FILE, uri, TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo), TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track, NULL); g_object_unref (uri); } else if (line[0] == '\\' && line[1] == '\\') { /* ... Or it's in the windows smb form * (\\machine\share\filename), Note drive names * (C:\ D:\ etc) are unhandled (unknown base for * drive letters) */ char *tmpuri; lines[i] = g_strdelimit (lines[i], "\\", '/'); tmpuri = g_strjoin (NULL, "smb:", line, NULL); totem_pl_parser_add_uri (parser, TOTEM_PL_PARSER_FIELD_URI, tmpuri, TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo), TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track, NULL); g_free (tmpuri); } else { /* Try with a base */ GFile *uri, *_base_file; char sep; _base_file = g_file_get_parent (file); sep = (dos_mode ? '\\' : '/'); if (sep == '\\') lines[i] = g_strdelimit (lines[i], "\\", '/'); uri = g_file_get_child (_base_file, line); g_object_unref (_base_file); totem_pl_parser_add_uri (parser, TOTEM_PL_PARSER_FIELD_FILE, uri, TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo), TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track, NULL); g_object_unref (uri); } extinfo = NULL; extvlcopt_audiotrack = NULL; g_free (audio_track); } g_strfreev (lines); totem_pl_parser_playlist_end (parser, pl_uri); g_free (pl_uri); return retval; }