update (hehe)
This commit is contained in:
parent
6470b7f95b
commit
9bb5a690a0
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
.static/settings.json
|
||||||
venv/
|
venv/
|
||||||
+++/*.jpg
|
+++/*.jpg
|
||||||
+++/*.jpeg
|
+++/*.jpeg
|
||||||
@ -7,3 +8,4 @@ venv/
|
|||||||
+++/533201N0032129W_from_the_Sea_poster.png
|
+++/533201N0032129W_from_the_Sea_poster.png
|
||||||
+++/key.asc
|
+++/key.asc
|
||||||
+++/index.html
|
+++/index.html
|
||||||
|
.DS_Store
|
||||||
|
|||||||
5
.static/settings.template.json
Normal file
5
.static/settings.template.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"inputdir": "<>",
|
||||||
|
"outputdir": "<>",
|
||||||
|
"style": "<>"
|
||||||
|
}
|
||||||
345
gen.py
345
gen.py
@ -1,31 +1,13 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import sys, os, string, markdown, argparse, shutil, json, glob, re
|
import argparse, json, sys, markdown, shutil, json, re, pathlib, shutil
|
||||||
from distutils import dir_util as dirutil
|
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(description='Generates html file accroding to directory content');
|
input_dir = None
|
||||||
|
output_dir = None
|
||||||
input_dir = '../content/';
|
style = None
|
||||||
output_dir = '../deploy/';
|
codebase = pathlib.Path(__file__).parent.absolute()
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
global input_dir, output_dir, clean
|
|
||||||
arg_parser.add_argument('--input', help='input directory');
|
|
||||||
arg_parser.add_argument('--output', help='output directory');
|
|
||||||
arg_parser.add_argument('--clean', help='cleans the output directory');
|
|
||||||
args = arg_parser.parse_args();
|
|
||||||
if args.input and os.path.isdir(args.input):
|
|
||||||
input_dir = args.input;
|
|
||||||
if args.output and os.path.isdir(args.output):
|
|
||||||
output_dir = args.output;
|
|
||||||
|
|
||||||
def translate_index_header(txt, dirname):
|
def translate_index_header(txt, dirname):
|
||||||
try:
|
|
||||||
table = open(os.path.join('.', '<table>'), 'r+');
|
|
||||||
except:
|
|
||||||
print('error opening <table> file. aborting...');
|
|
||||||
sys.exit(0);
|
|
||||||
|
|
||||||
href = None
|
href = None
|
||||||
sections = txt.count('- - -');
|
sections = txt.count('- - -');
|
||||||
if sections == 0:
|
if sections == 0:
|
||||||
@ -43,7 +25,12 @@ def translate_index_header(txt, dirname):
|
|||||||
# revise this - perhaps with a better
|
# revise this - perhaps with a better
|
||||||
link_md = link_md.replace('data/', dirname + '/');
|
link_md = link_md.replace('data/', dirname + '/');
|
||||||
|
|
||||||
out = table.read().replace('[[text_md]]', text_md);
|
|
||||||
|
table = codebase / "templates/<table>"
|
||||||
|
with table.open(encoding="utf-8") as fp:
|
||||||
|
out = fp.read()
|
||||||
|
|
||||||
|
out = out.replace('[[text_md]]', text_md);
|
||||||
out = out.replace('[[link_md]]', link_md);
|
out = out.replace('[[link_md]]', link_md);
|
||||||
if href:
|
if href:
|
||||||
href = href.replace('data/', dirname + '/');
|
href = href.replace('data/', dirname + '/');
|
||||||
@ -53,19 +40,23 @@ def translate_index_header(txt, dirname):
|
|||||||
def escape_date(dirname):
|
def escape_date(dirname):
|
||||||
return re.sub('^20\d{2}?.', '', dirname)
|
return re.sub('^20\d{2}?.', '', dirname)
|
||||||
|
|
||||||
def emit_img(file, data_dir):
|
def emit_img(file: pathlib.Path, data_dir: pathlib.Path):
|
||||||
return '<a href="' + file + '"><img src="' + file + '" /></a>'
|
|
||||||
|
|
||||||
def emit_video_mp4(file, data_dir):
|
## this is where LOD can be applied
|
||||||
return '<video controls><source src="' + file + '" type="video/mp4"</video>'
|
|
||||||
|
|
||||||
def emit_audio(file, data_dir, full=False):
|
return f'<a href="{file}"><img src="{file}" /></a>'
|
||||||
|
|
||||||
|
def emit_video_mp4(file: pathlib.Path, data_dir: pathlib.Path):
|
||||||
|
return f'<video controls><source src="{file}" type="video/mp4"</video>'
|
||||||
|
|
||||||
|
def emit_audio(file: pathlib.Path, data_dir: pathlib.Path, full=False):
|
||||||
# an '.audio' file is a json file with a list of audio elements
|
# an '.audio' file is a json file with a list of audio elements
|
||||||
# which need to be bundles as a type of list in a single <li>
|
# which need to be bundles as a type of list in a single <li>
|
||||||
|
|
||||||
filename = os.path.join(data_dir, file);
|
file = data_dir / file;
|
||||||
with open(filename) as f:
|
if file.is_file():
|
||||||
audio = json.loads(f.read())
|
with file.open() as fp:
|
||||||
|
audio = json.loads(fp.read())
|
||||||
if full:
|
if full:
|
||||||
out = '<sound class="full">\n'
|
out = '<sound class="full">\n'
|
||||||
else:
|
else:
|
||||||
@ -91,7 +82,7 @@ def emit_audio(file, data_dir, full=False):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
return "to do to do to do"
|
return None
|
||||||
|
|
||||||
def emit_audio_full(file, data_dir):
|
def emit_audio_full(file, data_dir):
|
||||||
return emit_audio(file, data_dir, full=True)
|
return emit_audio(file, data_dir, full=True)
|
||||||
@ -111,37 +102,25 @@ content_map = {
|
|||||||
'.txt': default
|
'.txt': default
|
||||||
};
|
};
|
||||||
|
|
||||||
def index_content(dir_name, data_dir, index_txt, desc_txt, template):
|
def index_content(dir_name: str, data_dir: pathlib.Path, index_txt: pathlib.Path, desc_txt: pathlib.Path, template: str):
|
||||||
|
|
||||||
print(" indexing content -- " + dir_name);
|
print(" indexing content -- " + dir_name);
|
||||||
|
|
||||||
# desc_txt is a markdown file containing description
|
# desc_txt is a markdown file containing description
|
||||||
# for the project - no layout applied to it, only md
|
# for the project - no layout applied to it, only md
|
||||||
desc_md = None
|
desc_md = None
|
||||||
if os.path.isfile(desc_txt):
|
if desc_txt.is_file():
|
||||||
try:
|
with desc_txt.open(encoding="utf-8") as fp:
|
||||||
desc_file = open(desc_txt, 'r+');
|
desc_md = markdown.markdown(fp.read());
|
||||||
desc_md = markdown.markdown(desc_file.read());
|
|
||||||
# transform markdown
|
|
||||||
except:
|
|
||||||
print("error opening description file: " + desc_txt);
|
|
||||||
desc_md = None;
|
|
||||||
#return;
|
|
||||||
|
|
||||||
|
|
||||||
# index_txt is a json file containing one thing:
|
# index_txt is a json file containing one thing:
|
||||||
# an array of files names or glob patterns
|
# an array of files names or glob patterns
|
||||||
content_index = None
|
content_index = None
|
||||||
if os.path.isfile(index_txt):
|
if index_txt.is_file():
|
||||||
try:
|
with index_txt.open(encoding="utf-8") as fp:
|
||||||
index_file = open(index_txt, 'r+');
|
content_index = json.loads(fp.read());
|
||||||
content_index = json.loads(index_file.read());
|
|
||||||
except:
|
|
||||||
print("error opening index: " + index_txt);
|
|
||||||
content_index = None;
|
|
||||||
#return;
|
|
||||||
|
|
||||||
if desc_md == None and content_index == None:
|
if desc_md is None and content_index is None:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
content = ""
|
content = ""
|
||||||
@ -153,153 +132,213 @@ def index_content(dir_name, data_dir, index_txt, desc_txt, template):
|
|||||||
|
|
||||||
files = [];
|
files = [];
|
||||||
for i in content_index:
|
for i in content_index:
|
||||||
f = os.path.join(data_dir, i);
|
f = data_dir / i
|
||||||
if os.path.isfile(f):
|
if f.is_file():
|
||||||
files.append(i);
|
files.append(i);
|
||||||
else:
|
else:
|
||||||
files += [os.path.basename(a) for a in glob.glob(f)];
|
files += [pathlib.Path(a.name) for a in list(data_dir.glob(i))]
|
||||||
|
|
||||||
# sort files?
|
# sort files?
|
||||||
files.sort()
|
files.sort()
|
||||||
|
|
||||||
for j in files:
|
for j in files:
|
||||||
x, ext = os.path.splitext(j);
|
ext = j.suffix.lower()
|
||||||
ext = ext.lower()
|
|
||||||
if ext in content_map:
|
if ext in content_map:
|
||||||
element = content_map[ext](j, data_dir);
|
element = content_map[ext](j, data_dir);
|
||||||
if element:
|
if element:
|
||||||
content += "<li>" + element + "</li>" + "\n";
|
content += "<li>" + element + "</li>" + "\n";
|
||||||
|
|
||||||
#print content
|
html = template.replace('[[content]]', content).replace('[[dir]]', str(dir_name));
|
||||||
|
|
||||||
html = template.replace('[[content]]', content).replace('[[dir]]', dir_name);
|
|
||||||
|
|
||||||
#print html
|
|
||||||
|
|
||||||
#check if <Project Name>.txt exists (description file)
|
|
||||||
f = os.path.join(data_dir, "*.txt");
|
|
||||||
txt_files = [a for a in [os.path.basename(a) for a in glob.glob(f)] if a != 'index.txt' and a != 'desc.txt'];
|
|
||||||
if len(txt_files) == 1:
|
|
||||||
fn = txt_files[0];
|
|
||||||
link = '<li><a href="' + fn + '">' + fn + '</a></li>';
|
|
||||||
html = html.replace('<!--[[info]]-->', link);
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
out = open(os.path.join(data_dir, 'index.html'), 'w');
|
out = data_dir / 'index.html'
|
||||||
out.write(html);
|
with out.open('w', encoding="utf-8") as fp:
|
||||||
out.close();
|
fp.write(html);
|
||||||
|
return out
|
||||||
except:
|
except:
|
||||||
print('error creating content index output file. aborting...');
|
print('error creating content index output file. aborting...');
|
||||||
sys.exit(0);
|
return None
|
||||||
|
|
||||||
|
def check_dir_exists(dirpath, create=False):
|
||||||
|
d = pathlib.Path(dirpath)
|
||||||
|
if d.is_dir():
|
||||||
|
return d
|
||||||
|
elif create:
|
||||||
|
print(f"Directory {dirpath} is not a directory... Create it? [y/n]")
|
||||||
|
x = input()
|
||||||
|
if x.lower() == "y":
|
||||||
|
d.mkdir(parents=True)
|
||||||
|
return d
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
# #fix python markdown utf8 nonsense
|
p = argparse.ArgumentParser(description="SSSSTATIC generates html files from directory contents")
|
||||||
# reload(sys);
|
p.add_argument('--input', "-i", help='input directory');
|
||||||
# sys.setdefaultencoding('utf8');
|
p.add_argument('--output', "-o", help='output directory');
|
||||||
|
p.add_argument('--style', "-y", default="+++", help='css style, ico, etc.');
|
||||||
|
p.add_argument("--settings", "-s", default=".static/settings.json", help="Settings file (default: .static/settings.json")
|
||||||
|
p.add_argument('--clean', help='cleans the output directory');
|
||||||
|
|
||||||
|
args = p.parse_args();
|
||||||
|
|
||||||
|
if args.settings == ".static/settings.json":
|
||||||
|
file_settings = codebase / ".static/settings.json"
|
||||||
|
else:
|
||||||
|
file_settings = pathlib.Path(args.settings)
|
||||||
|
|
||||||
|
if file_settings.exists() and file_settings.is_file():
|
||||||
|
with file_settings.open(encoding="utf-8") as fp:
|
||||||
|
settings = json.load(fp)
|
||||||
|
input_dir = check_dir_exists(settings['inputdir'])
|
||||||
|
output_dir = check_dir_exists(settings['outputdir'])
|
||||||
|
style = settings['style']
|
||||||
|
|
||||||
|
if args.input:
|
||||||
|
inputdir = check_dir_exists(args.input)
|
||||||
|
if inputdir is not None:
|
||||||
|
input_dir = inputdir;
|
||||||
|
else:
|
||||||
|
print(f"Input directory {args.input} is not a directory... Aborting.")
|
||||||
|
sys.exit(1)
|
||||||
|
if args.output:
|
||||||
|
outputdir = check_dir_exists(args.output, create=True)
|
||||||
|
if outputdir is not None:
|
||||||
|
output_dir = outputdir;
|
||||||
|
else:
|
||||||
|
print(f"Output directory {args.output} is not a directory... Aborting.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if style is not None:
|
||||||
|
style_dir = codebase / f"styles/{style}"
|
||||||
|
if not style_dir.is_dir():
|
||||||
|
style = args.style
|
||||||
|
|
||||||
|
if input_dir is None:
|
||||||
|
print(f"Error with input directory... Aborting.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if output_dir is None:
|
||||||
|
print(f"No output directory.")
|
||||||
|
print(f"Dry-run test? [y/n]")
|
||||||
|
x = input()
|
||||||
|
if x.lower() == "n":
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
if output_dir.exists() and any(output_dir.iterdir()):
|
||||||
|
print(f"? {output_dir} exists and is not empty. Erase content? [y/n]")
|
||||||
|
x = input()
|
||||||
|
if x.lower() == "y":
|
||||||
|
try:
|
||||||
|
shutil.rmtree(output_dir)
|
||||||
|
except:
|
||||||
|
print(f"error erasing {output_dir}. Continuing.")
|
||||||
|
|
||||||
parse_args();
|
|
||||||
|
|
||||||
print('1/3 - Configuring');
|
print('1/3 - Configuring');
|
||||||
|
|
||||||
# main index template
|
# main index template
|
||||||
try:
|
indx_template = codebase / "templates/index_template.html"
|
||||||
template = open(os.path.join('.', 'index_template.html'), 'r+');
|
with indx_template.open(encoding="utf-8") as fp:
|
||||||
except:
|
indx_template_str = fp.read()
|
||||||
print('error opening template file. aborting...');
|
|
||||||
sys.exit(0);
|
|
||||||
|
|
||||||
# images index template
|
# images index template
|
||||||
try:
|
section_indx_template = codebase / "templates/index_apache_template.html"
|
||||||
content_indx_template = open(os.path.join('.', 'index_apache_template.html'), 'r+');
|
with section_indx_template.open(encoding="utf-8") as fp:
|
||||||
content_index_template_str = content_indx_template.read();
|
section_indx_template_str = fp.read()
|
||||||
except:
|
|
||||||
print('error opening template file. aborting...');
|
|
||||||
sys.exit(0);
|
|
||||||
|
|
||||||
if not os.path.exists(output_dir):
|
|
||||||
os.mkdir(output_dir);
|
|
||||||
|
|
||||||
try:
|
|
||||||
out = open(os.path.join(output_dir, 'index.html'), 'w');
|
|
||||||
except:
|
|
||||||
print('error creating output file. aborting...');
|
|
||||||
sys.exit(0);
|
|
||||||
|
|
||||||
print('2/3 - Parsing input');
|
print('2/3 - Parsing input');
|
||||||
|
|
||||||
dirs = [d for d in os.listdir(input_dir) if not d == '_system' and os.path.isdir(os.path.join(input_dir,d))];
|
dirs = sorted([d for d in input_dir.iterdir() if d.is_dir()])
|
||||||
|
|
||||||
content = '';
|
|
||||||
|
|
||||||
dirs.sort(); # dirs should be date-named
|
|
||||||
|
|
||||||
|
content = ''
|
||||||
for d in reversed(dirs):
|
for d in reversed(dirs):
|
||||||
dd = os.path.join(input_dir,d);
|
indx_txt = d / 'index.txt'
|
||||||
indx_txt = os.path.join(dd, 'index.txt');
|
|
||||||
if os.path.isfile(indx_txt):
|
if not indx_txt.exists():
|
||||||
|
print(f"{indx_txt} does not exists. Skipping.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
with indx_txt.open(encoding="utf-8") as fp:
|
||||||
|
txt = fp.read()
|
||||||
|
|
||||||
|
dirname = escape_date(d.name)
|
||||||
|
|
||||||
|
content += translate_index_header(txt, dirname);
|
||||||
|
|
||||||
|
datadir = d / "data"
|
||||||
|
if datadir.is_dir():
|
||||||
|
section_indx_txt = datadir / "index.txt"
|
||||||
|
section_desc_txt = datadir / "desc.txt"
|
||||||
|
|
||||||
|
if section_indx_txt.is_file() or section_desc_txt.is_file():
|
||||||
|
out_index = index_content(dirname, d, section_indx_txt, section_desc_txt, section_indx_template_str);
|
||||||
|
|
||||||
|
if out_index is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if output_dir is not None:
|
||||||
|
out_datadir = output_dir / dirname
|
||||||
|
|
||||||
|
if out_datadir.exists() and any(out_datadir.iterdir()):
|
||||||
|
print(f" ? {out_datadir} exists and is not empty. Erase content? [y/n]")
|
||||||
|
x = input()
|
||||||
|
if x.lower() == "y":
|
||||||
try:
|
try:
|
||||||
indx = open(indx_txt, 'r+');
|
shutil.rmtree(out_datadir)
|
||||||
except:
|
except:
|
||||||
print("error opening index: " + indx_txt);
|
print(f"error erasing {out_datadir}. Continuing.")
|
||||||
continue;
|
|
||||||
|
|
||||||
txt = indx.read();
|
|
||||||
dirname = os.path.basename(dd);
|
|
||||||
newdirname = escape_date(dirname) # trim date out of url -- permalink
|
|
||||||
content += translate_index_header(txt, newdirname);
|
|
||||||
content += '\n<br>\n';
|
|
||||||
|
|
||||||
# data dir / content
|
|
||||||
data_dir = os.path.join(dd, 'data');
|
|
||||||
if os.path.isdir(data_dir):
|
|
||||||
|
|
||||||
#check if content needs index -- index.txt is a json file
|
|
||||||
content_indx_txt = os.path.join(data_dir, 'index.txt');
|
|
||||||
|
|
||||||
#check if there is a description file -- desc.txt is a markdown file
|
|
||||||
content_desc_txt = os.path.join(data_dir, 'desc.txt');
|
|
||||||
|
|
||||||
if os.path.isfile(content_indx_txt) or os.path.isfile(content_desc_txt):
|
|
||||||
index_content(d, data_dir, content_indx_txt, content_desc_txt, content_index_template_str);
|
|
||||||
|
|
||||||
|
|
||||||
#copy content
|
|
||||||
out_data_dir = os.path.join(output_dir, newdirname);
|
|
||||||
try:
|
try:
|
||||||
dirutil.copy_tree(data_dir, out_data_dir);
|
shutil.copytree(datadir, out_datadir, ignore=shutil.ignore_patterns('.DS_Store'), dirs_exist_ok=True)
|
||||||
except:
|
except:
|
||||||
print("error copying " + data_dir + " to " + out_data_dir + ". Continuing.")
|
print(f"error copying {datadir} to {out_datadir}. Continuing.")
|
||||||
continue;
|
continue
|
||||||
|
|
||||||
|
# copy index after (since index.html might be lurking in content dirs)
|
||||||
|
try:
|
||||||
|
shutil.copy2(out_index, out_datadir)
|
||||||
|
except:
|
||||||
|
print(f"error copying {out_index} to {out_datadir}. Continuing.")
|
||||||
|
continue
|
||||||
|
|
||||||
print('3/3 - Generating ouput');
|
print('3/3 - Generating ouput');
|
||||||
|
|
||||||
html = template.read().replace('[[content]]', content);
|
html = indx_template_str.replace('[[content]]', content);
|
||||||
|
|
||||||
out.write(html);
|
if output_dir is not None:
|
||||||
|
|
||||||
style_in = os.path.join('.', '+++');
|
out = output_dir / "index.html"
|
||||||
style_out = os.path.join(output_dir, '+++');
|
out.write_text(html, encoding="utf-8")
|
||||||
|
|
||||||
|
# style
|
||||||
|
style_dir = codebase / f"styles/{style}"
|
||||||
|
if not style_dir.is_dir():
|
||||||
|
print(f"{style} does not exists (make sure to add a style to styles/)... going vanilla")
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
dirutil.copy_tree(style_in, style_out);
|
out_style_dir = output_dir / style
|
||||||
except IOError as err:
|
shutil.copytree(style_dir, out_style_dir, ignore=shutil.ignore_patterns('.DS_Store'), dirs_exist_ok=True)
|
||||||
print(err);
|
except:
|
||||||
|
print(f"error copying {style_dir} to {out_style_dir}. Continuing.")
|
||||||
|
|
||||||
|
|
||||||
# robots.txt?
|
# robots.txt?
|
||||||
robots_in = os.path.join('.', 'robots.txt')
|
robots = codebase / "templates/robots.txt"
|
||||||
if os.path.isfile(indx_txt):
|
if robots.is_file():
|
||||||
shutil.copy(robots_in, output_dir)
|
try:
|
||||||
|
shutil.copy(robots, output_dir)
|
||||||
|
except:
|
||||||
|
print(f"error copying {robots} to {output_dir}. Continuing.")
|
||||||
|
|
||||||
# .htaccess?
|
# .htaccess?
|
||||||
ht_in = os.path.join('.', '.htaccess')
|
ht = codebase / "templates/.htaccess"
|
||||||
if os.path.isfile(indx_txt):
|
if ht.is_file():
|
||||||
shutil.copy(ht_in, output_dir)
|
try:
|
||||||
|
shutil.copy(ht, output_dir)
|
||||||
template.close();
|
except:
|
||||||
content_indx_template.close();
|
print(f"error copying {ht} to {output_dir}. Continuing.")
|
||||||
out.close();
|
|
||||||
|
|
||||||
print('done.');
|
print('done.');
|
||||||
BIN
styles/+++/back.gif
Normal file
BIN
styles/+++/back.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 216 B |
BIN
styles/+++/david-gauthier.jpg
Normal file
BIN
styles/+++/david-gauthier.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
77
styles/+++/index.html
Normal file
77
styles/+++/index.html
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- <link rel="stylesheet" type="text/css" href="lestyle.css"/> -->
|
||||||
|
<style>
|
||||||
|
.rototo {
|
||||||
|
width: 500px;
|
||||||
|
animation: alors 20000ms infinite linear;
|
||||||
|
}
|
||||||
|
@keyframes alors {
|
||||||
|
50% {
|
||||||
|
transform: rotateY(360deg) rotateX(-180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div align="center">
|
||||||
|
<img class="rototo" src="david-gauthier.jpg">
|
||||||
|
<pre>
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=rlRS
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
</pre>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
styles/+++/jules-henri.ico
Normal file
BIN
styles/+++/jules-henri.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 798 B |
143
styles/+++/lestyle.css
Normal file
143
styles/+++/lestyle.css
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableau {
|
||||||
|
border: 10px grey ridge;
|
||||||
|
margin: 5em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
display: block;
|
||||||
|
margin: 1em;
|
||||||
|
border: 10px grey ridge;
|
||||||
|
font-size: small;
|
||||||
|
text-align: left;
|
||||||
|
width: 55em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
border: 2px grey ridge;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td h1 {
|
||||||
|
bborder: 1px red solid;
|
||||||
|
margin-top: 0.4em;
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td p {
|
||||||
|
bborder: 1px red solid;
|
||||||
|
margin-top: 0.1em;
|
||||||
|
margin-bottom: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table tr {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td img {
|
||||||
|
width: 100%;
|
||||||
|
border: 2px grey ridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst {
|
||||||
|
margin-right: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst p mat {
|
||||||
|
margin-left: : 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li { display: inline; }
|
||||||
|
|
||||||
|
.lst ul li desc {
|
||||||
|
margin: 2em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
width: 985;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li desc img {
|
||||||
|
border: 10px grey ridge;
|
||||||
|
margin: 0em;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
width: 985;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li desc video {
|
||||||
|
border: 10px grey ridge;
|
||||||
|
margin: 0em;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
width: 985;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li img {
|
||||||
|
border: 10px grey ridge;
|
||||||
|
margin: 2em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
width: 450;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li video {
|
||||||
|
border: 10px grey ridge;
|
||||||
|
margin: 2em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
width: 450;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li sound {
|
||||||
|
display: inline-block;
|
||||||
|
border: 10px grey ridge;
|
||||||
|
margin: 2em;
|
||||||
|
width: 440;
|
||||||
|
padding: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li sound track {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0.3em;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li sound info {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li sound audio {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li lo img {
|
||||||
|
border: none;
|
||||||
|
margin: 1em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
max-width: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lst ul li la img {
|
||||||
|
border: none;
|
||||||
|
margin: 1em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
max-width: 100;
|
||||||
|
max-height: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#index_tile h1 {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1
templates/.htaccess
Normal file
1
templates/.htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
RedirectMatch 404 /\.git
|
||||||
12
templates/<table>
Normal file
12
templates/<table>
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
[[text_md]]
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
[[link_md]]
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
24
templates/index_apache_template.html
Normal file
24
templates/index_apache_template.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="icon" href="../+++/jules-henri.ico" type="image/x-icon">
|
||||||
|
<title>Index of /gauthiier.info/[[dir]]</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../+++/lestyle.css"/>
|
||||||
|
<meta name="keywords" content="david gauthier, gauthiier, davidgauthier, dviid">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="index_tile"><h1>Index of /gauthiier.info/[[dir]]</h1></div>
|
||||||
|
<div style=" margin-left: 20px;">
|
||||||
|
<a href=".."><img src="../+++/back.gif"></a>
|
||||||
|
<a href=".." style=" margin-left: 5px;"> Parent Directory</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="lst">
|
||||||
|
<ul>
|
||||||
|
[[content]]
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<address>Apache Server at gauthiier.info Port 80</address>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
23
templates/index_template.html
Normal file
23
templates/index_template.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="keywords" content="david gauthier, gauthiier, davidgauthier, dviid">
|
||||||
|
<meta name="description" content="David Gauthier (b.1979, CA) - selected index of works">
|
||||||
|
<link rel="icon" href="+++/jules-henri.ico" type="image/x-icon">
|
||||||
|
<link rel="stylesheet" type="text/css" href="+++/lestyle.css"/>
|
||||||
|
<link rel="pgpkey" href="+++/key.asc"/>
|
||||||
|
<link rel="openid.delegate" href="http://gauthiier.info/" />
|
||||||
|
<link rel="openid.server" href="https://indieauth.com/openid" />
|
||||||
|
<title>David Gauthier</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div align="center">
|
||||||
|
<a href="+++/"><img src="+++/yeux.png" width="500" class="tableau"></a>
|
||||||
|
<h4>David Gauthier</h4>
|
||||||
|
<h1><i>(Selected) Index of works</i></h1>
|
||||||
|
<h4><a href="https://www.uu.nl/medewerkers/DGauthier">index of academic work</a></h4>
|
||||||
|
<h4>d[at]gauthiier.info</h4>
|
||||||
|
[[content]]
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
templates/robots.txt
Normal file
2
templates/robots.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /+++/
|
||||||
61
utils/wavconv.py
Normal file
61
utils/wavconv.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import argparse, sys, os, glob, subprocess
|
||||||
|
|
||||||
|
supported = ['ogg', 'mp3']
|
||||||
|
|
||||||
|
def sanity_check_system():
|
||||||
|
r = subprocess.call("ffmpeg -version", shell=True) == 0
|
||||||
|
if not r:
|
||||||
|
sys.exit("ffmpeg not installed. Aborting...")
|
||||||
|
|
||||||
|
def convert(i, o, f):
|
||||||
|
global supported
|
||||||
|
if f not in supported:
|
||||||
|
print("warning: format " + f + "is not supported")
|
||||||
|
return
|
||||||
|
|
||||||
|
if f == 'mp3':
|
||||||
|
codec = 'libmp3lame'
|
||||||
|
elif f == 'ogg':
|
||||||
|
codec = 'libvorbis'
|
||||||
|
|
||||||
|
subprocess.call(['ffmpeg', '-i', i, '-acodec', codec, o])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
p = argparse.ArgumentParser(description='Converts .wav files to other formats (using ffmpeg)');
|
||||||
|
p.add_argument('-i', '--input', help='input directory');
|
||||||
|
p.add_argument('-f', '--format', help='output formats (ogg and/or mp3)', nargs="+");
|
||||||
|
|
||||||
|
sanity_check_system()
|
||||||
|
|
||||||
|
args = p.parse_args()
|
||||||
|
|
||||||
|
if not args.format:
|
||||||
|
sys.exit("Nor formats specified. Aborting.")
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
for f in args.format:
|
||||||
|
if f not in supported:
|
||||||
|
print("warning: format " + f + "is not supported")
|
||||||
|
else:
|
||||||
|
formats.append(f)
|
||||||
|
|
||||||
|
if not formats:
|
||||||
|
sys.exit("None of the specified formats are supported. Aborting.")
|
||||||
|
|
||||||
|
input_dir = "."
|
||||||
|
if args.input:
|
||||||
|
input_dir = args.input
|
||||||
|
|
||||||
|
wav_files = glob.glob(os.path.join(input_dir, "*.wav"))
|
||||||
|
for w in wav_files:
|
||||||
|
for f in formats:
|
||||||
|
fn = os.path.join(input_dir, os.path.basename(w).replace('.wav', '.' + f))
|
||||||
|
convert(w, fn, f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user