Log link index

June 13th, 2021

A .sql file containing an index that allows searching by content linked to in the logs is available here. It's only about 200mb compressed.

Thimbronion's Violin

June 13th, 2021

I picked up my violin again after several years of neglect. I hadn't really played since I put together a quartet to perform (actually I can't remember what we played) at a small recital back in 2007 or 2008. I think one reason I stopped playing was because my soon to be ex-wife strongly disliked the instrument.

I started to play again for purely incidental reasons. One is that a girl I've been seeing saw my violin and asked to hear me play. Sadly at the time I couldn't due to having severly injured my wrists in a completely avoidable electric unicycle accident. As time has passed and my wrists have healed, I have indeed begun to be able to pick up my violin and play again. The accident has definitely given me a new found appreciation for my wrists, which, even though they are of the utmost importance to me because of my profession I have perhaps taken for granted. In any case I'm glad she asked because I'm enjoying it again after really having given up on it. Another reason is that I met some musicians in Costa Rica and I think it would be a blast to give some performances with them.

I never really had a good violin before now. I had played on student violins, and if you asked me before, I couldn't tell you how to tell the difference between a good violin and a bad one. As I started to play again this last time, I was forced between choosing to repair my low quality student violin and purchaing a different instrument. I chose to purchase a new (well, used) instrument of higher quality. It indeed sounds better. Anything played on the E-string in particular just sounds ... brighter.

I am now working on playing the 4th part of Romanian Folk Dances, by Bartok. I don't have any particular reason to play it other than that I still have the sheet music, and I love playing it. In a way, the distance between now and the last time I practiced anything is a gift. I can hear myself critically now, from a distance, including all of the flaws in my technique. I don't know why I couldn't hear or didn't care to hear the problems before but I believe I now have a chance to improve, whereas if I'd continued as before, I might never have improved. In particular my bowing is problematic. The bow bounces in the middle of a long stroke. It touches adjacent strings when it shouldn't. It starts strokes roughly, and change between upstrokes and down strokes is not smooth. My intonation also is not great, and my 4th finger vibrato is non-existant. There are a lot more resources available now than before that I can use to improve, including, yes, even youtube. There are hours of videos to watch on vibrato alone.

I've already been able to improve my technique by memorizing the piece so I can concentrate on and literally observe my bow, rather than the music on the page.

I am happy to be getting this part of my life back and looking forward to continued advancements and playing more with others.

Alethepedia Improvements

May 3rd, 2021

Alethepedia is an encyclopedia based on an OCR scan of the 11th edition of Encyclopedia Britannica. It is currently hosted in an mp-wp running on a Digital Ocean VM. Mp-wp is a good foundation for an encyclopedia CMS, but much work needs to be done to make it better suited to the task. Following are the things I'd like to accomplish over the next 6 months or so:

Categorize articles alphabetically

I want all articles to be associated with a letter category corresponding the first letter of the title.

  • Deliverable: a python script I can run against the database.

Order articles alphabetically

I want articles to be listed in alphabetical order by title within categories. See: https://codex.wordpress.org/Alphabetizing_Posts for inspiration.

  • Deliverable: a patch against my mp-wp.

Prioritize title matches in search results

Currently it is very difficult to sift through search results and find an article when searching for words in the title, since it seems that possibly matches are made only against the body. I have no idea how the results are sorted. I'm open to other proposals to improve search via the web interface.

  • Deliverable: a patch against my mp-wp.

Any word that matches an article title should link to the article, with exceptions for things like the article on the letter A.

  • Deliverable: a python script I can run against the database.

Develop a minimalist, monochrome, responsive encyclopedia theme for mp-wp.

I kind of like the WordPress default theme, but I want a theme that is responsive and looks good on mobile devices.
Article dates are irrelevant and shouldn't be displayed
next/prev shouldn't say 'Older entries,' should be something like just next/previous since the date of the article isn't relevant.

  • Deliverable: WordPress theme or patch to existing WordPress theme.

Dump db to public file

  • Deliverable: Python script that can be called by cron to periodically dump the contents of the db into a sanitized .sql file that can be downloaded by interested parties.

