123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- #!/usr/bin/env python3
- import os
- import re
- from markup import *
- #WARNING: if you're going to use special characters like emojis, type them as HTML entities!
- def build_entry_html_truncated(entry_id,entry_title,entry_date,entry_body):
- entry_body = entry_truncate(entry_body,entry_id)
- return """<article id="%s">
- <a name="entry_%s"></a>
- <h1 class="article-header">📄 <a href="articles/%s.html">%s</a></h1>
- <span class="metadata">%s</span><br>
- %s
- </article>
- """ % (entry_id,entry_id,entry_id,entry_title,entry_date,entry_body)
- def build_entry_html(entry_title,entry_date,entry_body):
- return """<!-- !!TITLE:%s -->
- <h1 class="article-header">%s</h1>
- <p class="metadata">%s</p>
- <!-- !!ARTICLE BODY -->
- %s
- <!-- !!END -->
- """ % (entry_title,entry_title,entry_date,entry_body)
- def build_entry_xml(entry_id,entry_date,neocities_username,entry_html_body):
- entry_desc = entry_truncate(entry_html_body,entry_id)
- entry_desc = entry_desc.replace('<','<').replace('>','>')
- return """<item>
- <guid>%s</guid>
- <title>New entry on %s.neocities.org</title>
- <pubDate>%s</pubDate>
- <description>
- %s
- </description>
- <link>https://%s.neocities.org/%s.html#entry_%s</link>
- </item>
- """ % (entry_id,neocities_username,entry_date,entry_desc,neocities_username,blog_fname,entry_id)
- def entry_truncate(str,entry_id):
- #truncates article preview to only the first paragraph, if no paragraphs (<p></p>), the whole entry is returned
- truncated=""
- paragraphs=str.split("</p>")
- if paragraphs.__len__ == 1:
- truncated=str+"<nav class=\"entrynav\"><a href=\"#entry_"+entry_id+"\">Permalink</a> | <a href=\"#top\">Top</a> | <a href=\"articles/"+entry_id+".html\">Full entry »</a></nav><br>"
- else:
- truncated=paragraphs[0]+"</p><nav class=\"entrynav\"><a href=\"#entry_"+entry_id+"\">Permalink</a> | <a href=\"#top\">Top</a> | <a href=\"articles/"+entry_id+".html\">Full entry »</a></nav><br>"
- return truncated
- def insert_article(entry_html_body, entry_xml_body):
- #insert an article into html
- blog_html = open("public_html/"+blog_fname+".html").read()
- #this is the reason why you shouldn't delete <!-- COMMENTS -->, they are used to insert entries
- blog_html_split = blog_html.split("<!-- !!BLOG ENTRIES -->\n")
- #split blog html and insert new article
- blog_html_top = blog_html_split[0]
- blog_html_bottom = blog_html_split[1]
- blog_html_new = blog_html_top+"<!-- !!BLOG ENTRIES -->\n"+entry_html_body+blog_html_bottom
- #temporary delete blog html and re-write it with new contents
- os.system("rm -f public_html/"+blog_fname+".html")
- os.system("touch public_html/"+blog_fname+".html")
- open("public_html/"+blog_fname+".html","w").write(blog_html_new)
- #now let's insert the article into rss feed! :3
- blog_rss = open("public_html/rss.xml").read()
- #split the file
- blog_rss_split = blog_rss.split("<!-- !!BLOG ENTRIES -->\n")
- blog_rss_top = blog_rss_split[0]
- blog_rss_bottom = blog_rss_split[1]
- blog_rss_new = blog_rss_top+"<!-- !!BLOG ENTRIES -->\n"+entry_xml_body+blog_rss_bottom
- #let's delete and re-write again...
- os.system("rm -f public_html/rss.xml")
- os.system("touch public_html/rss.xml")
- open("public_html/rss.xml","w").write(blog_rss_new)
- def create_article_file(entry_id,entry_title,entry_body_html):
- #read article template
- template_html = open("public_html/articles/article_template.html").read()
- template_html_split = template_html.split("<!-- !!ARTICLE -->\n")
- template_html_top=template_html_split[0]
- template_html_bottom=template_html_split[1]
- #insert article
- html_pre = template_html_top+"<!-- !!ARTICLE -->\n"+entry_body_html+template_html_bottom
- #insert <title>
- html_pre_split = html_pre.split("<title>")
- html_pre_top = html_pre_split[0]
- html_pre_bottom = html_pre_split[1]
- article_html = html_pre_top+"<title>"+entry_title+html_pre_bottom
- #create the new entry file! :3
- os.system("touch public_html/articles/"+entry_id+".html")
- open("public_html/articles/"+entry_id+".html","w").write(article_html)
- def add_new_entries(blog_fname):
- #count added entries
- added=0
- #read current html contents from blog file
- blog_html = open("public_html/"+blog_fname+".html").read()
- #count existing entries
- html_current_entries = re.findall("<article id=\"" + r"[0-9]+" + "\">",blog_html)
- html_entries_count = html_current_entries.__len__()
- #count entry files in "entries/" directory
- raw_entries_files = sorted(os.listdir("entries/"))
- raw_entries_count = raw_entries_files.__len__()-1 #exclude "README" file
- if raw_entries_count > html_entries_count:
- for fname in raw_entries_files:
- if fname=="README":
- continue
- entry_id=fname.split('_')[1]
- entry_raw=open("entries/"+fname).read()
- if entry_raw == "[DELETED]\n" or html_current_entries.count("<article id=\""+entry_id+"\">") > 0:
- continue
- entry_title=entry_raw.split('\n')[0].split("TITLE:")[1].replace('<','<').replace('>','>')
- entry_date=entry_raw.split('\n')[1].split("DATE:")[1]
- entry_body_raw=entry_raw.split("BODY:\n")[1]
- entry_body_html=mdtohtml(entry_body_raw)
- #build "final product"
- neocities_username=open("nci.conf").read().split('\n')[0]
- entry_full_html=build_entry_html(entry_title,entry_date,entry_body_html)
- entry_truncated_html=build_entry_html_truncated(entry_id,entry_title,entry_date,entry_body_html)
- entry_full_xml=build_entry_xml(entry_id,entry_date,neocities_username,entry_body_html)
- #insert data
- insert_article(entry_truncated_html,entry_full_xml)
- create_article_file(entry_id,entry_title,entry_full_html)
- def del_entries(blog_fname):
- #count deleted entries
- deleted=0
- #check if any raw entry is [DELETED]
- raw_entries_files=sorted(os.listdir("entries/"))
- raw_entries_count=raw_entries_files.__len__()
- for fname in raw_entries_files:
- if fname == "README":
- continue #exclude README file
- entry_id=fname.split("_")[1]
- entry_raw=open("entries/"+fname).read()
- #check if entry is deleted but still exists in public_html
- if entry_raw=="[DELETED]\n":
- #delete article page, if file not found, nothing will happen so thanks -f
- os.system("rm -f public_html/articles/"+entry_id+".html")
- #check if entry still exists in html or rss files and remove it from them if so
- blog_html=open("public_html/"+blog_fname+".html").read()
- html_current_entries=re.findall("<article id=\""+r"[0-9]+"+"\">",blog_html)
- #i suck at html DOM manipulation using python
- if html_current_entries.count("<article id=\""+entry_id+"\">") > 0:
- blog_html_split = blog_html.split("<article id=\""+entry_id+"\">")
- blog_html_top = blog_html_split[0]
- blog_html_pre_bottom = blog_html_split[1]
- blog_html_bottom = blog_html_pre_bottom[blog_html_pre_bottom.find("</article>")+10:]
- blog_html_new = blog_html_top+blog_html_bottom
- os.system("rm -f public_html/"+blog_fname+".html")
- os.system("touch public_html/"+blog_fname+".html")
- open("public_html/"+blog_fname+".html","w").write(blog_html_new)
- #delete from rss xml
- blog_rss_xml = open("public_html/rss.xml").read()
- rss_current_entries = re.findall("<guid>"+r"[0-9]+"+"</guid>",blog_rss_xml)
- if rss_current_entries.count("<guid>"+entry_id+"</guid>")>0:
- blog_rss_split = blog_rss_xml.split("<item>\n<guid>"+entry_id+"</guid>")
- blog_rss_top = blog_rss_split[0]
- blog_rss_pre_bottom = blog_rss_split[1]
- blog_rss_bottom = blog_rss_pre_bottom[blog_rss_pre_bottom.find("</item>")+7:]
- blog_rss_new = blog_rss_top+blog_rss_bottom
- os.system("rm -f public_html/rss.xml")
- os.system("touch public_html/rss.xml")
- open("public_html/rss.xml","w").write(blog_rss_new)
- def update_entries(blog_fname):
- #count updated entries
- updated=0
- html_articles = sorted(os.listdir("public_html/articles/"))
- #read excluded entries
- excluded_raw = ""
- to_exclude = []
- try:
- excluded_raw = open("exclude.conf").read()
- except FileNotFoundError:
- print("[!] Warning: exclude.conf file not found.")
- to_exclude = excluded_raw.split('\n')
- #compare html content with mdtohtml(raw) for each existing non-deleted entry
- for f_article in html_articles:
- if f_article == "article_template.html" or f_article == "style.css":
- continue
- entry_id = f_article.split(".html")[0]
- entry_page = open("public_html/articles/"+f_article).read()
- if str(entry_id) in to_exclude:
- print("[*] Entry No. "+entry_id+" excluded from being updated.")
- continue
- entry_title = entry_page.split("<!-- !!TITLE:")[1].split(" -->")[0]
- html_split = entry_page.split("<!-- !!ARTICLE BODY -->\n")
- html_top = html_split[0]
- entry_body = html_split[1]
- html_split2 = entry_body.split("<!-- !!END -->\n")
- entry_body = html_split2[0]
- html_bottom = html_split2[1]
- entry_new_title = open("entries/entry_"+entry_id).read().split('\n')[0].split("TITLE:")[1].replace('<',"<").replace('>',">")
- entry_new_body = mdtohtml(open("entries/entry_"+entry_id).read().split('BODY:\n')[1])
- #DATES CAN'T BE CHANGED (NO SUPPORT FOR THAT)! DO NOT TRY TO "UPDATE" YOUR ENTRIES POST DATE.
- entry_date = open("entries/entry_"+entry_id).read().split('\n')[1].split("DATE:")[1]
- if entry_body != entry_new_body or entry_title != entry_new_title:
- #modify blog html
- bhtml = open("public_html/"+blog_fname+".html").read()
- bhtml_split = bhtml.split("<article id=\""+entry_id+"\">\n")
- bhtml_top = bhtml_split[0]
- bhtml_entry_start = bhtml_split[1]
- bhtml_bottom = bhtml_entry_start[bhtml_entry_start.find("</article>")+10:]
- entry_new_html = build_entry_html_truncated(entry_id, entry_new_title, entry_date, entry_new_body)
- bhtml_new = bhtml_top+entry_new_html+bhtml_bottom
- os.system("rm -f public_html/"+blog_fname+".html")
- os.system("touch public_html/"+blog_fname+".html")
- open("public_html/"+blog_fname+".html","w").write(bhtml_new)
- #modify rss
- blog_rss_xml = open("public_html/rss.xml").read()
- blog_rss_split = blog_rss_xml.split("<item>\n<guid>"+entry_id+"</guid>")
- blog_rss_top = blog_rss_split[0]
- blog_rss_entry_start = blog_rss_split[1]
- blog_rss_bottom = blog_rss_entry_start[blog_rss_entry_start.find("</item>")+7:]
- username=open("nci.conf").read().split('\n')[0]
- entry_new_xml = build_entry_xml(entry_id,entry_date,username,entry_new_body)
- blog_rss_new_xml = blog_rss_top+entry_new_xml+blog_rss_bottom
- os.system("rm -f public_html/rss.xml")
- os.system("touch public_html/rss.xml")
- open("public_html/rss.xml","w").write(blog_rss_new_xml)
- #modify entry page
- article_html_new = html_top.replace(entry_title,entry_new_title)+"<!-- !!ARTICLE BODY -->\n"+entry_new_body+"<!-- !!END -->\n"+html_bottom
- os.system("rm -f public_html/articles/"+entry_id+".html")
- os.system("touch public_html/articles/"+entry_id+".html")
- open("public_html/articles/"+entry_id+".html","w").write(article_html_new)
- #...
- print("Updating blog public files...")
- #read blog filename from configuration file
- blog_fname = open("nci.conf").read().split('\n')[1]
- #update
- add_new_entries(blog_fname)
- del_entries(blog_fname)
- update_entries(blog_fname)
- print("Files successfully updated! IMPORTANT: Remember to run the \"./push\" command to upload your changed files to Neocities.")
- print("OK.")
|