Compare commits

...

6 Commits

5 changed files with 311 additions and 105 deletions

View File

@ -13,8 +13,8 @@ dependencies. This package requires two underlying packages. Those are
`python-magic`, and `pillow`. Here are the installation documentation for those `python-magic`, and `pillow`. Here are the installation documentation for those
packages: packages:
* https://github.com/threatstack/libmagic * [github.com/threatstack/libmagic](https://github.com/threatstack/libmagic)
* https://pillow.readthedocs.io/en/5.3.x/installation.html#external-libraries * [pillow.readthedocs.io](https://pillow.readthedocs.io/en/5.3.x/installation.html#external-libraries)
## Installation ## Installation
@ -28,6 +28,16 @@ Using [--user] or [a virtual environment] is recommended:
$ pip install --user distribusi $ pip install --user distribusi
``` ```
Note: check if the path of your local bin is added to your shell path (otherwise you cannot run distribusi from the shell directly).
To check where distribusi is installed:
$ find * | grep distribusi
Add local bin to the $PATH variable:
$ PATH=$PATH:/home/USERNAME/.local/bin/
## Usage ## Usage
Get help with: Get help with:
@ -81,6 +91,8 @@ $ pipenv run distribusi --help
## Release It ## Release It
You'll need a [PyPi](https://pypi.org/) account and to be added as a maintainer.
``` ```
$ make publish $ make publish
``` ```

98
distribusi/README.md Normal file
View File

@ -0,0 +1,98 @@
# Distribusi CMS
`distribusi` is a content management system for the web that produces static
index pages based on folders in the filesystem. It is inspired by the automatic
index functions featured in several web servers. It works by traversing the
file system and directory hierarchy to automatically list all the files in the
directory and providing them with html classes and tags for easy styling.
## Requirements
While a Pip install will pull in Python dependencies, you might need system
dependencies. This package requires two underlying packages. Those are
`python-magic`, and `pillow`. Here are the installation documentation for those
packages:
* [github.com/threatstack/libmagic](https://github.com/threatstack/libmagic)
* [pillow.readthedocs.io](https://pillow.readthedocs.io/en/5.3.x/installation.html#external-libraries)
## Installation
Using [--user] or [a virtual environment] is recommended:
[--user]: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
[a virtual environment]: https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments
```bash
$ pip install --user distribusi
```
Note: check if the path of your local bin is added to your shell path (otherwise you cannot run distribusi from the shell directly).
To check where distribusi is installed:
$ find * | grep distribusi
Add local bin to the $PATH variable:
$ PATH=$PATH:/home/USERNAME/.local/bin/
## Usage
Get help with:
```bash
$ distribusi --help
```
Make a distribusi of your home folder:
```bash
$ distribusi -d ~/
```
You will find that you now have an `index.html` in every folder.
Create a quick gallery for the web:
```
$ distribusi -d /path/to/my/photos -t
```
This creates an `index.html` with `base64` encoded thumbnails.
Generate verbose output:
```
$ distribusi -v
```
Make an index of the archive page:
```
$ distribusi -d /var/www/archive/my_event -t -v
```
# ✌
## Change It
Install [Pipenv] and then run:
[Pipenv]: https://pipenv.readthedocs.io/en/latest/install/#installing-pipenv
```
$ pipenv install --dev
$ pipenv run pip install -e .
$ pipenv run distribusi --help
```
## Release It
You'll need a [PyPi](https://pypi.org/) account and to be added as a maintainer.
```
$ make publish
```

View File

@ -1,6 +1,6 @@
import argparse import argparse
from distribusi.distribusi import distribusify from distribusi import distribusify
def build_argparser(): def build_argparser():
@ -56,4 +56,8 @@ def cli_entrypoint():
else: else:
directory = '.' directory = '.'
print('running distribusi ...')
distribusify(args, directory) distribusify(args, directory)
if __name__ == '__main__':
cli_entrypoint()

View File

@ -3,7 +3,7 @@ import os
from io import BytesIO from io import BytesIO
import magic import magic
from distribusi.page_template import html_footer, html_head from page_template import html_footer, html_head, styles
from PIL import Image from PIL import Image
@ -51,11 +51,11 @@ def div(mime, tag, *values):
id_name = values[0].split('.')[0].replace(' ', '_') id_name = values[0].split('.')[0].replace(' ', '_')
if 'image' in mime: if 'image' in mime:
html = '<div id="{}">{}<br><span class="filename">{}</span></div>' html = '<div class="{}">{}<span class="filename">{}</span></div>'
elif 'pdf' in mime: elif 'pdf' in mime:
html = '<div id="{}">{}<br><class="filename">{}</span></div>' html = '<div class="{}">{}<span class="filename">{}</span></div>'
else: else:
html = '<div id="{}">{}</div>' html = '<div class="{}">{}</div>'
return html.format(id_name, tag, values[0]) return html.format(id_name, tag, values[0])
@ -110,18 +110,31 @@ def distribusify(args, directory): # noqa
html.append(div(mime, a, name)) html.append(div(mime, a, name))
if root != directory: if root != directory:
html.append('<a href="../">../</a>') html.append('<a class="back" href="../">../</a>')
position = '../' * root.count('/')
stylesheet = '<link type="text/css" rel="stylesheet" href="{}stylesheet.css" />'.format(position)
else:
stylesheet = '<link type="text/css" rel="stylesheet" href="stylesheet.css" />'
for name in dirs: for name in dirs:
a = "<a href='{}' class='dir'>{}/</a>".replace('{}', name) a = "<a href='{}' class='dir'>{}/</a>".replace('{}', name)
html.append(div('dir', a, 'folder')) html.insert(0, div('dir', a, 'folder'))
with open(os.path.join(root, 'index.html'), 'w') as f: with open(os.path.join(root, 'index.html'), 'w') as f:
if not args.no_template: if not args.no_template:
f.write(html_head) header = html_head(stylesheet)
f.write(header)
h1 = '<h1 class="foldername">{}</h1>'.format(''.join(root))
print('path:', h1)
html.insert(0, h1)
for line in html: for line in html:
f.write(line+'\n') f.write(line+'\n')
if not args.no_template: if not args.no_template:
f.write(html_footer) f.write(html_footer)
print('adding a stylesheet to {}'.format(directory))
with open(os.path.join(directory, 'stylesheet.css'), 'w') as s:
s.write(styles)

View File

@ -1,21 +1,100 @@
html_head = """ def html_head(stylesheet):
header = """
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<!-- Generated with distribusi https://git.vvvvvvaria.org/rra/distribusi --> <!-- Generated with distribusi https://git.vvvvvvaria.org/rra/distribusi -->
<meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-type" content="text/html; charset=utf-8">
<style> {}
.image{max-width: 100%;}
.pdf {width:100%;}
div{width: 640px;float:left;padding:1em;}
video {width:640px;}
.dir::before{content:"📁";font-size:18px;}
</style>
</head> </head>
<body> <body>
""" """.format(stylesheet)
return header
html_footer = """ html_footer = """
</body> </body>
</html> </html>
""" """
styles = """
body{
position: absolute;
top:0;
left:0;
margin:3.5em 1em 1em 1em;
}
.stylesheet{
display: none;
}
h1.foldername{
margin: 0 0 1em 1.5em;
}
a{
text-decoration:none;
}
div{
width: 640px;
float:left;
padding:1em;
}
div.folder, div.README{
float: none;
padding: 0.5em 1em;
}
a.dir::before{
content:"📁";
font-size:18px;
padding-right: 1em;
text-decoration:none;
}
a.text::before{
content:"";
font-size:18px;
padding-right: 1em;
text-decoration:none;
}
a.back::before{
content:"";
font-size:18px;
padding-right: 1.25em;
text-decoration:none;
}
a.back{
position: fixed;
width:100%;
background-color:white;
top:0;
left:0;
padding:1em 1.5em;
}
.image{
max-width: 100%;
}
.pdf {
width:100%;
}
video {
width:640px;
}
.filename{
display:block;
font-size:small;
margin-top:0.5em;
}
@media only screen and (max-width: 600px) {
body{
width:calc(100% - 2em);
}
div {
width:calc(100% - 2em);
}
div a img{
width:100%;
}
}
"""