Future work:

I am accepting proposals for work on cleaning up the text of the entries themselves. Here are some of the problems:

  • The OCR software mangled many dates within articles, as well as tables.
  • Many words have been mangled as well.

Ircbot Alt-Genesis

November 21st, 2020

While attempting to press trinque's ircbot including whaack's and ben_vulpes's patches, I ran into the issue of the genesis having been created using a differing hashing algorithm than that used for whaack's patch making pressing ircbot impossible using the available patches and genesis. Here you'll find a genesis including trinque's genesis and the changes from ben_vulpes's patch and whaack's patch.


1 diff -uNr a/ircbot/INSTALL b/ircbot/INSTALL
2 --- a/ircbot/INSTALL false
3 +++ b/ircbot/INSTALL c4c41d96ddb71db32e8cd54c22e7250abbc52d51f4b25d8092dc094b4a84100949d0a74378fc33131d2d9a5144156a738f5a91d7e949922898993eb4384b4757
4 @@ -0,0 +1,19 @@
6 +
7 + * Install SBCL (with sb-thread) and Quicklisp.
8 +
9 + * From the SBCL REPL:
10 + (ql:quickload :cl-irc)
11 +
12 + * Use V to press `ircbot`
13 +
14 +mkdir -p ~/src/ircbot
15 +cd ~/src/ircbot
16 +
17 +mkdir .wot
18 +cd .wot && wget http://trinque.org/trinque.asc && cd ..
19 +
20 +v.pl init http://trinque.org/src/ircbot
21 +v.pl press ircbot-genesis ircbot-genesis.vpatch
22 +
23 +ln -s ~/src/ircbot/ircbot-genesis ~/quicklisp/local-projects/ircbot
24 diff -uNr a/ircbot/README b/ircbot/README
25 --- a/ircbot/README false
26 +++ b/ircbot/README 6a76028622c6bb986d68d42b7b133221d3659d56da1bd5d4e8b39f0a6075a17d8b3ee33c8e37c7d4b3ec1f108ad940777d762bab01763a63742733a1445660d4
27 @@ -0,0 +1,8 @@
29 +
30 +`ircbot` provides a simple CLOS class, `ircbot`, which will maintain a
31 +connection to a single IRC channel via `cl-irc`. The bot will handle
32 +ping/pong and detect failed connections, and is capable of
33 +authenticating with NickServ (using ghost when necessary to
34 +reacquire nick).
35 +
36 diff -uNr a/ircbot/USAGE b/ircbot/USAGE
37 --- a/ircbot/USAGE false
38 +++ b/ircbot/USAGE 20d07e6f190f6655a2884e60c1d6a7eccdd76d019797bb165c716a6919fb5161a31b1956b9dda7927839837a924ae6ea3d0c1a833458bbbd5765f76548d637d2
39 @@ -0,0 +1,14 @@
41 +
42 +(asdf:load-system :ircbot)
43 +(defvar *bot*)
44 +(setf *bot*
45 + (ircbot:make-ircbot
46 + "chat.freenode.net" 6667 "nick" "password" "#channel"))
47 +
48 +; connect in separate thread, returning thread
49 +(ircbot:ircbot-connect-thread *bot*)
50 +
51 +; or connect using the current thread
52 +; (ircbot:ircbot-connect *bot*)
53 +
54 diff -uNr a/ircbot/ircbot.asd b/ircbot/ircbot.asd
55 --- a/ircbot/ircbot.asd false
56 +++ b/ircbot/ircbot.asd 9dfba5c2bd97e5ffc2ab071786b14c05dfda1c898ef58a5d87ea020bde042bf76c0e88b78f6d4a4fbd453aabea58e4710bf717defa023dfe410d19ac01c4e2d9
57 @@ -0,0 +1,10 @@
58 +;;;; ircbot.asd
59 +
60 +(asdf:defsystem #:ircbot
61 + :description "ircbot"
62 + :author "Michael Trinque <mike@trinque.org>"
63 + :license "http://trilema.com/2015/a-new-software-licensing-paradigm/"
64 + :depends-on (#:cl-irc)
65 + :components ((:file "package")
66 + (:file "ircbot")))
67 +
68 diff -uNr a/ircbot/ircbot.lisp b/ircbot/ircbot.lisp
69 --- a/ircbot/ircbot.lisp false
70 +++ b/ircbot/ircbot.lisp 738a2c0ca77a69fc7805cbfc668da1b61e25e512d6d9f3bdf200968e39eb201bb87be83c6ae1411c6e6a5c7dd63524a5b5ab71d99a2813ac85fc5ac4360b3b17
71 @@ -0,0 +1,143 @@
72 +(in-package #:ircbot)
73 +
74 +(defvar *max-lag* 60)
75 +(defvar *ping-freq* 30)
76 +
77 +
78 +(defclass ircbot ()
79 + ((connection :accessor ircbot-connection :initform nil)
80 + (channels :reader ircbot-channels :initarg :channels)
81 + (server :reader ircbot-server :initarg :server)
82 + (port :reader ircbot-port :initarg :port)
83 + (nick :reader ircbot-nick :initarg :nick)
84 + (password :reader ircbot-password :initarg :password)
85 + (connection-security :reader ircbot-connection-security
86 + :initarg :connection-security
87 + :initform :none)
88 + (run-thread :accessor ircbot-run-thread :initform nil)
89 + (ping-thread :accessor ircbot-ping-thread :initform nil)
90 + (lag :accessor ircbot-lag :initform nil)
91 + (lag-track :accessor ircbot-lag-track :initform nil)))
92 +
93 +(defmethod ircbot-check-nick ((bot ircbot) message)
94 + (destructuring-bind (target msgtext) (arguments message)
95 + (declare (ignore msgtext))
96 + (if (string= target (ircbot-nick bot))
97 + (ircbot-nickserv-auth bot)
98 + (ircbot-nickserv-ghost bot))))
99 +
100 +(defmethod ircbot-connect :around ((bot ircbot))
101 + (let ((conn (connect :nickname (ircbot-nick bot)
102 + :server (ircbot-server bot)
103 + :port (ircbot-port bot)
104 + :connection-security (ircbot-connection-security bot))))
105 + (setf (ircbot-connection bot) conn)
106 + (call-next-method)
107 + (read-message-loop conn)))
108 +
109 +(defmethod ircbot-connect ((bot ircbot))
110 + (let ((conn (ircbot-connection bot)))
111 + (add-hook conn 'irc-err_nicknameinuse-message (lambda (message)
112 + (declare (ignore message))
113 + (ircbot-randomize-nick bot)))
114 + (add-hook conn 'irc-kick-message (lambda (message)
115 + (declare (ignore message))
116 + (map nil
117 + (lambda (c) (join (ircbot-connection bot) c))
118 + (ircbot-channels bot))))
119 + (add-hook conn 'irc-notice-message (lambda (message)
120 + (ircbot-handle-nickserv bot message)))
121 + (add-hook conn 'irc-pong-message (lambda (message)
122 + (ircbot-handle-pong bot message)))
123 + (add-hook conn 'irc-rpl_welcome-message (lambda (message)
124 + (ircbot-start-ping-thread bot)
125 + (ircbot-check-nick bot message)))))
126 +
127 +(defmethod ircbot-connect-thread ((bot ircbot))
128 + (setf (ircbot-run-thread bot)
129 + (sb-thread:make-thread (lambda () (ircbot-connect bot))
130 + :name "ircbot-run")))
131 +
132 +(defmethod ircbot-disconnect ((bot ircbot) &optional (quit-msg "..."))
133 + (sb-sys:without-interrupts
134 + (quit (ircbot-connection bot) quit-msg)
135 + (setf (ircbot-lag-track bot) nil)
136 + (setf (ircbot-connection bot) nil)
137 + (if (not (null (ircbot-run-thread bot)))
138 + (sb-thread:terminate-thread (ircbot-run-thread bot)))
139 + (if (not (or (null (ircbot-ping-thread bot)) (equal sb-thread:*current-thread* (ircbot-ping-thread bot))))
140 + (sb-thread:terminate-thread (ircbot-ping-thread bot)))))
141 +
142 +(defmethod ircbot-reconnect ((bot ircbot) &optional (quit-msg "..."))
143 + (let ((threaded-p (not (null (ircbot-run-thread bot)))))
144 + (ircbot-disconnect bot quit-msg)
145 + (if threaded-p
146 + (ircbot-connect-thread bot)
147 + (ircbot-connect bot))))
148 +
149 +(defmethod ircbot-handle-nickserv ((bot ircbot) message)
150 + (let ((conn (ircbot-connection bot)))
151 + (if (string= (host message) "services.")
152 + (destructuring-bind (target msgtext) (arguments message)
153 + (declare (ignore target))
154 + (cond ((string= msgtext "This nickname is registered. Please choose a different nickname, or identify via /msg NickServ identify <password>.")
155 + (ircbot-nickserv-auth bot))
156 + ((string= msgtext (format nil "~A has been ghosted." (ircbot-nick bot)))
157 + (nick conn (ircbot-nick bot)))
158 + ((string= msgtext (format nil "~A is not online." (ircbot-nick bot)))
159 + (ircbot-nickserv-auth bot))
160 + ((string= msgtext (format nil "You are now identified for ~A." (ircbot-nick bot)))
161 + (map nil (lambda (c) (join conn c)) (ircbot-channels bot))))))))
162 +
163 +(defmethod ircbot-handle-pong ((bot ircbot) message)
164 + (destructuring-bind (server ping) (arguments message)
165 + (declare (ignore server))
166 + (let ((response (ignore-errors (parse-integer ping))))
167 + (when response
168 + (setf (ircbot-lag-track bot) (delete response (ircbot-lag-track bot) :test #'=))
169 + (setf (ircbot-lag bot) (- (received-time message) response))))))
170 +
171 +(defmethod ircbot-nickserv-auth ((bot ircbot))
172 + (privmsg (ircbot-connection bot) "NickServ"
173 + (format nil "identify ~A" (ircbot-password bot))))
174 +
175 +(defmethod ircbot-nickserv-ghost ((bot ircbot))
176 + (privmsg (ircbot-connection bot) "NickServ"
177 + (format nil "ghost ~A ~A" (ircbot-nick bot) (ircbot-password bot))))
178 +
179 +(defmethod ircbot-randomize-nick ((bot ircbot))
180 + (nick (ircbot-connection bot)
181 + (format nil "~A-~A" (ircbot-nick bot) (+ (random 90000) 10000))))
182 +
183 +(defmethod ircbot-send-message ((bot ircbot) target message-text)
184 + (privmsg (ircbot-connection bot) target message-text))
185 +
186 +(defmethod ircbot-start-ping-thread ((bot ircbot))
187 + (let ((conn (ircbot-connection bot)))
188 + (setf (ircbot-ping-thread bot)
189 + (sb-thread:make-thread
190 + (lambda ()
191 + (loop
192 + do (progn (sleep *ping-freq*)
193 + (let ((ct (get-universal-time)))
194 + (push ct (ircbot-lag-track bot))
195 + (ping conn (princ-to-string ct))))
196 + until (ircbot-timed-out-p bot))
197 + (ircbot-reconnect bot))
198 + :name "ircbot-ping"))))
199 +
200 +(defmethod ircbot-timed-out-p ((bot ircbot))
201 + (loop
202 + with ct = (get-universal-time)
203 + for v in (ircbot-lag-track bot)
204 + when (> (- ct v) *max-lag*)
205 + do (return t)))
206 +
207 +
208 +(defun make-ircbot (server port nick password channels)
209 + (make-instance 'ircbot
210 + :server server
211 + :port port
212 + :nick nick
213 + :password password
214 + :channels channels))
215 diff -uNr a/ircbot/manifest b/ircbot/manifest
216 --- a/ircbot/manifest false
217 +++ b/ircbot/manifest 8a535c4a26e5fba0aa52c44bfcd84176de82568ddd7e98e8fb84ab48b5dbc0bc315c09f37c8eb7201a88fb804a18712d1a876f02e06552157ebefc63a123a9c4
218 @@ -0,0 +1 @@
219 +658020 ircbot_genesis thimbronion This genesis combines trinque's genesis with ben_vulpes' multi-channel fix and whaack's reconnection fix. Theses patches were generated using differing hash algos and can not be applied by any existing v implementation and I do not see any reason that anyone would find ircbot usable without any of them.
220 diff -uNr a/ircbot/package.lisp b/ircbot/package.lisp
221 --- a/ircbot/package.lisp false
222 +++ b/ircbot/package.lisp d186f3af63443337d23a0bfbaae79246fae2b2781acb53109132b42f84cf46acabf1fe12f2aba00c452e679c721ca955daaf302e1a04a56fccb8125d95e1527c
223 @@ -0,0 +1,18 @@
224 +;;;; package.lisp
225 +
226 +(defpackage :ircbot
227 + (:use :cl
228 + :cl-irc)
229 + (:export :make-ircbot
230 + :ircbot
231 + :ircbot-connect
232 + :ircbot-connect-thread
233 + :ircbot-disconnect
234 + :ircbot-reconnect
235 + :ircbot-connection
236 + :ircbot-channels
237 + :ircbot-send-message
238 + :ircbot-server
239 + :ircbot-port
240 + :ircbot-nick
241 + :ircbot-lag))
242 /

Thoughts on WoT Search

October 25th, 2020

Here is how I am looking at WoT search right now.

The work remaining on Lekythion is

  1. Constructing a decent search query in SQL
  2. Hooking the bot up to postgres
  3. Formatting the response
  4. Publishing the lisp code I use to build the index

After publication of the code, my hope to see others build their own indexes and share them using the WoT. Index owners could share read-only access to their postgres instance, perhaps via whitelisted IPs, to others in the WoT. This is similar to the approach suggested by asciilifeform, but I can’t find a reference to his proposal at the moment.

Individuals could stand up their own bots and connect queries to whichever indexes they preferred, be they their own indexes or others’.

My indexes will eventually include at least:

  • All known former republican blogs1
  • All pages linked to in the logs
  • The logs

Perhaps at some point it will become relatively easy to quickly build an index of favorite sites/data sets and and make them available.

  1. As time goes on it may be possible for me to connect directly to blog owner indexes, rather than creating my own []

Socialist Art and Architecture of Sacramento

September 20th, 2020

All of the above images are taken from the back alley behind my apartment.

This is an outdoor olympic weightlifting gym, also in the back alley behind my apartment. I won’t report how much I can lift just yet.

I do like the industrial warehouse look of these two buildings, although both are now used for non-industrial purposes.

Disgusting, don’t you think?


This is where Newsom contemplates climate change instead of doing anything useful.

I actually liked this building until I discovered it’s a federal building.

More modern architecture.

Some train pics for the spergs.

Me and my ride.

Notes on Chinese from gregorynyssa

September 20th, 2020

In this article I attempt to condense some interesting information about Chinese I’ve learned in my recent discussions with gregorynyssa, a scholar of Chinese, Greek, and Latin, much after my own heart but far more advanced in all of these studies than myself.

Sentence Structure

According to gregorynyssa speakers of Mandarin Chinese, a language significantly lacking in grammar (such as explicit case), use these tricks with sentences to express more complicated ideas.

Since Chinese does not handle embedded clauses very elegantly, often speakers have a tendency just to avoid them.

Here are three techniques used by Mandarin speakers to express more complicated ideas.

Comma Splicing

Join two complete sentences with a comma. A result of this is there is no consistent distinction between commas and periods in Chinese writing.


Subject-periodic Construction

This involves combining sentences which share a subject.


Pivotal Construction

If the object of the first sentence is the same as the subject of the second, omit the latter and join the two sentences with a comma.


Digraphic Verbs, Improper Digraphic Verbs, and Monographic Verbs

Monographic verbs can’t serve as nouns.
Improper digraphic verbs can’t serve as nouns.
Most but not all digraphic verbs can serve as nouns.

The upshot of this is that it is necessary to learn the the noun forms for all improper digraphic verbs. For example, 睡觉 may not serve as a noun. In that case 睡眠 must be used. This partially explains why there are so many two-character words in chinese where both characters, according to the dictionary, mean exactly the same thing.

Improper digraphic verbs generally have a second syllable indicating direction or result.

Minor Grammatical Points

来 before a verb indicates the infinitive.
得 is more idiomatic when used vefore adverbs.
来到 is an improper verb meaning “come to.”
迅速 is used more often as an adverb in declarative sentences than 快, which is most often used in an imperative sense.
去 may only be used before place names, non-monographic verbs, and before terms indicating general vicinity1.

Further Reading

According to gregorynyssa, reading Disyllabic Words in Chinese and
Metrical Phonology have helped him fundamentally understand the nature 普通话(Putonghua). I haven’t yet read these papers and as of yet have no comment on them.

For a better understanding of how 普通话(apparently of relatively recent origin) differs from Ancient Chinese, read Peasant and Merchant as well as Rule of Law.

  1. Thus it is necessary to append 那边 to nouns like 超市 when expressing “going to <non-place name> []

Simple Mp-wp Article Import Script

September 20th, 2020

Below is a simple script for importing an article directly into mp-wp via the db inspired by lobbes' previous work on importing logs into mp-wp. It is a necessary step towards being able to import the entire Encyclopedia Britannica into mp-wp. I thought it might be useful for anyone wishing to automate creation of articles.


import mysql.connector
import time
import json
from pprint import pprint

def add_article(cnx, article):
        cursor = cnx.cursor()

        content = article['content'] 

        current_date = time.strftime("%Y-%m-%d %H:%M:%S",
                                                     (1910, 1, 1, 1, 3, 38, 1, 48, 0))
        current_date_gmt = current_date
        title = article['title']
        post_url_relative = '-'.join(title.split())

        query = '''INSERT INTO wpmp_posts(post_author, post_date,
                        post_date_gmt, post_content, post_title,
                        post_category, post_status, comment_status, ping_status,
                        post_name, post_modified, post_modified_gmt, post_parent,
                        guid, menu_order, post_type, comment_count,
                        post_excerpt, to_ping, pinged, post_content_filtered,
                        post_mime_type, post_password) VALUES (%s,%s,%s,%s,
                                %s,%s,%s) ; '''
                (0, current_date, current_date_gmt, content, title, 0, "publish",
                 "open", "open", post_url_relative, current_date,
                 current_date_gmt, 0, "", 0, "post", 0, "", "", "", "", "", "")


cnx = mysql.connector.connect(user='jwz', password='justwantedto',
json_file = '../data/encyclopedia.json'
with open(json_file) as json_data:
    data = json.load(json_data)
add_article(cnx, data[0]['articles'][0])

Chicken Lives Matter

September 1st, 2020

Pour one out for this chicken that was ritually sacrificed on behalf of my health sometime in the last few days by my Chinese ex-girlfriend’s1 priest/shaman somewhere in the godforsaken East.

I can already feel the chicken’s essence giving me power as its soul seeps slowly into my qi. I don’t know if this chicken will be enough for me to do the work to begin importing encyclopedia entries into mp-wp. It may take a few more chicken lives.

  1. I’ve left her on read for months but she persists []

July Search Update

July 18th, 2020

Work is progressing on the search bot.

I now have a configuration that will index the btcbase.org logs. The resulting index is not perfect - anything from reddit is excluded due to my ip being blocked, and many archive.is pages are not successfully indexed due to archive.is periodically going offline. There is an error when attempting to index any Bitcointalk link that I haven’t been able to resolve. Also, due to the timespan involved, many links have rotted and are lost forever. Most links provided as “shortened” links also no longer work. The results for this crawl should show up in the bot’s index about one week from now.

Work on the encyclopedia crawl progresses as well. Apify delivered a half-functional crawling script that works with their platform. At the moment I don’t have a configuration which allows the crawl to get all volumes of the encyclopedia. I am currently working with support to get this resolved.