Commit 0d6c6171 authored by Denis Salem's avatar Denis Salem
Browse files

Fix minor bugs, add theme dependency management

parent 6157bc78
......@@ -159,9 +159,9 @@
DONE | Fix Shabang issue for compatibility.
DONE | Semantic-web features.
DONE | Theme must have it's own yaml configuration.
WIP | Client-side search engine.
WIP | Reorganize themes dependencies in setup (adding default templates, scripts, and pages to include).
WIP | Add relevant templates for themes.
WIP | Client-side search engine.
TODO | Add definition in documentation for optional fields in blog configuration.
TODO | Change nomenclature: Most of the usual patterns are changed. Fix doc.
......
......@@ -17,19 +17,21 @@
# You should have received a copy of the GNU General Public License
# along with VenC. If not, see <http://www.gnu.org/licenses/>.
from os.path import expanduser, isdir
from os import listdir
from setuptools import setup
import os
dst_themes_path = os.path.expanduser('~')+"/.local/share/VenC/themes/"
dst_themes_path = expanduser('~')+"/.local/share/VenC/themes/"
src_themes_path = "share/themes/"
themes = os.listdir(src_themes_path)
themes = listdir(src_themes_path)
extra_files = []
for theme in themes:
for filename in os.listdir(src_themes_path+theme+'/'):
if os.path.isdir(src_themes_path+theme+'/'+filename):
for filename in listdir(src_themes_path+theme+'/'):
if isdir(src_themes_path+theme+'/'+filename):
dst = dst_themes_path+theme+'/'+filename
src_files = [src_themes_path+theme+'/'+filename+'/'+f for f in os.listdir(src_themes_path+theme+'/'+filename)]
src_files = [src_themes_path+theme+'/'+filename+'/'+f for f in listdir(src_themes_path+theme+'/'+filename)]
else:
dst = dst_themes_path+theme
......@@ -42,9 +44,11 @@ for theme in themes:
))
extra_files.append((os.path.expanduser('~')+"/.local/share/VenC/embed_providers/",["share/embed_providers/oembed.json"]))
extra_files.append((expanduser('~')+"/.local/share/VenC/embed_providers/", ["share/embed_providers/oembed.json"]))
extra_files.append((expanduser('~')+"/.local/share/VenC/themes_assets", ["share/themes_assets/"+filename for filename in listdir("share/themes_assets")]) )
setup(name='VenC',
setup(
name='VenC',
version='2.0.0',
description='A static blog generator.',
author='Denis Salem',
......
......@@ -3,3 +3,6 @@ info:
override:
columns: 1
dependencies: ['VenC-Categories-0.0.0.js']
/*
* Copyright 2016, 2019 Denis Salem
*
* This file is part of VenC.
*
* VenC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* VenC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VenC. If not, see <http://www.gnu.org/licenses/>.
*/
var VENC_INFINITE_SCROLL = {
queue: 0,
end: false,
hideVenCNavigation: true,
pageHook : "",
interval : 250,
xmlhttp : Object,
timer: Object,
imageDefaultSetup: function(img) {},
entryDefaultSetup: function(entry) {
entry.style.opacity = "0.0";
},
onLoadImage: function(img) {},
onLoadEntry: function(entry){
entry.style.transition = "opacity 0.5s ease";
entry.style.opacity = "1.0";
},
loading : function() {
try {
document.getElementById("__VENC_LOADING__").style.opacity = "1";
}
catch (e) {
console.log("VenC: There is no __VENC_LOADING__ element.");
}
},
idle : function() {
try {
document.getElementById("__VENC_LOADING__").style.opacity = "0";
}
catch (e) {
console.log("VenC: There is no __VENC_LOADING__ element.");
}
},
getPageHook : function() {
v = document.querySelectorAll('[data-venc-api-infinite-scroll-hook]')
if (v.length == 1) {
this.pageHook = v[0].dataset.vencApiInfiniteScrollHook;
console.log("VenC: Hook", this.pageHook);
}
else if (v.length > 1) {
console.log("VenC: There is more than one infinite scroll hook in DOM. Aborting...")
this.end = true;
return
}
else {
console.log("VenC: Infinite Scroll hook not found. Exiting...");
this.end = true;
return;
}
},
getContent : function() {
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
this.xmlhttp = new XMLHttpRequest();
}
else { // code for IE6, IE5
this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
this.xmlhttp.onreadystatechange = this.domUpdate;
this.xmlhttp.open("GET", this.pageHook, true);
this.xmlhttp.send();
},
dontWait: false,
currentLocation : Object,
domUpdate : Object
};
function VENC_INFINITE_SCROLL_UPDATE_DOM() {
if (VENC_INFINITE_SCROLL.xmlhttp.readyState == 4 && VENC_INFINITE_SCROLL.xmlhttp.status == 200) {
xmlDoc = document.implementation.createHTMLDocument('');
xmlDoc.body.innerHTML = VENC_INFINITE_SCROLL.xmlhttp.responseText;
currentColumns = document.getElementsByClassName("__VENC_COLUMN__");
newColumns = xmlDoc.getElementsByClassName("__VENC_COLUMN__");
for (i=0; i < currentColumns.length; i++) {
newEntries = newColumns[i].getElementsByClassName("entry");
entriesClones = Array();
for (j=0; j < newEntries.length; j++) {
entriesClones.push( newEntries[j].cloneNode(true));
}
for(j=0; j < entriesClones.length; j++) {
VENC_INFINITE_SCROLL.entryDefaultSetup(entriesClones[j]);
images = entriesClones[j].getElementsByTagName("img");
if (images.length == 0) {
VENC_INFINITE_SCROLL.onLoadEntry(entriesClones[j]);
}
else {
for (k=0; k < images.length; k++) {
VENC_INFINITE_SCROLL.queue++;
VENC_INFINITE_SCROLL.imageDefaultSetup(images[k]);
images[k].loaded = false;
images[k].onerror = function(e) {
this.onload(e);
}
images[k].onload = function(e) {
this.loaded = true;
VENC_INFINITE_SCROLL.queue--;
VENC_INFINITE_SCROLL.onLoadImage(this);
for(l = 0; l < images.lenght; l) {
if (images[l].loaded == false) {
return;
}
}
VENC_INFINITE_SCROLL.onLoadEntry(this.closest(".entry"));
}
d = new Date()
images[k].src = images[k].src+"?uglyWorkAround="+d.getTime();
}
}
currentColumns[i].appendChild(entriesClones[j]);
}
}
// Update Hook
new_hook = xmlDoc.querySelectorAll('[data-venc-api-infinite-scroll-hook]')
old_hook = document.querySelectorAll('[data-venc-api-infinite-scroll-hook]')
if (new_hook.length == 1) {
// There is no verificaton because hook exists at this point of code.
oh = old_hook[0];
old_hook_parent = oh.parentNode;
old_hook_parent.replaceChild(new_hook[0], oh);
VENC_INFINITE_SCROLL.getPageHook();
}
else {
console.log("VenC: Infinite Scroll hook not found. Exiting...");
VENC_INFINITE_SCROLL.end = true;
}
}
};
function VENC_INFINITE_SCROLL_RUN() {
if (VENC_INFINITE_SCROLL.end) {
clearInterval(VENC_INFINITE_SCROLL.timer);
console.log("VenC: Done.")
return;
}
if (VENC_INFINITE_SCROLL.queue == 0) {
VENC_INFINITE_SCROLL.idle();
}
else {
VENC_INFINITE_SCROLL.loading();
}
currentColumns = document.getElementsByClassName("__VENC_COLUMN__");
viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
for (i=0; i < currentColumns.length; i++) {
if (currentColumns[i].clientHeight <= viewPortHeight + window.pageYOffset) {
if ((VENC_INFINITE_SCROLL.queue == 0 || VENC_INFINITE_SCROLL.dontWait) && !VENC_INFINITE_SCROLL.end) {
VENC_INFINITE_SCROLL.getContent();
return 1;
}
}
}
return 0;
};
function VENC_INFINITE_SCROLL_ON_LOAD() {
VENC_INFINITE_SCROLL.currentLocation = window.location.pathname.split('/')[window.location.pathname.split('/').length-1]
VENC_INFINITE_SCROLL.getPageHook()
if (VENC_INFINITE_SCROLL.hideVenCNavigation) {
try {
document.getElementById("__VENC_NAVIGATION__").setAttribute("style","display: none;");
}
catch (e) {
console.log("VenC: There is no __VENC_NAVIGATION__ element.");
}
}
if (VENC_INFINITE_SCROLL.end == false) {
console.log("there")
VENC_INFINITE_SCROLL.domUpdate = VENC_INFINITE_SCROLL_UPDATE_DOM;
VENC_INFINITE_SCROLL.timer = setInterval(VENC_INFINITE_SCROLL_RUN, VENC_INFINITE_SCROLL.interval);
}
};
......@@ -3,3 +3,5 @@ info:
override:
columns: 1
dependencies: ['VenC-Infinite-Scroll-1.1.0.js']
/*
* Copyright 2016, 2019 Denis Salem
*
* This file is part of VenC.
*
* VenC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* VenC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VenC. If not, see <http://www.gnu.org/licenses/>.
*/
var VENC_INFINITE_SCROLL = {
queue: 0,
end: false,
hideVenCNavigation: true,
pageHook : "",
interval : 250,
xmlhttp : Object,
timer: Object,
imageDefaultSetup: function(img) {},
entryDefaultSetup: function(entry) {
entry.style.opacity = "0.0";
},
onLoadImage: function(img) {},
onLoadEntry: function(entry){
entry.style.transition = "opacity 0.5s ease";
entry.style.opacity = "1.0";
},
loading : function() {
try {
document.getElementById("__VENC_LOADING__").style.opacity = "1";
}
catch (e) {
console.log("VenC: There is no __VENC_LOADING__ element.");
}
},
idle : function() {
try {
document.getElementById("__VENC_LOADING__").style.opacity = "0";
}
catch (e) {
console.log("VenC: There is no __VENC_LOADING__ element.");
}
},
getPageHook : function() {
v = document.querySelectorAll('[data-venc-api-infinite-scroll-hook]')
if (v.length == 1) {
this.pageHook = v[0].dataset.vencApiInfiniteScrollHook;
console.log("VenC: Hook", this.pageHook);
}
else if (v.length > 1) {
console.log("VenC: There is more than one infinite scroll hook in DOM. Aborting...")
this.end = true;
return
}
else {
console.log("VenC: Infinite Scroll hook not found. Exiting...");
this.end = true;
return;
}
},
getContent : function() {
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
this.xmlhttp = new XMLHttpRequest();
}
else { // code for IE6, IE5
this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
this.xmlhttp.onreadystatechange = this.domUpdate;
this.xmlhttp.open("GET", this.pageHook, true);
this.xmlhttp.send();
},
dontWait: false,
currentLocation : Object,
domUpdate : Object
};
function VENC_INFINITE_SCROLL_UPDATE_DOM() {
if (VENC_INFINITE_SCROLL.xmlhttp.readyState == 4 && VENC_INFINITE_SCROLL.xmlhttp.status == 200) {
xmlDoc = document.implementation.createHTMLDocument('');
xmlDoc.body.innerHTML = VENC_INFINITE_SCROLL.xmlhttp.responseText;
currentColumns = document.getElementsByClassName("__VENC_COLUMN__");
newColumns = xmlDoc.getElementsByClassName("__VENC_COLUMN__");
for (i=0; i < currentColumns.length; i++) {
newEntries = newColumns[i].getElementsByClassName("entry");
entriesClones = Array();
for (j=0; j < newEntries.length; j++) {
entriesClones.push( newEntries[j].cloneNode(true));
}
for(j=0; j < entriesClones.length; j++) {
VENC_INFINITE_SCROLL.entryDefaultSetup(entriesClones[j]);
images = entriesClones[j].getElementsByTagName("img");
if (images.length == 0) {
VENC_INFINITE_SCROLL.onLoadEntry(entriesClones[j]);
}
else {
for (k=0; k < images.length; k++) {
VENC_INFINITE_SCROLL.queue++;
VENC_INFINITE_SCROLL.imageDefaultSetup(images[k]);
images[k].loaded = false;
images[k].onerror = function(e) {
this.onload(e);
}
images[k].onload = function(e) {
this.loaded = true;
VENC_INFINITE_SCROLL.queue--;
VENC_INFINITE_SCROLL.onLoadImage(this);
for(l = 0; l < images.lenght; l) {
if (images[l].loaded == false) {
return;
}
}
VENC_INFINITE_SCROLL.onLoadEntry(this.closest(".entry"));
}
d = new Date()
images[k].src = images[k].src+"?uglyWorkAround="+d.getTime();
}
}
currentColumns[i].appendChild(entriesClones[j]);
}
}
// Update Hook
new_hook = xmlDoc.querySelectorAll('[data-venc-api-infinite-scroll-hook]')
old_hook = document.querySelectorAll('[data-venc-api-infinite-scroll-hook]')
if (new_hook.length == 1) {
// There is no verificaton because hook exists at this point of code.
oh = old_hook[0];
old_hook_parent = oh.parentNode;
old_hook_parent.replaceChild(new_hook[0], oh);
VENC_INFINITE_SCROLL.getPageHook();
}
else {
console.log("VenC: Infinite Scroll hook not found. Exiting...");
VENC_INFINITE_SCROLL.end = true;
}
}
};
function VENC_INFINITE_SCROLL_RUN() {
if (VENC_INFINITE_SCROLL.end) {
clearInterval(VENC_INFINITE_SCROLL.timer);
console.log("VenC: Done.")
return;
}
if (VENC_INFINITE_SCROLL.queue == 0) {
VENC_INFINITE_SCROLL.idle();
}
else {
VENC_INFINITE_SCROLL.loading();
}
currentColumns = document.getElementsByClassName("__VENC_COLUMN__");
viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
for (i=0; i < currentColumns.length; i++) {
if (currentColumns[i].clientHeight <= viewPortHeight + window.pageYOffset) {
if ((VENC_INFINITE_SCROLL.queue == 0 || VENC_INFINITE_SCROLL.dontWait) && !VENC_INFINITE_SCROLL.end) {
VENC_INFINITE_SCROLL.getContent();
return 1;
}
}
}
return 0;
};
function VENC_INFINITE_SCROLL_ON_LOAD() {
VENC_INFINITE_SCROLL.currentLocation = window.location.pathname.split('/')[window.location.pathname.split('/').length-1]
VENC_INFINITE_SCROLL.getPageHook()
if (VENC_INFINITE_SCROLL.hideVenCNavigation) {
try {
document.getElementById("__VENC_NAVIGATION__").setAttribute("style","display: none;");
}
catch (e) {
console.log("VenC: There is no __VENC_NAVIGATION__ element.");
}
}
if (VENC_INFINITE_SCROLL.end == false) {
console.log("there")
VENC_INFINITE_SCROLL.domUpdate = VENC_INFINITE_SCROLL_UPDATE_DOM;
VENC_INFINITE_SCROLL.timer = setInterval(VENC_INFINITE_SCROLL_RUN, VENC_INFINITE_SCROLL.interval);
}
};
</div>
<footer id="__VENC_NAVIGATION__">
.:GetPreviousPage:: <a id="previous" href="{destination_page_url} "></a>:.
.:GetPreviousPage:: <a id="previous" href="{path} "></a>:.
<ul id="pagesList">.:ForPages::5::<li><a href="{path}">{page_number}</a></li>:: . :.</ul>
.:GetNextPage:: <a id="next" href="{destination_page_url} "></a>:.
.:GetNextPage:: <a id="next" href="{path} "></a>:.
</footer>
</body>
</html>
......@@ -3,3 +3,5 @@ info:
override:
columns: 3
dependencies: ['VenC-Infinite-Scroll-1.1.0.js']
......@@ -40,6 +40,8 @@ start_timestamp = time.time()
datastore = DataStore()
code_highlight = CodeHighlight(datastore.blog_configuration["code_highlight_css_override"])
theme_dependencies = []
def copy_recursively(src, dest):
import errno
for filename in os.listdir(src):
......@@ -72,6 +74,10 @@ def init_theme(argv):
if "override" in config.keys() and type(config["override"]) == dict:
for param in config["override"].keys():
datastore.blog_configuration[param] = config["override"][param]
if "dependencies" in config.keys() and type(config["dependencies"]) == list:
global theme_dependencies
theme_dependencies = config["dependencies"]
try:
return Theme(theme_folder), theme_folder
......@@ -173,6 +179,8 @@ def export_blog(argv=list()):
code_highlight.export_style_sheets()
copy_recursively("extra/","blog/")
copy_recursively(theme_folder+"assets/","blog/")
for depenpency in theme_dependencies:
shutil.copyfile(os.path.expanduser("~")+"/.local/share/VenC/themes_assets/"+depenpency, "blog/"+depenpency)
notify(messages.task_done_in_n_seconds.format(round(time.time() - start_timestamp,6)))
......
......@@ -109,5 +109,6 @@ class Messages:
task_done_in_n_seconds = "Task done in {0} seconds."
nothing_to_serv = "Nothing to do. Try venc -xb before."
theme_has_no_description = "This theme has no description."
undefined_variable = "{0} is undefined in {1}."
......@@ -107,4 +107,5 @@ class Messages:
task_done_in_n_seconds = "Tache réalisée en {0} seconds."
nothing_to_serv = "Rien à faire. Essayez venc -xb d'abord."
theme_has_no_description = "Ce thème n'a pas de description."
undefined_variable = "{0} n'est pas défini dans \"{1}\"."
......@@ -27,6 +27,20 @@ from venc2.l10n import messages
from venc2.patterns.exceptions import PatternInvalidArgument
from venc2.patterns.processor import Processor
current_source = None
def undefined_variable(match):
die(
messages.undefined_variable.format(
match,
current_source.ressource
),
extra=current_source.string.replace(
match[1:-1],
'\033[91m'+match[1:-1]+'\033[0m'
)
)
class Thread:
def __init__(self, prompt, datastore, theme, patterns_map):
self.indentation_level = "│ "
......@@ -60,8 +74,12 @@ class Thread:
self.processor.set_function(pattern_name, getattr(self, patterns_map.contextual["names"][pattern_name]))
def return_page_around(self, string, params):
return string.format(**params)
try:
return string.format(**params)
except KeyError as e:
self.undefined_variable(str(e))
# Must be called in child class
def get_relative_location(self, argv):
return self.export_path[5:]
......@@ -97,8 +115,12 @@ class Thread:
except AttributeError:
pass
return argv[0].format(**params)
try:
return argv[0].format(**params)
except KeyError as e:
undefined_variable(str(e))
else:
return str()
......@@ -124,8 +146,12 @@ class Thread:
except AttributeError:
pass
return argv[0].format(**params)
try:
return argv[0].format(**params)
except KeyError as e:
undefined_variable(str(e))
else:
return str()
......@@ -148,12 +174,12 @@ class Thread:
"entry_id":'',
"entry_title":'',