This commit is contained in:
deadvey 2025-03-24 18:08:06 +00:00
commit 4cc32d3200
19 changed files with 221 additions and 0 deletions

BIN
.create_pages.py.swp Normal file

Binary file not shown.

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
config.py

13
README.md Executable file
View File

@ -0,0 +1,13 @@
I've written a basic program in python called glogger, it is a customisable, statically generated gemini blogging frontend, it's being used right now. It works by having two mysql tables called " "users" which contains just two fields: userID and username, and "posts" which contains 6 fields: postID (PK), userID (FK), title, content, pubData and editDate, whenever you create a new post, it will add a new record to the posts table and write that post to the gemini frontend. It has a few options in the configuration, to allow for differing formatting to change how the whole thing is generated. I am wanting to add a better text input field instead of the basic python() input, probably consisting of a vim buffer that gets sent to the python program, that could be great! I also want to add passwords for different users and modification of previous posts.
# Setup
## Requirements:
mysql-connector-python
mariadb-client
mariadb-server
## Database setup
``` CREATE DATABASE glogger;
USE glogger;
CREATE TABLE users ( userID INT PRIMARY KEY AUTO_INCREMENT NOT NULL, username VARCHAR(255) );
CREATE TABLE posts ( postID INT PRIMARY KEY AUTO_INCREMENT NOT NULL, userID INT, FOREIGN KEY(userID) REFERENCES users(userID), title VARCHAR(255), content TEXT, pubDate VARCHAR(255), editDate VARCHAR(255) );
```

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

52
create_pages.py Executable file
View File

@ -0,0 +1,52 @@
# File tree:
#
# / -- index.gmi
# |
# |- post/ -- 1.gmi
# | |
# | |- 2.gmi
# | |
# | |- 3.gmi
# |
# |- user/ -- deadvey.gmi
# |
# |- max.gmi
#
import config
import parse_post
from datetime import datetime
def create_user_page(userID, username, db):
with open(f"{config.webroot}/user/{username}.gmi", "w") as userfile:
cursor = db.cursor()
cursor.execute(f"SELECT * FROM posts WHERE userID = {userID} ORDER BY postID Desc")
userfile.write(f"# {username}:\n")
for x in cursor:
post = config.user_page_post_format
post = parse_post.parse_post_format(post, x, username)
userfile.write(post)
def create_post_page(postID, db):
with open(f"{config.webroot}/post/{postID}.gmi", "w") as postfile:
cursor = db.cursor()
cursor.execute(f"SELECT * FROM posts WHERE postID = {postID}")
cursor2 = db.cursor()
cursor2.execute('SELECT * FROM users')
post = config.post_page_post_format
post = parse_post.parse_post_format(post, x, cursor2[cursor[0]-1][1])
postfile.write(post)
def create_timeline(db):
with open(f"{config.webroot}/index.gmi", "w") as timeline_file:
users = []
cursor = db.cursor()
cursor.execute(f"SELECT userName FROM users")
for x in cursor:
users += x
cursor.execute(f"SELECT * FROM posts ORDER BY postID Desc LIMIT {config.posts_in_timeline}")
for x in cursor:
username = users[x[1]-1]
post = config.timeline_post_format
post = parse_post.parse_post_format(post, x, username)
timeline_file.write(post)

44
example.config.py Executable file
View File

@ -0,0 +1,44 @@
### General ###
site_url = "gemini://example.com"
webroot = "/path/to/root"
date_format = "%d/%m/%Y at %H:%M" # The date that is displayed on the page
post_seperator = "---------------------------------------------"
posts_in_timeline = 100
### SQL settings ###
host = "localhost"
user = "root"
password = "password"
database = "glogger"
### Format ###
# The syntax for this is pretty simple
# %S - post seperator as defined by post_seperator
# %T - Title
# %D - Published date in the format specified by date_format
# %E - Edited date in the format specified by date_format
# %C - Post content
# %L - URL Permanent link to the post
# %U - URL the the user (poster)
# %N - the username of the user (poster)
user_page_post_format = '''
## %T
%C
=> %L permalink
%S
'''
post_page_post_format = '''
# Posted by %N
## %T
### Published: %D
%C
=> %U %N
Published: %D
Last Edited: %E
'''
timeline_post_format = '''
## %T
%C
=> %U %N
%S
'''

