#!/usr/bin/python3 """═════════════ Site generator ═════════════- Python, pandoc static site generator # USE - Run: `./gen.py build` on a ./src directory containing directories of markdown files. - keep a ./src/index.md file which will be the home page. - and optionally ./src/about.md which will be an about page. - Build, upload and git upload : `make all` # TODO - Make index and about page compilation use template - only generate edited posts * - keep track of time edited to avoid this changing when repo is pulled to another machine. - Neaten and improve efficiency * - Move to pandoc ... -s, standalone tag, to include table of contents. ╚═════════════════════════════════════════════""" import os, re, time, yaml, sys # Globals pages_list="
\n" domain="example.com" # Add the site domain here rss_title='Open source cookery book.' rss_description='My virtual scrapbook.' if os.path.exists('config.yml'): # Load yaml config with open('config.yml','r') as file: config_file=yaml.safe_load(file) server=config_file['server_name'] domain=config_file['domain'] destdir=config_file['destdir'] rss="\n\n\t\n\t\t"+rss_title+"\n\t\thttps://"+domain+"\n\t\t"+rss_description+"\n\t\t"+time.strftime('%a, %d %b %Y %H:%M:%S %Z', time.localtime())+"\n\t\t15" # RSS XML channel preamble m_pattern = r"^[^#~]+.md$" h_pattern = r"^.+.html$|^.+.txt$" # t_pattern = r"^.+.txt$" p = re.compile(m_pattern) # md file regex hp = re.compile(h_pattern) # html file regex #tp = re.compile(t_pattern) # txt file regex posts={} # file list dictionary foot = "

Click to worms.





\n\n" # tags={} def get_yaml(f): # parse yaml header from markdown file pointer = f.tell() if f.readline() != '---\n': f.seek(pointer) print("\n\n**** Yaml header not detected in ", f.name, "****.\nPLEASE add \n---\nlang: en-GB\ntitle: Title for post\ndescription: Some description\n\n---\nTo the top of the file\n********************") sys.exit() readline = iter(f.readline, '') readline = iter(readline.__next__, '---\n') #underscores needed for Python3? return ''.join(readline) def yaml_rss(fpath,mtime,slug): # get metadata from each page and parse into rss global rss with open(fpath, encoding='UTF-8') as f: config = list(yaml.load_all(get_yaml(f), Loader=yaml.SafeLoader)) text = f.read() if 'title' in config[0]: # Add items to rss feed rss+="\n\t\t\n\t\t\t"+config[0]["title"]+"" if 'description' in config[0]: rss+="\n\t\t\t"+config[0]["description"]+"" else: rss+="\n\t\t\tNone" rss+="\n\t\t\t"+slug+"\n\t\t\t"+slug+"\n\t\t\t"+mtime+"\n\t\t" def create_post(file_abs, name, category): # compile markdown post to html page pst=time.time() rfc_822_time = time.strftime('%a, %d %b %Y %H:%M:%S %Z', time.localtime(os.path.getmtime(file_abs))) slug = "https://"+domain+category+name+".html" yaml_rss(file_abs, rfc_822_time,slug) _time="

Last edited :- "+rfc_822_time+"


" script="pandoc -f markdown -t html -s --toc --toc-depth=3 --template=templates/pream.html --mathml -V time='"+_time+"' "+file_abs+" > "+" ./site"+category+name+".html.tmp" os.system(script) content = open("site"+category+name+".html.tmp", "r").read() # write to index.html page = open("site"+category+name+".html", "w", encoding="utf-8") _title = "" description = "" meta = "" with open(file_abs, encoding='UTF-8') as f: meta = list(yaml.load_all(get_yaml(f), Loader=yaml.SafeLoader))[0] _title = meta["title"] if 'description' in meta: description = meta["description"] if 'tags' in meta: # extract tags and store if len(meta["tags"])>0: for t in meta["tags"]: if t not in tags.keys(): tags[t]=[] tags[t].append(file_abs) page.write(content) # Write index to index.html page.close() os.remove("site"+category+name+".html.tmp") print("[Created page (in "+str(round(time.time()-pst, 2))+" s): "+category+name+".html"+"]") def gen_tags(): # Generate html for tags and tag pages if not tags: return "" tagels="\n
" os.system("mkdir ./site/t") for i,k in enumerate(tags.keys()): links="

Pages tagged "+k+"

\n\n" if i==0: tagels+=""+k+" " else: tagels+="∩ "+k+" " tagpage = open("./site/t/"+k+".html", "w") preampage = open("templates/tags_pream.html","r").read() tagpage.write(preampage+links+"\n") tagpage.close() tagels+="
" return tagels def main(): # Main function. Generates site directory with rss feed page files and index. global pages_list global rss print("[...Starting HTML...]") start=time.time() # Grab files in directories root_files = [] for root, dirs, files, in os.walk("./src"): if root=="./src": root_files.append(files) # add files in root too for d in dirs: for files in os.walk("./src/" +d): posts[d]=files # Get folders which are categories categories = list(posts.keys()) if os.path.exists('site'): # Clean up os.system("rm -r site/* && mkdir ./site/assets") else: os.system("mkdir -p ./site/assets") # make the site director os.system("cp gen.py site/assets/ && cp -r assets/* site/assets") # copy this script and styles to assets num_cats=len(categories) # how many folders? for i,cat in enumerate(categories):# Generate index pages_list and categories. Compile each post. os.system('mkdir site/'+cat) # make a folder for each category if i%2==0 and i!=0: # Put some divs in the right places so bootstrap is nice pages_list+="
\n" pages_list+="

"+cat.capitalize().replace("_"," ")+"

\n
\n" root_files[0].remove("index.md") # Create pages for root markdown files. for f in root_files[0]: if p.findall(f): create_post("./src/"+f, f.split(".")[0], "/") rss+="\n\t\n" # RSS foot tagels = gen_tags() # Compile index and create add post category lists os.system('pandoc --verbose -s -f markdown -t html -V tag_list="'+tagels+'" --template=templates/index_pream.html src/index.md > tmp.html') pages_list+="\n

" index=open("tmp.html").read() + pages_list + foot# "

Click to Kill worms


\n
\n
\n\n" # add index.md stuff os.remove("tmp.html") # delete tmp.html index_file = open("site/index.html", "w", encoding="utf-8") # write to index.html print("[Compiled HTML in ",round(time.time()-start, 3),"seconds."+"]") start=time.time() print("[Writing RSS"+"]") rss_file = open("site/rss.xml", "w", encoding="utf-8") # write to index.html index_file.write(index) # Write index to index.html rss_file.write(rss) # Write rss feed to rss file index_file.close() rss_file.close() print("[Compiled RSS in ",round(time.time()-start, 3),"seconds"+"]"+"\nEND") """ --- Custom server name and destination directory --- """ server="s" destdir="/var/www/html" if __name__ == "__main__": if len(sys.argv)<2: print("\nNo arguments.\n\n Please try:\n 'git',\n 'build',\n 'serve' ,\n 'all',\n 'upload' (for this option make sure there is an ssh server called 's' available.\n\t\tThe destination directory is /var/www/html by default.\n\t\tSet server and destdir variables in generate.py file.)") sys.exit() elif (sys.argv[1]=="build"): print("[Building site."+"]") main() elif (sys.argv[1]=="upload"): print("[Uploading files."+"]") os.system("rsync -rh --info=progress2 --exclude='*.swp' site/* root@"+server+":"+destdir+" --delete") elif (sys.argv[1]=="all"): print("[Building..."+"]") main() print("[Uploading..."+"]") os.system("rsync -rh --info=progress2 --exclude='*.swp' site/* root@"+server+":"+destdir+" --delete") print("[Git commit and push..."+"]") os.system("git commit -am \"post\" && git push") elif (sys.argv[1]=="serve"): os.system("cd site && python3 -m http.server") elif (sys.argv[1]=="git"): print("[Commiting and pushing latest to git."+"]") os.system("git commit -am \"post\" && git push") else: print("\nArgument is invalid\n") print("Please try:\n 'git',\n 'build',\n 'serve' ,\n 'all',\n 'upload' (for this option make sure there is an ssh server called 's' available.\n\t\tThe destination directory is /var/www/html by default.\n\t\tSet server and destdir variables in generate.py file.)") sys.exit()