Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
dbc59e3a
Commit
dbc59e3a
authored
Jun 14, 2006
by
Yoann Peronneau
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* Tree playlist XSPF export
Kids, don't try this at home...
parent
e955c93c
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
146 additions
and
108 deletions
+146
-108
modules/gui/wxwidgets/dialogs/playlist.cpp
modules/gui/wxwidgets/dialogs/playlist.cpp
+8
-5
modules/misc/playlist/xspf.c
modules/misc/playlist/xspf.c
+136
-102
modules/misc/playlist/xspf.h
modules/misc/playlist/xspf.h
+2
-1
No files found.
modules/gui/wxwidgets/dialogs/playlist.cpp
View file @
dbc59e3a
...
...
@@ -932,7 +932,7 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
char
*
psz_desc
;
char
*
psz_filter
;
char
*
psz_module
;
}
formats
[]
=
{{
_
(
"M3U file"
),
"*.m3u"
,
"export-m3u"
},
}
formats
[]
=
{
//
{ _("M3U file"), "*.m3u", "export-m3u" },
{
_
(
"XSPF playlist"
),
"*.xspf"
,
"export-xspf"
}
};
...
...
@@ -959,10 +959,13 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
{
if
(
dialog
.
GetPath
().
mb_str
()
)
{
abort
();
// playlist_Export( p_playlist, dialog.GetPath().mb_str(),
// /* ROOT */
// formats[dialog.GetFilterIndex()].psz_module );
/* what root should we export? */
if
(
p_playlist
->
p_root_category
->
i_children
>
0
)
{
playlist_Export
(
p_playlist
,
dialog
.
GetPath
().
mb_str
(),
p_playlist
->
p_root_category
->
pp_children
[
0
],
formats
[
dialog
.
GetFilterIndex
()].
psz_module
);
}
}
}
...
...
modules/misc/playlist/xspf.c
View file @
dbc59e3a
/******************************************************************************
* Copyright (C) 2006 Daniel Stränger <vlc at schmaller dot de>
* xspf.c : XSPF playlist export functions
******************************************************************************
* Copyright (C) 2006 the VideoLAN team
* $Id$
*
* Authors: Daniel Stränger <vlc at schmaller dot de>
* Yoann Peronneau <yoann@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -39,87 +45,59 @@ int E_(xspf_export_playlist)( vlc_object_t *p_this )
const
playlist_export_t
*
p_export
=
(
playlist_export_t
*
)
p_playlist
->
p_private
;
int
i
;
char
*
psz
;
char
*
psz_temp
;
playlist_item_t
**
pp_items
=
NULL
;
int
i_size
;
playlist_item_t
*
p_node
;
playlist_item_t
*
p_node
=
p_export
->
p_root
;
int
i_count
;
/* write XSPF XML header - since we don't use <extension>,
* we get by with version 0 */
/* write XSPF XML header */
fprintf
(
p_export
->
p_file
,
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
"
);
fprintf
(
p_export
->
p_file
,
"<playlist version=
\"
0
\"
xmlns=
\"
http://xspf.org/ns/0/
\"
>
\n
"
);
"<playlist version=
\"
1
\"
xmlns=
\"
http://xspf.org/ns/0/
\"
>
\n
"
);
if
(
!
p_node
)
return
VLC_SUCCESS
;
/* save tho whole playlist or only the current node */
#define p_item p_playlist->status.p_item
if
(
p_item
)
{
if
(
p_item
->
p_parent
->
p_input
->
i_type
==
ITEM_TYPE_PLAYLIST
)
{
/* set the current node and its children */
p_node
=
p_item
->
p_parent
;
pp_items
=
p_node
->
pp_children
;
i_size
=
p_node
->
i_children
;
#undef p_item
/* save name of the playlist node */
psz_temp
=
convert_xml_special_chars
(
p_node
->
p_input
->
psz_name
);
if
(
*
psz_temp
)
fprintf
(
p_export
->
p_file
,
"
\t
<title>%s</title>
\n
"
,
psz_temp
);
free
(
psz_temp
);
/* save the creator of the playlist node */
psz
=
p_node
->
p_input
->
p_meta
->
psz_artist
?
strdup
(
p_node
->
p_input
->
p_meta
->
psz_artist
)
:
strdup
(
""
);
if
(
psz
&&
!*
psz
)
if
(
*
psz_temp
)
{
free
(
psz
);
psz
=
NULL
;
fprintf
(
p_export
->
p_file
,
"
\t
<title>%s</title>
\n
"
,
psz_temp
);
}
if
(
!
psz
)
psz
=
p_node
->
p_input
->
p_meta
->
psz_author
?
strdup
(
p_node
->
p_input
->
p_meta
->
psz_author
)
:
strdup
(
""
);
psz_temp
=
convert_xml_special_chars
(
psz
);
if
(
psz
)
free
(
psz
);
if
(
*
psz_temp
)
fprintf
(
p_export
->
p_file
,
"
\t
<creator>%s</creator>
\n
"
,
psz_temp
);
free
(
psz_temp
);
/* save location of the playlist node */
psz
=
assertUTF8URI
(
p_export
->
psz_filename
);
if
(
psz
&&
*
psz
)
psz_temp
=
assertUTF8URI
(
p_export
->
psz_filename
);
if
(
psz_temp
&&
*
psz_temp
)
{
fprintf
(
p_export
->
p_file
,
"
\t
<location>%s</location>
\n
"
,
psz
);
free
(
psz
);
}
}
fprintf
(
p_export
->
p_file
,
"
\t
<location>%s</location>
\n
"
,
psz_temp
);
free
(
psz_temp
);
}
/* prepare all the playlist children for export */
if
(
!
pp_items
)
/* export all items in a flat format */
fprintf
(
p_export
->
p_file
,
"
\t
<trackList>
\n
"
);
i_count
=
0
;
for
(
i
=
0
;
i
<
p_node
->
i_children
;
i
++
)
{
pp_items
=
p_playlist
->
pp_items
;
i_size
=
p_playlist
->
i_size
;
xspf_export_item
(
p_node
->
pp_children
[
i
],
p_export
->
p_file
,
&
i_count
)
;
}
fprintf
(
p_export
->
p_file
,
"
\t
</trackList>
\n
"
);
/* export all items */
fprintf
(
p_export
->
p_file
,
"
\t
<trackList>
\n
"
);
for
(
i
=
0
;
i
<
i_size
;
i
++
)
/* export the tree structure in <extension> */
fprintf
(
p_export
->
p_file
,
"
\t
<extension>
\n
"
);
i_count
=
0
;
for
(
i
=
0
;
i
<
p_node
->
i_children
;
i
++
)
{
xspf_export_item
(
pp_items
[
i
],
p_export
->
p_file
);
xspf_extension_item
(
p_node
->
pp_children
[
i
],
p_export
->
p_file
,
&
i_count
);
}
fprintf
(
p_export
->
p_file
,
"
\t
</extension>
\n
"
);
/* close the header elements */
fprintf
(
p_export
->
p_file
,
"
\t
</trackList>
\n
"
);
fprintf
(
p_export
->
p_file
,
"</playlist>
\n
"
);
return
VLC_SUCCESS
;
...
...
@@ -129,25 +107,23 @@ int E_(xspf_export_playlist)( vlc_object_t *p_this )
* \brief exports one item to file or traverse if item is a node
* \param p_item playlist item to export
* \param p_file file to write xml-converted item to
* \param p_i_count counter for track identifiers
*/
static
void
xspf_export_item
(
playlist_item_t
*
p_item
,
FILE
*
p_file
)
static
void
xspf_export_item
(
playlist_item_t
*
p_item
,
FILE
*
p_file
,
int
*
p_i_count
)
{
int
i
;
/**< iterator for all children if the current item is a node */
char
*
psz
;
char
*
psz_temp
;
if
(
!
p_item
)
return
;
if
(
!
p_item
)
return
;
/** \todo only "flat" playlists supported at this time.
* extend to save the tree structure.
*/
/* if we get a node here, we must traverse it */
if
(
p_item
->
i_children
>
0
)
if
(
p_item
->
i_children
>
0
)
{
for
(
i
=
0
;
i
<
p_item
->
i_children
;
i
++
)
int
i
;
for
(
i
=
0
;
i
<
p_item
->
i_children
;
i
++
)
{
xspf_export_item
(
p_item
->
pp_children
[
i
],
p_file
);
xspf_export_item
(
p_item
->
pp_children
[
i
],
p_file
,
p_i_count
);
}
return
;
}
...
...
@@ -155,8 +131,12 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
/* leaves can be written directly */
fprintf
(
p_file
,
"
\t\t
<track>
\n
"
);
/* print identifier and increase the counter */
fprintf
(
p_file
,
"
\t\t\t
<identifier>%d</identifier>
\n
"
,
*
p_i_count
);
(
*
p_i_count
)
++
;
/* -> the location */
if
(
p_item
->
p_input
->
psz_uri
&&
*
p_item
->
p_input
->
psz_uri
)
if
(
p_item
->
p_input
->
psz_uri
&&
*
p_item
->
p_input
->
psz_uri
)
{
psz
=
assertUTF8URI
(
p_item
->
p_input
->
psz_uri
);
fprintf
(
p_file
,
"
\t\t\t
<location>%s</location>
\n
"
,
psz
);
...
...
@@ -164,33 +144,42 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
}
/* -> the name/title (only if different from uri)*/
if
(
p_item
->
p_input
->
psz_name
&&
if
(
p_item
->
p_input
->
psz_name
&&
p_item
->
p_input
->
psz_uri
&&
strcmp
(
p_item
->
p_input
->
psz_uri
,
p_item
->
p_input
->
psz_name
)
)
{
psz_temp
=
convert_xml_special_chars
(
p_item
->
p_input
->
psz_name
);
if
(
*
psz_temp
)
if
(
*
psz_temp
)
fprintf
(
p_file
,
"
\t\t\t
<title>%s</title>
\n
"
,
psz_temp
);
free
(
psz_temp
);
}
if
(
p_item
->
p_input
->
p_meta
==
NULL
)
{
goto
xspfexportitem_end
;
}
/* -> the artist/creator */
psz
=
p_item
->
p_input
->
p_meta
->
psz_artist
?
strdup
(
p_item
->
p_input
->
p_meta
->
psz_artist
)
:
strdup
(
""
);
if
(
psz
&&
!*
psz
)
if
(
psz
&&
!*
psz
)
{
free
(
psz
);
free
(
psz
);
psz
=
NULL
;
}
if
(
!
psz
)
if
(
!
psz
)
{
psz
=
p_item
->
p_input
->
p_meta
->
psz_author
?
strdup
(
p_item
->
p_input
->
p_meta
->
psz_author
)
:
strdup
(
""
);
}
psz_temp
=
convert_xml_special_chars
(
psz
);
if
(
psz
)
free
(
psz
);
if
(
*
psz_temp
)
if
(
psz
)
free
(
psz
);
if
(
*
psz_temp
)
{
fprintf
(
p_file
,
"
\t\t\t
<creator>%s</creator>
\n
"
,
psz_temp
);
}
free
(
psz_temp
);
/* -> the album */
...
...
@@ -198,24 +187,29 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
strdup
(
p_item
->
p_input
->
p_meta
->
psz_album
)
:
strdup
(
""
);
psz_temp
=
convert_xml_special_chars
(
psz
);
if
(
psz
)
free
(
psz
);
if
(
*
psz_temp
)
if
(
psz
)
free
(
psz
);
if
(
*
psz_temp
)
{
fprintf
(
p_file
,
"
\t\t\t
<album>%s</album>
\n
"
,
psz_temp
);
}
free
(
psz_temp
);
/* -> the track number */
psz
=
p_item
->
p_input
->
p_meta
->
psz_tracknum
?
strdup
(
p_item
->
p_input
->
p_meta
->
psz_tracknum
)
:
strdup
(
""
);
if
(
psz
)
if
(
psz
)
{
if
(
*
psz
)
{
if
(
*
psz
)
fprintf
(
p_file
,
"
\t\t\t
<trackNum>%i</trackNum>
\n
"
,
atoi
(
psz
)
);
}
free
(
psz
);
}
xspfexportitem_end:
/* -> the duration */
if
(
p_item
->
p_input
->
i_duration
>
0
)
if
(
p_item
->
p_input
->
i_duration
>
0
)
{
fprintf
(
p_file
,
"
\t\t\t
<duration>%ld</duration>
\n
"
,
(
long
)(
p_item
->
p_input
->
i_duration
/
1000
)
);
...
...
@@ -226,6 +220,43 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
return
;
}
/**
* \brief exports one item in extension to file and traverse if item is a node
* \param p_item playlist item to export
* \param p_file file to write xml-converted item to
* \param p_i_count counter for track identifiers
*/
static
void
xspf_extension_item
(
playlist_item_t
*
p_item
,
FILE
*
p_file
,
int
*
p_i_count
)
{
if
(
!
p_item
)
return
;
/* if we get a node here, we must traverse it */
if
(
p_item
->
i_children
>
0
)
{
int
i
;
fprintf
(
p_file
,
"
\t\t
<node>
\n
"
);
fprintf
(
p_file
,
"
\t\t\t
<title>%s</title>
\n
"
,
p_item
->
p_input
->
psz_name
);
for
(
i
=
0
;
i
<
p_item
->
i_children
;
i
++
)
{
xspf_extension_item
(
p_item
->
pp_children
[
i
],
p_file
,
p_i_count
);
}
fprintf
(
p_file
,
"
\t\t
</node>
\n
"
);
return
;
}
/* print leaf and increase the counter */
fprintf
(
p_file
,
"
\t\t\t
<item href=
\"
%d
\"
/>
\n
"
,
*
p_i_count
);
(
*
p_i_count
)
++
;
return
;
}
/**
* \param psz_name the location of the media ressource (e.g. local file,
* device, network stream, etc.)
...
...
@@ -239,7 +270,7 @@ static char *assertUTF8URI( char *psz_name )
char
*
psz_s
=
NULL
,
*
psz_d
=
NULL
;
/**< src & dest pointers for URI conversion */
vlc_bool_t
b_name_is_uri
=
VLC_FALSE
;
if
(
!
psz_name
||
!*
psz_name
)
if
(
!
psz_name
||
!*
psz_name
)
return
NULL
;
/* check that string is valid UTF-8 */
...
...
@@ -250,11 +281,11 @@ static char *assertUTF8URI( char *psz_name )
/* max. 3x for URI conversion (percent escaping) and
8 bytes for "file://" and NULL-termination */
psz_ret
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
strlen
(
psz_name
)
*
6
*
3
+
8
);
if
(
!
psz_ret
)
if
(
!
psz_ret
)
return
NULL
;
/** \todo check for a valid scheme part preceding the colon */
if
(
strchr
(
psz_s
,
':'
)
)
if
(
strchr
(
psz_s
,
':'
)
)
{
psz_d
=
psz_ret
;
b_name_is_uri
=
VLC_TRUE
;
...
...
@@ -266,10 +297,10 @@ static char *assertUTF8URI( char *psz_name )
psz_d
=
psz_ret
+
7
;
}
while
(
*
psz_s
)
while
(
*
psz_s
)
{
/* percent-encode all non-ASCII and the XML special characters and the percent sign itself */
if
(
*
psz_s
&
B10000000
||
if
(
*
psz_s
&
B10000000
||
*
psz_s
==
'<'
||
*
psz_s
==
'>'
||
*
psz_s
==
'&'
||
...
...
@@ -279,8 +310,11 @@ static char *assertUTF8URI( char *psz_name )
*
psz_d
++
=
'%'
;
*
psz_d
++
=
hexchars
[(
*
psz_s
>>
4
)
&
B00001111
];
*
psz_d
++
=
hexchars
[
*
psz_s
&
B00001111
];
}
else
}
else
{
*
psz_d
++
=
*
psz_s
;
}
psz_s
++
;
}
...
...
modules/misc/playlist/xspf.h
View file @
dbc59e3a
...
...
@@ -33,5 +33,6 @@ const char hexchars[16] = "0123456789ABCDEF";
/* prototypes */
int
E_
(
xspf_export_playlist
)(
vlc_object_t
*
);
static
void
xspf_export_item
(
playlist_item_t
*
,
FILE
*
);
static
void
xspf_export_item
(
playlist_item_t
*
,
FILE
*
,
int
*
);
static
void
xspf_extension_item
(
playlist_item_t
*
,
FILE
*
,
int
*
);
static
char
*
assertUTF8URI
(
char
*
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment