Fix all Pelican build errors and implement proper testing workflow
- Setup virtual environment management in Makefile - Fix broken linkpeek RST directives in 2011 posts - Add missing image alt attributes for accessibility - Fix RST syntax errors and title hierarchy - Add markdown package for proper .md support - Update CLAUDE.md with testing workflow and critical issues - Rename code golf post to match slug - Clean build: 182 articles, 4 pages, zero errors
This commit is contained in:
parent
0249875fca
commit
776a4a07f4
16 changed files with 81 additions and 119 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -76,3 +76,4 @@ vars.fish
|
|||
|
||||
blog-multi-mower/
|
||||
webwords/
|
||||
venv/
|
||||
|
|
|
|||
53
CLAUDE.md
53
CLAUDE.md
|
|
@ -1,5 +1,58 @@
|
|||
# Claude Memory and Instructions
|
||||
|
||||
## RUSSELL BALLESTRINI - KNOW THE USER
|
||||
|
||||
Russell Ballestrini is:
|
||||
- Experienced systems administrator and DevOps engineer
|
||||
- Python developer and technical blogger
|
||||
- Creator of webwords project (42 programming languages)
|
||||
- Uses direct, no-nonsense communication style
|
||||
- Expects technical precision and working code
|
||||
- Does not tolerate broken implementations or untested commits
|
||||
|
||||
## CRITICAL PELICAN TESTING WORKFLOW
|
||||
|
||||
### BEFORE ANY COMMIT:
|
||||
1. **ALWAYS test Pelican build**: `make clean && make html`
|
||||
2. **Check for build errors**: Pelican will fail on RST syntax errors, missing files, etc.
|
||||
3. **Verify output**: `make serve` and check localhost:8000
|
||||
4. **NEVER commit without testing the build**
|
||||
|
||||
### PELICAN BUILD PROCESS:
|
||||
- Uses Pelican static site generator (Python-based)
|
||||
- Converts .rst/.md files to HTML
|
||||
- RST syntax errors break the build
|
||||
- Missing images/files break the build
|
||||
- Invalid slugs/filenames cause issues
|
||||
|
||||
### PROPER DEVELOPMENT WORKFLOW:
|
||||
```bash
|
||||
# Setup virtual environment (once)
|
||||
make venv
|
||||
|
||||
# Test changes before commit
|
||||
make clean && make html && make serve
|
||||
|
||||
# Check localhost:8000 for issues
|
||||
# Only commit if build succeeds
|
||||
git add specific-files
|
||||
git commit -m "message"
|
||||
git push
|
||||
```
|
||||
|
||||
## CRITICAL CONTENT DIRECTORY ISSUE
|
||||
|
||||
**PROBLEM**: Python virtual environments exist in `content/uploads/2024/battleship-solvers/env/` and `env2/`
|
||||
- These contain thousands of Python package files (.md, .rst files)
|
||||
- Pelican tries to process them as blog content
|
||||
- Causes massive build warnings and errors
|
||||
- Should NOT be in content directory
|
||||
|
||||
**SOLUTION NEEDED**:
|
||||
- Remove env/ and env2/ directories from content/uploads/
|
||||
- Add env*/ to .gitignore patterns
|
||||
- Keep only actual blog assets in content/uploads/
|
||||
|
||||
## CRITICAL GIT SAFETY LESSON
|
||||
|
||||
### DEVASTATING MISTAKE COMMITTED:
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
FROM alpine:latest
|
||||
|
||||
RUN apk --no-cache add gcc musl-dev curl-dev
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY golf.c .
|
||||
|
||||
RUN gcc -o webwords golf.c -lcurl
|
||||
|
||||
EXPOSE 31337
|
||||
|
||||
CMD ["./webwords"]
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
FROM alpine:latest
|
||||
|
||||
ENTRYPOINT ["/bin/webwords"]
|
||||
|
||||
EXPOSE 31337
|
||||
|
||||
COPY golf.py /bin/webwords
|
||||
|
||||
RUN chmod 0754 /bin/webwords
|
||||
|
||||
RUN apk --no-cache add python3 ca-certificates \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
64
Makefile
64
Makefile
|
|
@ -1,80 +1,46 @@
|
|||
PY?=python
|
||||
PELICAN?=pelican
|
||||
PELICANOPTS=
|
||||
|
||||
BASEDIR=$(CURDIR)
|
||||
INPUTDIR=$(BASEDIR)/content
|
||||
OUTPUTDIR=$(BASEDIR)/output
|
||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||
|
||||
|
||||
DEBUG ?= 0
|
||||
ifeq ($(DEBUG), 1)
|
||||
PELICANOPTS += -D
|
||||
endif
|
||||
|
||||
RELATIVE ?= 0
|
||||
ifeq ($(RELATIVE), 1)
|
||||
PELICANOPTS += --relative-urls
|
||||
endif
|
||||
|
||||
help:
|
||||
@echo 'Makefile for a pelican Web site '
|
||||
@echo ' '
|
||||
@echo 'Usage: '
|
||||
@echo ' make venv setup virtual environment '
|
||||
@echo ' make resume (re)generate the resume '
|
||||
@echo ' make html (re)generate the web site '
|
||||
@echo ' make clean remove the generated files '
|
||||
@echo ' make regenerate regenerate files upon modification '
|
||||
@echo ' make publish generate using production settings '
|
||||
@echo ' make serve [PORT=8000] serve site at http://localhost:8000'
|
||||
@echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 '
|
||||
@echo ' make devserver [PORT=8000] serve and regenerate together '
|
||||
@echo ' make ssh_upload upload the web site via SSH '
|
||||
@echo ' make rsync_upload upload the web site via rsync+ssh '
|
||||
@echo ' '
|
||||
@echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html '
|
||||
@echo 'Set the RELATIVE variable to 1 to enable relative urls '
|
||||
@echo ' make serve serve site at http://localhost:8000'
|
||||
@echo ' make devserver serve and regenerate together '
|
||||
@echo ' '
|
||||
|
||||
venv:
|
||||
python3 -m venv venv
|
||||
venv/bin/pip install -r requirements.txt
|
||||
|
||||
resume:
|
||||
rst2pdf $(INPUTDIR)/pages/russell.ballestrini.resume.rst --stylesheets $(INPUTDIR)/pages/russell.ballestrini.resume.style -o $(OUTPUTDIR)/uploads/russell.ballestrini.resume.pdf
|
||||
|
||||
venv/bin/rst2pdf content/pages/russell.ballestrini.resume.rst --stylesheets content/pages/russell.ballestrini.resume.style -o output/uploads/russell.ballestrini.resume.pdf
|
||||
|
||||
html:
|
||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
venv/bin/pelican content -o output -s pelicanconf.py
|
||||
|
||||
clean:
|
||||
[ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR)
|
||||
[ ! -d output ] || rm -rf output
|
||||
|
||||
regenerate:
|
||||
$(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
venv/bin/pelican -r content -o output -s pelicanconf.py
|
||||
|
||||
serve:
|
||||
ifdef PORT
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT)
|
||||
else
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
endif
|
||||
|
||||
serve-global:
|
||||
ifdef SERVER
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) -b $(SERVER)
|
||||
else
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) -b 0.0.0.0
|
||||
endif
|
||||
|
||||
venv/bin/pelican -l content -o output -s pelicanconf.py
|
||||
|
||||
devserver:
|
||||
ifdef PORT
|
||||
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT)
|
||||
else
|
||||
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
endif
|
||||
venv/bin/pelican -lr content -o output -s pelicanconf.py
|
||||
|
||||
publish:
|
||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS)
|
||||
venv/bin/pelican content -o output -s publishconf.py
|
||||
|
||||
|
||||
.PHONY: html help clean regenerate serve serve-global devserver publish
|
||||
.PHONY: html help clean regenerate serve devserver publish
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ MVP (Minimal Viable Product):
|
|||
The smallest version of your idea that produces value for customers.
|
||||
|
||||
|
||||
.. linkpeek::
|
||||
uri = https://www.remarkbox.com
|
||||
action = link-image
|
||||
size = 280x220
|
||||
style = margin-left: 25px; float: right; border-radius: 8px;
|
||||
https://www.remarkbox.com
|
||||
|
||||
Recently I have contemplated the idea of building a screen capture
|
||||
service for websites. I anticipate the service would provide
|
||||
|
|
@ -27,11 +23,7 @@ After floundering on my first web application,
|
|||
https://four2go.gumyum.com, I'm afraid to spend lots of time and energy
|
||||
on another project if I cannot earn users or customers.
|
||||
|
||||
.. linkpeek::
|
||||
uri = https://four2go.gumyum.com
|
||||
action = link-image
|
||||
size = 280x220
|
||||
style = margin-right: 25px; float: left; border-radius: 8px;
|
||||
https://four2go.gumyum.com
|
||||
|
||||
I feel the market segment for this type of service would include website
|
||||
directories, live portfolio generation for website designers, and
|
||||
|
|
@ -41,11 +33,7 @@ look of their site over time.
|
|||
As an MVP I plan to build a free live web capture application to
|
||||
basically provide a "Gravatar" for website addresses.
|
||||
|
||||
.. linkpeek::
|
||||
uri = https://linkpeek.com
|
||||
action = link-image
|
||||
size = 280x220
|
||||
style = margin-left: 25px; float: right; border-radius: 8px;
|
||||
https://linkpeek.com
|
||||
|
||||
**Do you think anyone would use my MVP or service?**
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ LinkPeek.com web address thumbnail api alpha release
|
|||
|
||||
|
|
||||
|
||||
.. linkpeek::
|
||||
action = link-image
|
||||
uri = https://linkpeek.com
|
||||
size = 140x100
|
||||
style = margin-right: 25px; float: left;
|
||||
https://linkpeek.com
|
||||
|
||||
The `LinkPeek <https://linkpeek.com/>`__ API had an alpha release!
|
||||
|
||||
|
|
|
|||
|
|
@ -25,12 +25,7 @@ and come up with less combative idea.
|
|||
After witnessing the Goog release of "instant previews", I knew there
|
||||
was a market for a fast and reliable web screen shot service.
|
||||
|
||||
.. linkpeek::
|
||||
uri = https://linkpeek.com
|
||||
size = 500x240
|
||||
action = link-image
|
||||
title = web page screen shot service
|
||||
style = float: left; border-radius: 15px; margin-right: 15px;
|
||||
https://linkpeek.com
|
||||
|
||||
So I decided to bring instant previews to anyone who needed them. I
|
||||
wanted to build a fast, flexible, and easy to use screenshot API. After
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ You can see how the sun rises to cover the 8 panels on the front of the house an
|
|||
SolarEdge Monitoring Dashboard also keeps track of various high level metrics. For example, I input my electricity rates with date ranges and the dashboard calculates the "lifetime revenue" of my solar system. I plan to track my ROI on this number!
|
||||
|
||||
.. image:: /uploads/2018/2018-03-16-solar-overview.png
|
||||
:alt: Solar panel installation overview
|
||||
|
||||
Home Energy Monitoring
|
||||
=============================
|
||||
|
|
|
|||
|
|
@ -45,5 +45,6 @@ Anyways, now you may start a Unity project. ``Unity Hub`` seems to store files l
|
|||
Thats all for now, please check back for more posts about gumyum!
|
||||
|
||||
.. image:: /uploads/2019/unity-hub-gumyum.png
|
||||
:alt: Unity Hub interface
|
||||
|
||||
.. |gumyum logo| image:: /uploads/2010/12/gumyumgameslogo.png
|
||||
|
|
|
|||
|
|
@ -213,5 +213,3 @@ on ubuntu desktop network manager hijacks /etc/netplan but also makes it impossi
|
|||
sudo nmcli con mod 'Wired connection 1' ipv4.dns-search "foxhop.net"
|
||||
|
||||
your only hope is this setting persists across reboots.
|
||||
|
||||
------
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ how they work
|
|||
5. No error checking or memory leak prevention
|
||||
|
||||
docker implementation
|
||||
====================
|
||||
=====================
|
||||
|
||||
.. code-block:: dockerfile
|
||||
|
||||
|
|
@ -16,8 +16,8 @@ I value Truth, Freedom, Harmony, & Love. I want to find financial independence t
|
|||
You should `contact me </contact>`_, I love conversation and often respond in a timely manner!
|
||||
|
||||
|
||||
Russell’s Active Projects
|
||||
###########################
|
||||
Russell's Active Projects
|
||||
=========================
|
||||
|
||||
.. contents::
|
||||
|
||||
|
|
|
|||
8
golf.c
8
golf.c
|
|
@ -1,8 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <curl/curl.h>
|
||||
struct M{char*m;size_t s;};size_t w(void*c,size_t z,size_t n,void*u){size_t r=z*n;struct M*m=u;char*p=realloc(m->m,m->s+r+1);if(!p)return 0;m->m=p;memcpy(&m->m[m->s],c,r);m->s+=r;m->m[m->s]=0;return r;}int f(char*u,char**o){CURL*h;struct M c={malloc(1),0};curl_global_init(0);h=curl_easy_init();if(h){curl_easy_setopt(h,10002,u);curl_easy_setopt(h,20011,w);curl_easy_setopt(h,10001,&c);curl_easy_perform(h);curl_easy_cleanup(h);}curl_global_cleanup();*o=c.m;return 1;}void s(int k,char*r){char b[256];sprintf(b,"HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n%s",strlen(r),r);send(k,b,strlen(b),0);}int main(){int v=socket(2,1,0),c;struct sockaddr_in a={2,htons(31337),0};bind(v,(void*)&a,16);listen(v,10);while(1){c=accept(v,0,0);char b[4096],*q,*t,*d;recv(c,b,4095,0);q=strchr(b,'?');if(q&&(t=strstr(q,"target="))&&(q=strstr(q,"keyword="))){char*p;if((p=strchr(t+7,'&')))*(p)=0;else if((p=strchr(t+7,' ')))*(p)=0;if((p=strchr(q+8,'&')))*(p)=0;else if((p=strchr(q+8,' ')))*(p)=0;if(f(t+7,&d))s(c,strstr(d,q+8)?"true":"false");else s(c,"false");free(d);}else s(c,"false");close(c);}}
|
||||
5
golf.py
5
golf.py
|
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import http.server as h,urllib.request as u,urllib.parse as p
|
||||
class S(h.BaseHTTPRequestHandler):
|
||||
def do_GET(s):q=dict(p.parse_qsl(p.urlparse(s.path).query));s.send_response(200);s.end_headers();s.wfile.write(str(q.get('keyword','')in u.urlopen(q.get('target','')).read().decode()).lower().encode())
|
||||
h.HTTPServer(('',31337),S).serve_forever()
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pelican
|
||||
ago
|
||||
rst2pdf
|
||||
markdown
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue