Skip to content

Commit

Permalink
Test pydoc
Browse files Browse the repository at this point in the history
  • Loading branch information
pabera committed Nov 5, 2023
1 parent 6f55597 commit e1c6aeb
Showing 1 changed file with 229 additions and 0 deletions.
229 changes: 229 additions & 0 deletions documentation/api-reference/playlistgenerator.html
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' }, {&hellip;} ]
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>

0 comments on commit e1c6aeb

Please sign in to comment.