-
Notifications
You must be signed in to change notification settings - Fork 397
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> | ||
<meta name="generator" content="pdoc 0.10.0" /> | ||
<title>playlistgenerator API documentation</title> | ||
<meta name="description" content="Playlists are build from directory content in the following way: | ||
a directory is parsed and files are added to the playlist in the following way …" /> | ||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> | ||
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> | ||
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> | ||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> | ||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> | ||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> | ||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> | ||
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> | ||
</head> | ||
<body> | ||
<main> | ||
<article id="content"> | ||
<header> | ||
<h1 class="title">Module <code>playlistgenerator</code></h1> | ||
</header> | ||
<section id="section-intro"> | ||
<p>Playlists are build from directory content in the following way: | ||
a directory is parsed and files are added to the playlist in the following way</p> | ||
<ol> | ||
<li>files are added in alphabetic order</li> | ||
<li>files ending with <code>*livestream.txt</code> are unpacked and the containing URL(s) are added verbatim to the playlist</li> | ||
<li>files ending with <code>*podcast.txt</code> are unpacked and the containing Podcast URL(s) are expanded and added to the playlist</li> | ||
<li>files ending with <code>*.m3u</code> are treated as folder playlist. Regular folder processing is suspended and the playlist | ||
is build solely from the <code>*.m3u</code> content. Only the alphabetically first <code>*.m3u</code> is processed. URLs are added verbatim | ||
to the playlist except for <code>*.xml</code> and <code>*.podcast</code> URLS, which are expanded first</li> | ||
</ol> | ||
<p>An directory may contain a mixed set of files and multiple <code>*.txt</code> files, e.g.</p> | ||
<p>.. code-block:: bash</p> | ||
<pre><code>01-livestream.txt | ||
02-livestream.txt | ||
music.mp3 | ||
podcast.txt | ||
</code></pre> | ||
<p>All files are treated as music files and are added to the playlist, except those:</p> | ||
<ul> | ||
<li>starting with <code>.</code>,</li> | ||
<li>not having a file ending, i.e. do not contain a <code>.</code>,</li> | ||
<li>ending with <code>.txt</code>,</li> | ||
<li>ending with <code>.m3u</code>,</li> | ||
<li>ending with one of the excluded file endings in :attr:<code>PlaylistCollector._exclude_endings</code></li> | ||
</ul> | ||
<p>In recursive mode, the playlist is generated by concatenating all sub-folder playlists. Sub-folders are parsed | ||
in alphabetic order. Symbolic links are being followed. The above rules are enforced on a per-folder bases. | ||
This means, one <code>*.m3u</code> file per sub-folder is processed (if present).</p> | ||
<p>In <code>*.txt</code> and <code>*.m3u</code> files, all lines starting with <code>#</code> are ignored.</p> | ||
</section> | ||
<section> | ||
</section> | ||
<section> | ||
<h2 class="section-title" id="header-variables">Global variables</h2> | ||
<dl> | ||
<dt id="playlistgenerator.TYPE_DECODE"><code class="name">var <span class="ident">TYPE_DECODE</span></code></dt> | ||
<dd> | ||
<div class="desc"><p>Types if file entires in parsed directory</p></div> | ||
</dd> | ||
</dl> | ||
</section> | ||
<section> | ||
<h2 class="section-title" id="header-functions">Functions</h2> | ||
<dl> | ||
<dt id="playlistgenerator.decode_livestream"><code class="name flex"> | ||
<span>def <span class="ident">decode_livestream</span></span>(<span>filename: posix.DirEntry, path, playlist)</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
<dt id="playlistgenerator.decode_m3u"><code class="name flex"> | ||
<span>def <span class="ident">decode_m3u</span></span>(<span>filename: posix.DirEntry, path, playlist: List[<a title="playlistgenerator.PlaylistEntry" href="#playlistgenerator.PlaylistEntry">PlaylistEntry</a>])</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
<dt id="playlistgenerator.decode_musicfile"><code class="name flex"> | ||
<span>def <span class="ident">decode_musicfile</span></span>(<span>filename: posix.DirEntry, path, playlist)</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
<dt id="playlistgenerator.decode_podcast"><code class="name flex"> | ||
<span>def <span class="ident">decode_podcast</span></span>(<span>filename: str, path, playlist)</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
<dt id="playlistgenerator.decode_podcast_core"><code class="name flex"> | ||
<span>def <span class="ident">decode_podcast_core</span></span>(<span>url, playlist)</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
</dl> | ||
</section> | ||
<section> | ||
<h2 class="section-title" id="header-classes">Classes</h2> | ||
<dl> | ||
<dt id="playlistgenerator.PlaylistCollector"><code class="flex name class"> | ||
<span>class <span class="ident">PlaylistCollector</span></span> | ||
<span>(</span><span>music_library_base_path='/')</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"><p>Build a playlist from directory(s)</p> | ||
<p>This class is intended to be used with an absolute path to the music library::</p> | ||
<pre><code>plc = PlaylistCollector('/home/chris/music') | ||
plc.parse('Traumfaenger') | ||
print(f"res = {plc}") | ||
</code></pre> | ||
<p>But it can also be used with relative paths from current working directory::</p> | ||
<pre><code>plc = PlaylistCollector('.') | ||
plc.parse('../../../../music/Traumfaenger') | ||
print(f"res = {plc}") | ||
</code></pre> | ||
<p>The file ending exclusion list :attr:<code>PlaylistCollector._exclude_endings</code> is a class variable for performance reasons. | ||
If changed it will affect all instances. For modifications always call :func:<code>set_exclusion_endings</code>.</p> | ||
<p>Initialize the playlist generator with music_library_base_path</p> | ||
<p>:param music_library_base_path: Base path the the music library. This is used to locate the file in the disk | ||
but is omitted when generating the playlist entries. I.e. all files in the playlist are relative to this base dir</p></div> | ||
<h3>Static methods</h3> | ||
<dl> | ||
<dt id="playlistgenerator.PlaylistCollector.set_exclusion_endings"><code class="name flex"> | ||
<span>def <span class="ident">set_exclusion_endings</span></span>(<span>endings: List[str])</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"><p>Set the class-wide file ending exclusion list</p> | ||
<p>See :attr:<code>PlaylistCollector._exclude_endings</code></p></div> | ||
</dd> | ||
</dl> | ||
<h3>Methods</h3> | ||
<dl> | ||
<dt id="playlistgenerator.PlaylistCollector.get_directory_content"><code class="name flex"> | ||
<span>def <span class="ident">get_directory_content</span></span>(<span>self, path='.')</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"><p>Parse the folder <code>path</code> and create a content list. Depth is always the current level</p> | ||
<p>:param path: Path to folder <strong>relative</strong> to <code>music_library_base_path</code> | ||
:return: [ { type: 'directory', name: 'Simone', path: '/some/path/to/Simone' }, {…} ] | ||
where type is one of :attr:<code><a title="playlistgenerator.TYPE_DECODE" href="#playlistgenerator.TYPE_DECODE">TYPE_DECODE</a></code></p></div> | ||
</dd> | ||
<dt id="playlistgenerator.PlaylistCollector.parse"><code class="name flex"> | ||
<span>def <span class="ident">parse</span></span>(<span>self, path='.', recursive=False)</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"><p>Parse the folder <code>path</code> and create a playlist from it's content</p> | ||
<p>:param path: Path to folder <strong>relative</strong> to <code>music_library_base_path</code> | ||
:param recursive: Parse folder recursivley, or stay in top-level folder</p></div> | ||
</dd> | ||
</dl> | ||
</dd> | ||
<dt id="playlistgenerator.PlaylistEntry"><code class="flex name class"> | ||
<span>class <span class="ident">PlaylistEntry</span></span> | ||
<span>(</span><span>filetype: int, name: str, path: str)</span> | ||
</code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
<h3>Instance variables</h3> | ||
<dl> | ||
<dt id="playlistgenerator.PlaylistEntry.filetype"><code class="name">var <span class="ident">filetype</span></code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
<dt id="playlistgenerator.PlaylistEntry.name"><code class="name">var <span class="ident">name</span></code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
<dt id="playlistgenerator.PlaylistEntry.path"><code class="name">var <span class="ident">path</span></code></dt> | ||
<dd> | ||
<div class="desc"></div> | ||
</dd> | ||
</dl> | ||
</dd> | ||
</dl> | ||
</section> | ||
</article> | ||
<nav id="sidebar"> | ||
<h1>Index</h1> | ||
<div class="toc"> | ||
<ul></ul> | ||
</div> | ||
<ul id="index"> | ||
<li><h3><a href="#header-variables">Global variables</a></h3> | ||
<ul class=""> | ||
<li><code><a title="playlistgenerator.TYPE_DECODE" href="#playlistgenerator.TYPE_DECODE">TYPE_DECODE</a></code></li> | ||
</ul> | ||
</li> | ||
<li><h3><a href="#header-functions">Functions</a></h3> | ||
<ul class=""> | ||
<li><code><a title="playlistgenerator.decode_livestream" href="#playlistgenerator.decode_livestream">decode_livestream</a></code></li> | ||
<li><code><a title="playlistgenerator.decode_m3u" href="#playlistgenerator.decode_m3u">decode_m3u</a></code></li> | ||
<li><code><a title="playlistgenerator.decode_musicfile" href="#playlistgenerator.decode_musicfile">decode_musicfile</a></code></li> | ||
<li><code><a title="playlistgenerator.decode_podcast" href="#playlistgenerator.decode_podcast">decode_podcast</a></code></li> | ||
<li><code><a title="playlistgenerator.decode_podcast_core" href="#playlistgenerator.decode_podcast_core">decode_podcast_core</a></code></li> | ||
</ul> | ||
</li> | ||
<li><h3><a href="#header-classes">Classes</a></h3> | ||
<ul> | ||
<li> | ||
<h4><code><a title="playlistgenerator.PlaylistCollector" href="#playlistgenerator.PlaylistCollector">PlaylistCollector</a></code></h4> | ||
<ul class=""> | ||
<li><code><a title="playlistgenerator.PlaylistCollector.get_directory_content" href="#playlistgenerator.PlaylistCollector.get_directory_content">get_directory_content</a></code></li> | ||
<li><code><a title="playlistgenerator.PlaylistCollector.parse" href="#playlistgenerator.PlaylistCollector.parse">parse</a></code></li> | ||
<li><code><a title="playlistgenerator.PlaylistCollector.set_exclusion_endings" href="#playlistgenerator.PlaylistCollector.set_exclusion_endings">set_exclusion_endings</a></code></li> | ||
</ul> | ||
</li> | ||
<li> | ||
<h4><code><a title="playlistgenerator.PlaylistEntry" href="#playlistgenerator.PlaylistEntry">PlaylistEntry</a></code></h4> | ||
<ul class=""> | ||
<li><code><a title="playlistgenerator.PlaylistEntry.filetype" href="#playlistgenerator.PlaylistEntry.filetype">filetype</a></code></li> | ||
<li><code><a title="playlistgenerator.PlaylistEntry.name" href="#playlistgenerator.PlaylistEntry.name">name</a></code></li> | ||
<li><code><a title="playlistgenerator.PlaylistEntry.path" href="#playlistgenerator.PlaylistEntry.path">path</a></code></li> | ||
</ul> | ||
</li> | ||
</ul> | ||
</li> | ||
</ul> | ||
</nav> | ||
</main> | ||
<footer id="footer"> | ||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> | ||
</footer> | ||
</body> | ||
</html> |