38
glogger.py Executable file
View File

@ -0,0 +1,38 @@
import mysql.connector
import config
import newpost
import rebuild
from datetime import datetime
db = mysql.connector.connect(
host=config.host,
user=config.user,
password=config.password,
database=config.database
)
cursor = db.cursor()
cursor.execute("SELECT * FROM users")
username = input("Username: ").lower()
# Check if this user exists
user_present = False
for x in cursor:
if x[1] == username:
user_present = True
userID = x[0]
if user_present == True:
print('''What do you want to do?
1. Create (N)ew post
2. (R)ebuild''')
answer = input()
if answer == 'N' or answer == '1':
newpost.newpost(db, userID, username, datetime)
if answer == 'R' or answer == '2':
rebuild.rebuild(db)
else:
print('Sorry, that account does not exist, If it should, please ask the webadmin to add this account')
db.commit()

47
newpost.py Executable file
View File

@ -0,0 +1,47 @@
# users:
# +----------+--------------+------+-----+---------+----------------+
# | Field | Type | Null | Key | Default | Extra |
# +----------+--------------+------+-----+---------+----------------+
# | userID | int(11) | NO | PRI | NULL | auto_increment |
# | userName | varchar(255) | NO | | NULL | |
# +----------+--------------+------+-----+---------+----------------+
#
# posts:
# +----------+--------------+------+-----+---------+----------------+
# | Field | Type | Null | Key | Default | Extra |
# +----------+--------------+------+-----+---------+----------------+
# | postID | int(11) | NO | PRI | NULL | auto_increment |
# | userID | int(11) | YES | MUL | NULL | |
# | title | varchar(255) | YES | | NULL | |
# | content | text | YES | | NULL | |
# | pubDate | varchar(255) | YES | | NULL | |
# | editDate | varchar(255) | YES | | NULL | |
# +----------+--------------+------+-----+---------+----------------+
import mysql.connector
from datetime import datetime
import click # Used to write post content, it launches a text editor to type into
# Other python files #
import create_pages
import config
def newpost(db, userID, username, datetime):
title = input("Title: ")
content = click.edit()
content = content.replace("'", "&#39")
print(content)
datetime = datetime.now().strftime("%d%m%YZ%H%M%ST")
cursor = db.cursor()
cursor.execute(f"INSERT INTO posts (userID, title, content, pubDate, editDate) VALUES({userID}, '{title}', '{content}', '{datetime}', '{datetime}')")
cursor.execute(f"SELECT * FROM posts ORDER BY postID Desc LIMIT 1")
for x in cursor:
postID = x[0]
db.commit()
## Write to user page ##
create_pages.create_user_page(userID, username, db)
create_pages.create_post_page(postID, username, db)
create_pages.create_timeline(db)

15
parse_post.py Executable file
View File

@ -0,0 +1,15 @@
import config
from datetime import datetime
def parse_post_format(post, record, username):
post = post.replace("%S", config.post_seperator)
post = post.replace("%T", record[2])
post = post.replace("%D", datetime.strptime(str(record[4]),"%d%m%YZ%H%M%ST").strftime(config.date_format))
post = post.replace("%E", datetime.strptime(str(record[5]),"%d%m%YZ%H%M%ST").strftime(config.date_format))
post = post.replace("%C", record[3])
post = post.replace("%L", f"{config.site_url}/post/{record[0]}.gmi")
post = post.replace("%U", f"{config.site_url}/user/{username}.gmi")
post = post.replace("%N", username)
return post

11
rebuild.py Executable file
View File

@ -0,0 +1,11 @@
import config
import create_pages
def rebuild(db):
cursor = db.cursor()
cursor.execute('SELECT * FROM users')
for x in cursor:
create_pages.create_user_page(x[0], x[1], db)
create_pages.create_timeline(db)
cursor.execute('SELECT * FROM posts')
for x in cursor:
create_pages.create_post_page(x[0], db)