Project

General

Profile

playlist-files.cc

Latest Fauxdacious version - Jim Turner, March 22, 2017 04:34

 
1
/*
2
 * playlist-files.c
3
 * Copyright 2010-2013 John Lindgren
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions, and the following disclaimer.
10
 *
11
 * 2. Redistributions in binary form must reproduce the above copyright notice,
12
 *    this list of conditions, and the following disclaimer in the documentation
13
 *    provided with the distribution.
14
 *
15
 * This software is provided "as is" and without any warranty, express or
16
 * implied. In no event shall the authors be liable for any damages arising from
17
 * the use of this software.
18
 */
19
#include <stdlib.h>
20
#include <stdio.h>
21
#include <string.h>
22
#include <unistd.h>
23
#include "playlist-internal.h"
24

    
25
#include "audstrings.h"
26
#include "i18n.h"
27
#include "interface.h"
28
#include "plugin.h"
29
#include "plugins-internal.h"
30
#include "runtime.h"
31

    
32
EXPORT bool aud_filename_is_playlist (const char * filename)
33
{
34
    bool userurl2playlist = false;
35
    if (strstr (filename, "://") && ! strstr (filename, "file:/"))  //JWT:WE'RE SOME KIND OF URL:
36
    {
37
        String url_helper = aud_get_str ("audacious", "url_helper");
38
               StringBuf temp_playlist_filename = filename_build ({aud_get_path (AudPath::UserDir), "tempurl.pls"});
39
               remove ((const char *) temp_playlist_filename);
40
        if (url_helper[0])  //JWT:WE HAVE A PERL HELPER, LESSEE IF IT RECOGNIZES & CONVERTS IT (ie. tunein.com, youtube, etc):
41
        {
42
            system ((const char *) str_concat ({url_helper, " ", filename, " ", aud_get_path (AudPath::UserDir)}));    
43
            if (access((const char *) temp_playlist_filename, F_OK ) != -1 )
44
                userurl2playlist = true;
45
        }
46
    }
47

    
48
    /* JWT:THE HELPER CONVERTS RECOGNIZED URL PATTERNS TO A TEMP. SINGLE-ITEM PLAYLIST AS THIS IS 
49
       THE ONLY WAY IN AUDACIOUS TO *CHANGE* THE URL (filename) TO SOMETHING ELSE! */
50
    StringBuf ext = userurl2playlist ? str_printf (_("pls")) : uri_get_extension (filename);
51
    if (ext)
52
    {
53
        for (PluginHandle * plugin : aud_plugin_list (PluginType::Playlist))
54
        {
55
            if (aud_plugin_get_enabled (plugin) && playlist_plugin_has_ext (plugin, ext))
56
                return true;
57
        }
58
    }
59

    
60
    return false;
61
}
62

    
63
bool playlist_load (const char * filename, String & title, Index<PlaylistAddItem> & items)
64
{
65
    bool userurl2playlist = false;
66
    bool plugin_found = false;
67

    
68
    AUDINFO ("Loading playlist %s.\n", filename);
69

    
70
    if (strstr (filename, "://") && ! strstr (filename, "file:/"))
71
    {
72
        StringBuf temp_playlist_filename = filename_build ({aud_get_path (AudPath::UserDir), "tempurl.pls"});
73
        if (access((const char *) temp_playlist_filename, F_OK ) != -1 )
74
            userurl2playlist = true;
75
    }
76

    
77
    StringBuf ext = userurl2playlist ? str_printf (_("pls")) : uri_get_extension (filename);
78

    
79
    if (ext)
80
    {
81
        for (PluginHandle * plugin : aud_plugin_list (PluginType::Playlist))
82
        {
83
            if (! aud_plugin_get_enabled (plugin) || ! playlist_plugin_has_ext (plugin, ext))
84
                continue;
85

    
86
            AUDINFO ("Trying playlist plugin %s.\n", aud_plugin_get_name (plugin));
87
            plugin_found = true;
88

    
89
            auto pp = (PlaylistPlugin *) aud_plugin_get_header (plugin);
90
            if (! pp)
91
                continue;
92

    
93
            if (userurl2playlist)
94
            {
95
                ext.steal (str_printf (_("tempurl.pls")));
96
                ext.steal (filename_build ({aud_get_path (AudPath::UserDir), ext}));
97
                ext.steal (filename_to_uri (ext));
98

    
99
                VFSFile file ((const char *) ext, "r");
100
                if (! file)
101
                {
102
                    aud_ui_show_error (str_printf (_("Error opening %s:\n%s"),
103
                            (const char *) ext, file.error ()));
104
                    return false;
105
                }
106

    
107
                if (pp->load ((const char *) ext, file, title, items))
108
                    return true;
109
            }
110
            else
111
            {
112
                VFSFile file (filename, "r");
113
                if (! file)
114
                {
115
                    aud_ui_show_error (str_printf (_("Error opening %s:\n%s"),
116
                     filename, file.error ()));
117
                    return false;
118
                }
119

    
120
                if (pp->load (filename, file, title, items))
121
                    return true;
122
            }
123

    
124
            title = String ();
125
            items.clear ();
126
        }
127
    }
128

    
129
    if (plugin_found)
130
        aud_ui_show_error (str_printf (_("Error loading %s."), filename));
131
    else
132
        aud_ui_show_error (str_printf (_("Cannot load %s: unsupported file "
133
         "name extension."), filename));
134

    
135
    return false;
136
}
137

    
138
// This procedure is only used when loading playlists from ~/.config/audacious;
139
// hence, it is drastically simpler than the full-featured routines in adder.cc.
140
// All support for adding folders, cuesheets, subtunes, etc. is omitted here.
141
// Additionally, in order to avoid heavy I/O at startup, failed entries are not
142
// rescanned; they can be rescanned later by refreshing the playlist. */
143
bool playlist_insert_playlist_raw (int list, int at, const char * filename)
144
{
145
    String title;
146
    Index<PlaylistAddItem> items;
147

    
148
    if (! playlist_load (filename, title, items))
149
        return false;
150

    
151
    if (title && ! aud_playlist_entry_count (list))
152
        aud_playlist_set_title (list, title);
153

    
154
    playlist_entry_insert_batch_raw (list, at, std::move (items));
155

    
156
    return true;
157
}
158

    
159
EXPORT bool aud_playlist_save (int list, const char * filename, Playlist::GetMode mode)
160
{
161
    String title = aud_playlist_get_title (list);
162

    
163
    Index<PlaylistAddItem> items;
164
    items.insert (0, aud_playlist_entry_count (list));
165

    
166
    int i = 0;
167
    for (PlaylistAddItem & item : items)
168
    {
169
        item.filename = aud_playlist_entry_get_filename (list, i);
170
        item.tuple = aud_playlist_entry_get_tuple (list, i, mode);
171
        item.tuple.delete_fallbacks ();
172
        i ++;
173
    }
174

    
175
    AUDINFO ("Saving playlist %s.\n", filename);
176

    
177
    StringBuf ext = uri_get_extension (filename);
178

    
179
    if (ext)
180
    {
181
        for (PluginHandle * plugin : aud_plugin_list (PluginType::Playlist))
182
        {
183
            if (! aud_plugin_get_enabled (plugin) || ! playlist_plugin_has_ext (plugin, ext))
184
                continue;
185

    
186
            PlaylistPlugin * pp = (PlaylistPlugin *) aud_plugin_get_header (plugin);
187
            if (! pp || ! pp->can_save)
188
                continue;
189

    
190
            VFSFile file (filename, "w");
191
            if (! file)
192
                return false;
193

    
194
            return pp->save (filename, file, title, items) && file.fflush () == 0;
195
        }
196
    }
197

    
198
    aud_ui_show_error (str_printf (_("Cannot save %s: unsupported file name extension."), filename));
199

    
200
    return false;
201
}
202

    
203
EXPORT Index<Playlist::SaveFormat> aud_playlist_save_formats ()
204
{
205
    Index<Playlist::SaveFormat> formats;
206

    
207
    for (auto plugin : aud_plugin_list (PluginType::Playlist))
208
    {
209
        if (! aud_plugin_get_enabled (plugin) || ! playlist_plugin_can_save (plugin))
210
            continue;
211

    
212
        auto & format = formats.append ();
213
        format.name = String (aud_plugin_get_name (plugin));
214

    
215
        for (auto & ext : playlist_plugin_get_exts (plugin))
216
            format.exts.append (ext);
217
    }
218

    
219
    return formats;
220
}