|
|
codemadness - sfeed_tests - sfeed tests and RSS and Atom files |
|
|
 |
git clone git://git.codemadness.org/sfeed_tests (git://git.codemadness.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
README |
|
|
 |
LICENSE |
|
|
|
--- |
|
|
|
codemadness (109825B) |
|
|
|
--- |
|
|
|
1 <?xml version="1.0" encoding="UTF-8"?> |
|
|
|
2 <feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"> |
|
|
|
3 <title type="text">Codemadness</title> |
|
|
|
4 <subtitle type="text">blog with various projects and articles about computer-related things</subtitle> |
|
|
|
5 <updated>2020-09-03T00:00:00Z</updated> |
|
|
|
6 <link rel="alternate" type="text/html" href="https://www.codemadness.org" /> |
|
|
|
7 <id>https://www.codemadness.org/atom.xml</id> |
|
|
|
8 <link rel="self" type="application/atom+xml" href="https://www.codemadness.org/atom.xml" /> |
|
|
|
9 <entry> |
|
|
|
10 <title type="text">Sfeed_curses: a curses UI front-end for sfeed</title> |
|
|
|
11 <link rel="alternate" type="text/html" href="https://www.codemadness.org/sfeed_curses-ui.html" /> |
|
|
|
12 <id>https://www.codemadness.org/sfeed_curses-ui.html</id> |
|
|
|
13 <updated>2020-08-30T00:00:00Z</updated> |
|
|
|
14 <published>2020-06-25T00:00:00Z</published> |
|
|
|
15 <author> |
|
|
|
16 <name>hiltjo</name> |
|
|
|
17 <uri>https://www.codemadness.org</uri> |
|
|
|
18 </author> |
|
|
|
19 <summary type="text">Sfeed_curses is a curses UI front-end for the sfeed RSS/Atom parser</summary> |
|
|
|
20 <content type="html"><![CDATA[<h1>Sfeed_curses: a curses UI front-end for sfeed</h1> |
|
|
|
21 <p><strong>Last modification on </strong> <time>2020-08-30</time></p> |
|
|
|
22 <p>sfeed_curses is a curses UI front-end for <a href="sfeed.html">sfeed</a>.</p> |
|
|
|
23 |
|
|
|
24 <p>It shows the TAB-separated feed items in a graphical command-line UI. The |
|
|
|
25 interface has a look inspired by the <a href="http://www.mutt.org/">mutt mail |
|
|
|
26 client</a>. It has a sidebar panel for the feeds, a panel with a listing of |
|
|
|
27 the items and a small statusbar for the selected item/url. Some functions like |
|
|
|
28 searching and scrolling are integrated in the interface itself.</p> |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 <h2>Features</h2> |
|
|
|
32 <ul> |
|
|
|
33 <li>Relatively few LOC, about 2K lines of C.</li> |
|
|
|
34 <li>Few dependencies: a C compiler and a curses library (typically ncurses). |
|
|
|
35 It also requires a terminal (emulator) supporting UTF-8.</li> |
|
|
|
36 <li>Easy to customize by modifying the small source-code and shellscripts.</li> |
|
|
|
37 <li>Quite fast.</li> |
|
|
|
38 <li>Plumb support: open the url or an enclosure url directly with any program.</li> |
|
|
|
39 <li>Pipe support: pipe the selected Tab-Separated Value line to a program for |
|
|
|
40 scripting purposes. Like viewing the content in any way you like.</li> |
|
|
|
41 <li>Yank support: copy the url or an enclosure url to the clipboard.</li> |
|
|
|
42 <li>Familiar keybinds: supports both vi-like, emacs-like and arrow keys for |
|
|
|
43 actions.</li> |
|
|
|
44 <li>Mouse support: xterm mouse-mode, if supported by the terminal emulator.</li> |
|
|
|
45 <li>Support two ways of managing read/unread items. |
|
|
|
46 By default sfeed_curses marks the feed items of the last day as new/bold. |
|
|
|
47 Alternatively a simple plain-text list with the read urls can be used.</li> |
|
|
|
48 </ul> |
|
|
|
49 |
|
|
|
50 |
|
|
|
51 <p>Like the format programs included in sfeed you can run it by giving the feed |
|
|
|
52 files as arguments like this:</p> |
|
|
|
53 <pre><code>sfeed_curses ~/.sfeed/feeds/*</code></pre> |
|
|
|
54 |
|
|
|
55 <p>... or by reading directly from stdin:</p> |
|
|
|
56 <pre><code>sfeed_curses < ~/.sfeed/feeds/xkcd</code></pre> |
|
|
|
57 |
|
|
|
58 <p>It will show a sidebar if one or more files are specified as parameters. It will |
|
|
|
59 not show the sidebar by default when reading from stdin.</p> |
|
|
|
60 |
|
|
|
61 <p><a href="downloads/screenshots/sfeed_curses_screenshot.png"><img src="downloads/screenshots/sfeed_curses_screenshot.png" width="480" height="270" alt="Screenshot showing what the UI looks" loading="lazy" /></a></p> |
|
|
|
62 |
|
|
|
63 |
|
|
|
64 <p>On pressing the 'o' or ENTER keybind it will open the link url of an item with the plumb program. |
|
|
|
65 On pressing the 'a', 'e' or '@' keybind it will open the enclosure url if there is one. |
|
|
|
66 The default plumb program is set to "<a href="https://portland.freedesktop.org/doc/xdg-open.html">xdg-open</a>", |
|
|
|
67 but can be modified by setting the environment variable $SFEED_PLUMBER. |
|
|
|
68 The plumb program receives the url as a command-line argument.</p> |
|
|
|
69 |
|
|
|
70 |
|
|
|
71 <p>The TAB-Separated-Value line of the current selected item in the feed file |
|
|
|
72 can be piped to a program by pressing the 'c', 'p' or '|' keybind. This allows |
|
|
|
73 much flexibility to make a content formatter or write other custom actions or |
|
|
|
74 views. This line is in the exact same format as described in the sfeed(5) man |
|
|
|
75 page. |
|
|
|
76 The pipe program can be changed by setting the environment variable $SFEED_PIPER. |
|
|
|
77 </p> |
|
|
|
78 |
|
|
|
79 <p><a href="downloads/screenshots/sfeed_curses_pipe_screenshot.png"><img src="downloads/screenshots/sfeed_curses_pipe_screenshot.png" width="480" height="270" alt="Screenshot showing the output of the pipe content script" loading="lazy" /></a></p> |
|
|
|
80 |
|
|
|
81 <p>The above screenshot shows the included |
|
|
|
82 <a href="https://git.codemadness.org/sfeed_curses/file/sfeed_content.html">sfeed_content</a> |
|
|
|
83 shellscript which uses the <a href="https://invisible-island.net/lynx/">lynx text-browser</a> |
|
|
|
84 to convert HTML to plain-text. |
|
|
|
85 It pipes the formatted plain-text to the user $PAGER (or "less"). |
|
|
|
86 Of course the script can be easily changed to use a different browser like |
|
|
|
87 <a href="http://w3m.sourceforge.net/">w3m</a>, |
|
|
|
88 <a href="http://www.jikos.cz/~mikulas/links/">links</a>, |
|
|
|
89 <a href="https://www.dillo.org/">dillo</a> or |
|
|
|
90 <a href="https://git.codemadness.org/webdump/file/README.html">webdump</a>.</p> |
|
|
|
91 |
|
|
|
92 <p>It's easy to modify the colorscheme by changing the macros in the source-code. |
|
|
|
93 On the left a <a href="https://templeos.org/">TempleOS</a>-like colorscheme on the right a <a href="https://newsboat.org/">newsboat</a>-like colorscheme. |
|
|
|
94 The README file contains the macros for these schemes.</p> |
|
|
|
95 |
|
|
|
96 <p><a href="downloads/screenshots/sfeed_curses_theme_screenshot.png"><img src="downloads/screenshots/sfeed_curses_theme_screenshot.png" width="480" height="270" alt="Screenshot showing a custom colorscheme" loading="lazy" /></a></p> |
|
|
|
97 |
|
|
|
98 |
|
|
|
99 <h2>Clone</h2> |
|
|
|
100 <pre><code>git clone git://<a href="//git.codemadness.org/sfeed_curses/">git.codemadness.org/sfeed_curses</a></code></pre> |
|
|
|
101 |
|
|
|
102 |
|
|
|
103 <h2>Download releases</h2> |
|
|
|
104 <p> |
|
|
|
105 Releases are available at: |
|
|
|
106 <a href="/releases/sfeed_curses/">https://codemadness.org/releases/sfeed_curses/</a>. |
|
|
|
107 </p> |
|
|
|
108 |
|
|
|
109 |
|
|
|
110 <h2>Build and install</h2> |
|
|
|
111 |
|
|
|
112 <pre><code>$ make |
|
|
|
113 # make install</code></pre> |
|
|
|
114 ]]></content> |
|
|
|
115 </entry> |
|
|
|
116 <entry> |
|
|
|
117 <title type="text">hurl: HTTP, HTTPS and Gopher file grabber</title> |
|
|
|
118 <link rel="alternate" type="text/html" href="https://www.codemadness.org/hurl.html" /> |
|
|
|
119 <id>https://www.codemadness.org/hurl.html</id> |
|
|
|
120 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
121 <published>2019-11-10T00:00:00Z</published> |
|
|
|
122 <author> |
|
|
|
123 <name>hiltjo</name> |
|
|
|
124 <uri>https://www.codemadness.org</uri> |
|
|
|
125 </author> |
|
|
|
126 <summary type="text">hurl: HTTP, HTTPS and Gopher file grabber</summary> |
|
|
|
127 <content type="html"><![CDATA[<h1>hurl: HTTP, HTTPS and Gopher file grabber</h1> |
|
|
|
128 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
129 <p>hurl is a relatively simple HTTP, HTTPS and Gopher client/file grabber.</p> |
|
|
|
130 |
|
|
|
131 |
|
|
|
132 <h2>Why?</h2> |
|
|
|
133 |
|
|
|
134 <p>Sometimes (or most of the time?) you just want to fetch a file via the HTTP, |
|
|
|
135 HTTPS or Gopher protocol.</p> |
|
|
|
136 |
|
|
|
137 <p>The focus of this tool is only this.</p> |
|
|
|
138 |
|
|
|
139 |
|
|
|
140 <h2>Features</h2> |
|
|
|
141 |
|
|
|
142 <ul> |
|
|
|
143 <li>Uses OpenBSD pledge(2) and unveil(2). Allow no filesystem access (writes to |
|
|
|
144 stdout).</li> |
|
|
|
145 <li>Impose time-out and maximum size limits.</li> |
|
|
|
146 <li>Use well-defined exitcodes for reliable scripting (curl sucks at this).</li> |
|
|
|
147 <li>Send as little information as possible (no User-Agent etc by default).</li> |
|
|
|
148 </ul> |
|
|
|
149 |
|
|
|
150 |
|
|
|
151 <h2>Anti-features</h2> |
|
|
|
152 |
|
|
|
153 <ul> |
|
|
|
154 <li>No HTTP byte range support.</li> |
|
|
|
155 <li>No HTTP User-Agent.</li> |
|
|
|
156 <li>No HTTP If-Modified-Since/If-* support.</li> |
|
|
|
157 <li>No HTTP auth support.</li> |
|
|
|
158 <li>No HTTP/2+ support.</li> |
|
|
|
159 <li>No HTTP keep-alive.</li> |
|
|
|
160 <li>No HTTP chunked-encoding support.</li> |
|
|
|
161 <li>No HTTP redirect support.</li> |
|
|
|
162 <li>No (GZIP) compression support.</li> |
|
|
|
163 <li>No cookie-jar or cookie parsing support.</li> |
|
|
|
164 <li>No Gopher text handling (".\r\n").</li> |
|
|
|
165 <li>... etc...</li> |
|
|
|
166 </ul> |
|
|
|
167 |
|
|
|
168 |
|
|
|
169 <h2>Dependencies</h2> |
|
|
|
170 |
|
|
|
171 <ul> |
|
|
|
172 <li>C compiler (C99).</li> |
|
|
|
173 <li>libc + some BSD functions like err() and strlcat().</li> |
|
|
|
174 <li>LibreSSL(-portable)</li> |
|
|
|
175 <li>libtls (part of LibreSSL).</li> |
|
|
|
176 </ul> |
|
|
|
177 |
|
|
|
178 |
|
|
|
179 <h2>Optional dependencies</h2> |
|
|
|
180 |
|
|
|
181 <ul> |
|
|
|
182 <li>POSIX make(1) (for Makefile).</li> |
|
|
|
183 <li>mandoc for documentation: https://mdocml.bsd.lv/</li> |
|
|
|
184 </ul> |
|
|
|
185 |
|
|
|
186 |
|
|
|
187 <h2>Clone</h2> |
|
|
|
188 <pre><code>git clone git://<a href="//git.codemadness.org/hurl/">git.codemadness.org/hurl</a></code></pre> |
|
|
|
189 |
|
|
|
190 |
|
|
|
191 <h2>Download releases</h2> |
|
|
|
192 <p> |
|
|
|
193 Releases are available at: |
|
|
|
194 <a href="/releases/hurl/">https://codemadness.org/releases/hurl/</a>. |
|
|
|
195 </p> |
|
|
|
196 |
|
|
|
197 |
|
|
|
198 <h2>Build and install</h2> |
|
|
|
199 |
|
|
|
200 <pre><code>$ make |
|
|
|
201 # make install</code></pre> |
|
|
|
202 |
|
|
|
203 |
|
|
|
204 <h2>Examples</h2> |
|
|
|
205 |
|
|
|
206 <p> |
|
|
|
207 Fetch the Atom feed from this site using a maximum filesize limit of 1MB and |
|
|
|
208 a time-out limit of 15 seconds: |
|
|
|
209 </p> |
|
|
|
210 |
|
|
|
211 <pre><code>hurl -m 1048576 -t 15 "https://codemadness.org/atom.xml"</code></pre> |
|
|
|
212 |
|
|
|
213 <p> |
|
|
|
214 There is an -H option to add custom headers. This way some of the anti-features |
|
|
|
215 listed above are supported. For example some CDNs like Cloudflare are known to block |
|
|
|
216 empty or certain User-Agents. |
|
|
|
217 </p> |
|
|
|
218 |
|
|
|
219 <p>User-Agent:</p> |
|
|
|
220 |
|
|
|
221 <pre><code>hurl -H 'User-Agent: some browser' 'https://codemadness.org/atom.xml'</code></pre> |
|
|
|
222 |
|
|
|
223 <p>HTTP Basic Auth (base64-encoded username:password):</p> |
|
|
|
224 |
|
|
|
225 <pre><code>hurl -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' 'https://codemadness.org/atom.xml'</code></pre> |
|
|
|
226 |
|
|
|
227 <p>GZIP (this assumes the served response Content-Type is gzip):</p> |
|
|
|
228 |
|
|
|
229 <pre><code>hurl -H 'Accept-Encoding: gzip' 'https://somesite/' | gzip -d</code></pre> |
|
|
|
230 ]]></content> |
|
|
|
231 </entry> |
|
|
|
232 <entry> |
|
|
|
233 <title type="text">json2tsv: a JSON to TSV converter</title> |
|
|
|
234 <link rel="alternate" type="text/html" href="https://www.codemadness.org/json2tsv.html" /> |
|
|
|
235 <id>https://www.codemadness.org/json2tsv.html</id> |
|
|
|
236 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
237 <published>2019-10-13T00:00:00Z</published> |
|
|
|
238 <author> |
|
|
|
239 <name>hiltjo</name> |
|
|
|
240 <uri>https://www.codemadness.org</uri> |
|
|
|
241 </author> |
|
|
|
242 <summary type="text">json2tsv: a JSON to TAB-Separated Value converter</summary> |
|
|
|
243 <content type="html"><![CDATA[<h1>json2tsv: a JSON to TSV converter</h1> |
|
|
|
244 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
245 <p> |
|
|
|
246 json2tsv reads JSON data from stdin. It outputs each JSON type to a |
|
|
|
247 TAB-Separated Value format per line. |
|
|
|
248 </p> |
|
|
|
249 |
|
|
|
250 |
|
|
|
251 <h2>TAB-Separated Value format</h2> |
|
|
|
252 |
|
|
|
253 <p>The output format per line is:</p> |
|
|
|
254 <pre><code>nodename<TAB>type<TAB>value<LF></code></pre> |
|
|
|
255 |
|
|
|
256 <p> |
|
|
|
257 Control-characters such as a newline, TAB and backslash (\n, \t and \\) are |
|
|
|
258 escaped in the nodename and value fields. Other control-characters are |
|
|
|
259 removed. |
|
|
|
260 </p> |
|
|
|
261 |
|
|
|
262 <p> |
|
|
|
263 The type field is a single byte and can be: |
|
|
|
264 </p> |
|
|
|
265 |
|
|
|
266 <ul> |
|
|
|
267 <li>a for array</li> |
|
|
|
268 <li>b for bool</li> |
|
|
|
269 <li>n for number</li> |
|
|
|
270 <li>o for object</li> |
|
|
|
271 <li>s for string</li> |
|
|
|
272 <li>? for null</li> |
|
|
|
273 </ul> |
|
|
|
274 |
|
|
|
275 <p> |
|
|
|
276 Filtering on the first field "nodename" is easy using awk for example. |
|
|
|
277 </p> |
|
|
|
278 |
|
|
|
279 |
|
|
|
280 <h2>Features</h2> |
|
|
|
281 <ul> |
|
|
|
282 <li>Accepts all <strong>valid</strong> JSON.</li> |
|
|
|
283 <li>Designed to work well with existing UNIX programs like awk and grep.</li> |
|
|
|
284 <li>Straightforward and not much lines of code: about 475 lines of C.</li> |
|
|
|
285 <li>Few dependencies: C compiler (C99), libc.</li> |
|
|
|
286 <li>No need to learn a new (meta-)language for processing data.</li> |
|
|
|
287 <li>The parser supports code point decoding (\u2303) and UTF-16 surrogates (\ud83d\ude02) to UTF-8.</li> |
|
|
|
288 <li>It does not output control-characters to the terminal for security reasons by default (but it has a -r option if needed).</li> |
|
|
|
289 <li>On OpenBSD it supports <a href="https://man.openbsd.org/pledge">pledge(2)</a> for syscall restriction, pledge("stdio", NULL).</li> |
|
|
|
290 </ul> |
|
|
|
291 |
|
|
|
292 |
|
|
|
293 <h2>Cons</h2> |
|
|
|
294 <ul> |
|
|
|
295 <li>For the tool there is additional overhead by processing and filtering data |
|
|
|
296 from stdin after parsing.</li> |
|
|
|
297 <li>The parser does not do complete validation on numbers.</li> |
|
|
|
298 <li>The parser accepts some bad input such as invalid UTF-8 |
|
|
|
299 (see <a href="https://tools.ietf.org/html/rfc8259#section-8.1">RFC8259 - 8.1. Character Encoding</a>). |
|
|
|
300 json2tsv reads from stdin and does not do assumptions about a "closed ecosystem" |
|
|
|
301 as described in the RFC.</li> |
|
|
|
302 <li>The parser accepts some bad JSON input and "extensions" |
|
|
|
303 (see <a href="https://tools.ietf.org/html/rfc8259#section-9">RFC8259 - 9. Parsers</a>).</li> |
|
|
|
304 <li>Encoded NUL bytes (\u0000) in strings are ignored. |
|
|
|
305 (see <a href="https://tools.ietf.org/html/rfc8259#section-9">RFC8259 - 9. Parsers</a>). |
|
|
|
306 "An implementation may set limits on the length and character contents of |
|
|
|
307 strings."</li> |
|
|
|
308 <li>The parser is not the fastest possible JSON parser (but also not the slowest). |
|
|
|
309 For example: for ease of use, at the cost of performance all strings are |
|
|
|
310 decoded, even though they may be unused. |
|
|
|
311 </li> |
|
|
|
312 </ul> |
|
|
|
313 |
|
|
|
314 |
|
|
|
315 <h2>Why Yet Another JSON parser?</h2> |
|
|
|
316 <p> |
|
|
|
317 I wanted a tool that makes parsing JSON easier and work well from the shell, similar to |
|
|
|
318 <a href="https://stedolan.github.io/jq/">jq</a>. |
|
|
|
319 </p> |
|
|
|
320 |
|
|
|
321 <p> |
|
|
|
322 sed and grep often work well enough for matching some value using some regex pattern, |
|
|
|
323 but it is not good enough to parse JSON correctly or to extract all information: |
|
|
|
324 just like parsing HTML/XML using some regex is not good (enough) or a good idea :P. |
|
|
|
325 </p> |
|
|
|
326 |
|
|
|
327 <p> |
|
|
|
328 I didn't want to learn a new |
|
|
|
329 <a href="https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions">specific meta-language which jq has</a> |
|
|
|
330 and wanted something simpler. |
|
|
|
331 While it is more efficient to embed this query language for data aggregation, |
|
|
|
332 it is also less simple. In my opinion it is simpler to separate this and use |
|
|
|
333 pattern-processing by awk or an other filtering/aggregating program. |
|
|
|
334 </p> |
|
|
|
335 |
|
|
|
336 <p> |
|
|
|
337 For the parser, there are many JSON parsers out there, like the efficient |
|
|
|
338 <a href="https://github.com/zserge/jsmn">jsmn parser</a>, however a few parser |
|
|
|
339 behaviours I want to have are: |
|
|
|
340 </p> |
|
|
|
341 |
|
|
|
342 <ul> |
|
|
|
343 <li>jsmn buffers data as tokens, which is very efficient, but also a bit |
|
|
|
344 annoying as an API as it requires another layer of code to interpret the |
|
|
|
345 tokens.</li> |
|
|
|
346 <li>jsmn does not handle decoding strings by default. Which is very efficient |
|
|
|
347 if you don't need parts of the data though.</li> |
|
|
|
348 <li>jsmn does not keep context of nested structures by default, so again requires |
|
|
|
349 writing custom utility functions for nested data.</li> |
|
|
|
350 </ul> |
|
|
|
351 |
|
|
|
352 <p> |
|
|
|
353 I went for a parser design that uses a single callback per "node" type and |
|
|
|
354 keeps track of the current nested structure in a single array and emits that. |
|
|
|
355 </p> |
|
|
|
356 |
|
|
|
357 |
|
|
|
358 <h2>Clone</h2> |
|
|
|
359 <pre><code>git clone git://<a href="//git.codemadness.org/json2tsv/">git.codemadness.org/json2tsv</a></code></pre> |
|
|
|
360 |
|
|
|
361 |
|
|
|
362 <h2>Download releases</h2> |
|
|
|
363 <p> |
|
|
|
364 Releases are available at: |
|
|
|
365 <a href="/releases/json2tsv/">https://codemadness.org/releases/json2tsv/</a>. |
|
|
|
366 </p> |
|
|
|
367 |
|
|
|
368 |
|
|
|
369 <h2>Build and install</h2> |
|
|
|
370 |
|
|
|
371 <pre><code>$ make |
|
|
|
372 # make install</code></pre> |
|
|
|
373 |
|
|
|
374 |
|
|
|
375 <h2>Examples</h2> |
|
|
|
376 |
|
|
|
377 <p> |
|
|
|
378 An usage example to parse posts of the JSON API of |
|
|
|
379 <a href="https://www.reddit.com/">reddit.com</a> |
|
|
|
380 and format them to a plain-text list using awk: |
|
|
|
381 </p> |
|
|
|
382 |
|
|
|
383 <pre><code>#!/bin/sh |
|
|
|
384 curl -s -H 'User-Agent:' 'https://old.reddit.com/.json?raw_json=1&limit=100' | \ |
|
|
|
385 json2tsv | \ |
|
|
|
386 awk -F '\t' ' |
|
|
|
387 function show() { |
|
|
|
388 if (length(o["title"]) == 0) |
|
|
|
389 return; |
|
|
|
390 print n ". " o["title"] " by " o["author"] " in r/" o["subreddit"]; |
|
|
|
391 print o["url"]; |
|
|
|
392 print ""; |
|
|
|
393 } |
|
|
|
394 $1 == ".data.children[].data" { |
|
|
|
395 show(); |
|
|
|
396 n++; |
|
|
|
397 delete o; |
|
|
|
398 } |
|
|
|
399 $1 ~ /^\.data\.children\[\]\.data\.[a-zA-Z0-9_]*$/ { |
|
|
|
400 o[substr($1, 23)] = $3; |
|
|
|
401 } |
|
|
|
402 END { |
|
|
|
403 show(); |
|
|
|
404 }' |
|
|
|
405 </code></pre> |
|
|
|
406 |
|
|
|
407 |
|
|
|
408 <h2>References</h2> |
|
|
|
409 <ul> |
|
|
|
410 <li> |
|
|
|
411 <strong>Sites:</strong> |
|
|
|
412 <ul> |
|
|
|
413 <li><a href="http://seriot.ch/parsing_json.php">seriot.ch - Parsing JSON is a Minefield</a></li> |
|
|
|
414 <li><a href="https://github.com/nst/JSONTestSuite">A comprehensive test suite for RFC 8259 compliant JSON parsers</a></li> |
|
|
|
415 <li><a href="https://json.org/">json.org</a></li> |
|
|
|
416 </ul> |
|
|
|
417 </li> |
|
|
|
418 <li> |
|
|
|
419 <strong>Current standard:</strong> |
|
|
|
420 <ul> |
|
|
|
421 <li><a href="https://tools.ietf.org/html/rfc8259">RFC8259 - The JavaScript Object Notation (JSON) Data Interchange Format</a></li> |
|
|
|
422 <li><a href="http://www.ecma-international.org/publications/standards/Ecma-404.htm">Standard ECMA-404 - The JSON Data Interchange Syntax (2nd edition (December 2017)</a></li> |
|
|
|
423 </ul> |
|
|
|
424 </li> |
|
|
|
425 <li> |
|
|
|
426 <strong>Historic standard:</strong> |
|
|
|
427 <ul> |
|
|
|
428 <li><a href="https://tools.ietf.org/html/rfc7159">RFC7159 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete)</a></li> |
|
|
|
429 <li><a href="https://tools.ietf.org/html/rfc7158">RFC7158 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete)</a></li> |
|
|
|
430 <li><a href="https://tools.ietf.org/html/rfc4627">RFC4627 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete, original)</a></li> |
|
|
|
431 </ul> |
|
|
|
432 </li> |
|
|
|
433 </ul> |
|
|
|
434 ]]></content> |
|
|
|
435 </entry> |
|
|
|
436 <entry> |
|
|
|
437 <title type="text">OpenBSD: setup a local auto-installation server</title> |
|
|
|
438 <link rel="alternate" type="text/html" href="https://www.codemadness.org/openbsd-autoinstall.html" /> |
|
|
|
439 <id>https://www.codemadness.org/openbsd-autoinstall.html</id> |
|
|
|
440 <updated>2020-04-30T00:00:00Z</updated> |
|
|
|
441 <published>2019-04-24T00:00:00Z</published> |
|
|
|
442 <author> |
|
|
|
443 <name>hiltjo</name> |
|
|
|
444 <uri>https://www.codemadness.org</uri> |
|
|
|
445 </author> |
|
|
|
446 <summary type="text">OpenBSD: setup a local auto-installation server</summary> |
|
|
|
447 <content type="html"><![CDATA[<h1>OpenBSD: setup a local auto-installation server</h1> |
|
|
|
448 <p><strong>Last modification on </strong> <time>2020-04-30</time></p> |
|
|
|
449 <p>This guide describes how to setup a local mirror and installation/upgrade |
|
|
|
450 server that requires little or no input interaction.</p> |
|
|
|
451 |
|
|
|
452 |
|
|
|
453 <h2>Setup a local HTTP mirror</h2> |
|
|
|
454 <p> |
|
|
|
455 The HTTP mirror will be used to fetch the base sets and (optional) custom sets. |
|
|
|
456 In this guide we will assume <b>192.168.0.2</b> is the local installation |
|
|
|
457 server and mirror, the CPU architecture is amd64 and the OpenBSD release |
|
|
|
458 version is 6.5. We will store the files in the directory with the structure: |
|
|
|
459 </p> |
|
|
|
460 |
|
|
|
461 <pre><code>http://192.168.0.2/pub/OpenBSD/6.5/amd64/</code></pre> |
|
|
|
462 |
|
|
|
463 <p>Create the www serve directory and fetch all sets and install files |
|
|
|
464 (if needed to save space *.iso and install65.fs can be skipped):</p> |
|
|
|
465 |
|
|
|
466 <pre><code>$ cd /var/www/htdocs |
|
|
|
467 $ mkdir -p pub/OpenBSD/6.5/amd64/ |
|
|
|
468 $ cd pub/OpenBSD/6.5/amd64/ |
|
|
|
469 $ ftp 'ftp://ftp.nluug.nl/pub/OpenBSD/6.5/amd64/*'</code></pre> |
|
|
|
470 |
|
|
|
471 <p>Verify signature and check some checksums:</p> |
|
|
|
472 <pre><code>$ signify -C -p /etc/signify/openbsd-65-base.pub -x SHA256.sig</code></pre> |
|
|
|
473 |
|
|
|
474 <p>Setup <a href="https://man.openbsd.org/httpd.8">httpd(8)</a> for simple file serving:</p> |
|
|
|
475 <pre><code># $FAVORITE_EDITOR /etc/<a href="https://man.openbsd.org/httpd.conf.5">httpd.conf</a></code></pre> |
|
|
|
476 |
|
|
|
477 <p>A minimal example config:</p> |
|
|
|
478 <pre><code>server "*" { |
|
|
|
479 listen on * port 80 |
|
|
|
480 }</code></pre> |
|
|
|
481 |
|
|
|
482 <p>The default www root directory is: /var/www/htdocs/</p> |
|
|
|
483 |
|
|
|
484 <p>Enable the httpd daemon to start by default and start it now:</p> |
|
|
|
485 <pre><code># rcctl enable httpd |
|
|
|
486 # rcctl start httpd</code></pre> |
|
|
|
487 |
|
|
|
488 |
|
|
|
489 <h2>Creating an installation response/answer file</h2> |
|
|
|
490 <p>The installer supports loading responses to the installation/upgrade questions |
|
|
|
491 from a simple text file. We can do a regular installation and copy the answers from |
|
|
|
492 the saved file to make an automated version of it.</p> |
|
|
|
493 |
|
|
|
494 <p>Do a test installation, at the end of the installation or upgrade when asked the |
|
|
|
495 question:</p> |
|
|
|
496 <pre><code>Exit to (S)hell, (H)alt or (R)eboot?</code></pre> |
|
|
|
497 |
|
|
|
498 <p>Type S to go to the shell. Find the response file for an installation and copy it to some USB stick or |
|
|
|
499 write down the response answers:</p> |
|
|
|
500 <pre><code>cp /tmp/i/install.resp /mnt/usbstick/</code></pre> |
|
|
|
501 |
|
|
|
502 <p>A response file could be for example:</p> |
|
|
|
503 |
|
|
|
504 <pre><code>System hostname = testvm |
|
|
|
505 Which network interface do you wish to configure = em0 |
|
|
|
506 IPv4 address for em0 = dhcp |
|
|
|
507 IPv6 address for em0 = none |
|
|
|
508 Which network interface do you wish to configure = done |
|
|
|
509 Password for root account = $2b$10$IqI43aXjgD55Q3nLbRakRO/UAG6SAClL9pyk0vIUpHZSAcLx8fWk. |
|
|
|
510 Password for user testuser = $2b$10$IqI43aXjgD55Q3nLbRakRO/UAG6SAClL9pyk0vIUpHZSAcLx8fWk. |
|
|
|
511 Start sshd(8) by default = no |
|
|
|
512 Do you expect to run the X Window System = no |
|
|
|
513 Setup a user = testuser |
|
|
|
514 Full name for user testuser = testuser |
|
|
|
515 What timezone are you in = Europe/Amsterdam |
|
|
|
516 Which disk is the root disk = wd0 |
|
|
|
517 Use (W)hole disk MBR, whole disk (G)PT, (O)penBSD area or (E)dit = OpenBSD |
|
|
|
518 Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout = a |
|
|
|
519 Location of sets = http |
|
|
|
520 HTTP proxy URL = none |
|
|
|
521 HTTP Server = <b>192.168.0.2</b> |
|
|
|
522 Server directory = pub/OpenBSD/6.5/amd64 |
|
|
|
523 Unable to connect using https. Use http instead = yes |
|
|
|
524 Location of sets = http |
|
|
|
525 Set name(s) = done |
|
|
|
526 Location of sets = done |
|
|
|
527 Exit to (S)hell, (H)alt or (R)eboot = R</code></pre> |
|
|
|
528 |
|
|
|
529 <p>Get custom encrypted password for response file:</p> |
|
|
|
530 <pre><code>$ printf '%s' 'yourpassword' | encrypt</code></pre> |
|
|
|
531 |
|
|
|
532 |
|
|
|
533 <h2>Changing the RAMDISK kernel disk image</h2> |
|
|
|
534 |
|
|
|
535 <p><a href="https://man.openbsd.org/rdsetroot.8">rdsetroot(8)</a> is publicly |
|
|
|
536 exposed now in base since 6.5. Before 6.5 it is available in the /usr/src/ tree as |
|
|
|
537 elfrdsetroot, see also the <a href="https://man.openbsd.org/rd.4">rd(4)</a> man page.</p> |
|
|
|
538 |
|
|
|
539 <pre><code>$ mkdir auto |
|
|
|
540 $ cd auto |
|
|
|
541 $ cp pubdir/bsd.rd . |
|
|
|
542 $ rdsetroot -x bsd.rd disk.fs |
|
|
|
543 # vnconfig vnd0 disk.fs |
|
|
|
544 # mkdir mount |
|
|
|
545 # mount /dev/vnd0a mount</code></pre> |
|
|
|
546 |
|
|
|
547 <p>Copy the response file (install.resp) to: mount/auto_install.conf (installation) <b>or</b> |
|
|
|
548 mount/auto_upgrade.conf (upgrade), but not both. In this guide we will do an |
|
|
|
549 auto-installation.</p> |
|
|
|
550 |
|
|
|
551 <p>Unmount, detach and patch RAMDISK:</p> |
|
|
|
552 <pre><code># umount mount |
|
|
|
553 # vnconfig -u vnd0 |
|
|
|
554 $ rdsetroot bsd.rd disk.fs</code></pre> |
|
|
|
555 |
|
|
|
556 <p>To test copy bsd.rd to the root of some testmachine like /bsd.test.rd then |
|
|
|
557 (re)boot and type:</p> |
|
|
|
558 <pre><code>boot /bsd.test.rd</code></pre> |
|
|
|
559 |
|
|
|
560 <p>In the future (6.5+) it will be possible to copy to a file named "/bsd.upgrade" in the root of a current system |
|
|
|
561 and automatically load the kernel: |
|
|
|
562 <a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/stand/boot/boot.c?rev=1.46&content-type=text/x-cvsweb-markup">bsd.upgrade in CVS</a> |
|
|
|
563 ofcourse this is possible with PXE boot or some custom USB/ISO also. |
|
|
|
564 As explained in the <a href="https://man.openbsd.org/autoinstall.8">autoinstall(8)</a> man page: |
|
|
|
565 create either an auto_upgrade.conf <b>or</b> an auto_install.conf, but not both. |
|
|
|
566 </p> |
|
|
|
567 |
|
|
|
568 |
|
|
|
569 <h2>Create bootable miniroot</h2> |
|
|
|
570 |
|
|
|
571 <p>In this example the miniroot will boot the custom kernel, but fetch all the |
|
|
|
572 sets from the local network.</p> |
|
|
|
573 |
|
|
|
574 <p>We will base our miniroot of the official version: miniroot65.fs.</p> |
|
|
|
575 |
|
|
|
576 <p>We will create a 16MB miniroot to boot from (in this guide it is assumed the |
|
|
|
577 original miniroot is about 4MB and the modified kernel image fits in the new |
|
|
|
578 allocated space):</p> |
|
|
|
579 |
|
|
|
580 <pre><code>$ dd if=/dev/zero of=new.fs bs=512 count=32768</code></pre> |
|
|
|
581 |
|
|
|
582 <p>Copy first part of the original image to the new disk (no truncation):</p> |
|
|
|
583 |
|
|
|
584 <pre><code>$ dd conv=notrunc if=miniroot65.fs of=new.fs |
|
|
|
585 # vnconfig vnd0 new.fs</code></pre> |
|
|
|
586 |
|
|
|
587 |
|
|
|
588 <p>Expand disk OpenBSD boundaries:</p> |
|
|
|
589 |
|
|
|
590 <pre><code># disklabel -E vnd0 |
|
|
|
591 > <b>b</b> |
|
|
|
592 Starting sector: [1024] |
|
|
|
593 Size ('*' for entire disk): [8576] <b>*</b> |
|
|
|
594 > <b>r</b> |
|
|
|
595 Total free sectors: 1168. |
|
|
|
596 > <b>c a</b> |
|
|
|
597 Partition a is currently 8576 sectors in size, and can have a maximum |
|
|
|
598 size of 9744 sectors. |
|
|
|
599 size: [8576] <b>*</b> |
|
|
|
600 > <b>w</b> |
|
|
|
601 > <b>q</b></code></pre> |
|
|
|
602 |
|
|
|
603 <p>or:</p> |
|
|
|
604 |
|
|
|
605 <pre><code># printf 'b\n\n*\nc a\n*\nw\n' | disklabel -E vnd0</code></pre> |
|
|
|
606 |
|
|
|
607 |
|
|
|
608 <p>Grow filesystem and check it and mark as clean:</p> |
|
|
|
609 |
|
|
|
610 <pre><code># growfs -y /dev/vnd0a |
|
|
|
611 # fsck -y /dev/vnd0a</code></pre> |
|
|
|
612 |
|
|
|
613 |
|
|
|
614 <p>Mount filesystem:</p> |
|
|
|
615 <pre><code># mount /dev/vnd0a mount/</code></pre> |
|
|
|
616 |
|
|
|
617 <p>The kernel on the miniroot is GZIP compressed. Compress our modified bsd.rd |
|
|
|
618 and overwrite the original kernel:</p> |
|
|
|
619 |
|
|
|
620 <pre><code># gzip -c9n bsd.rd > mount/bsd</code></pre> |
|
|
|
621 |
|
|
|
622 <p>Or to save space (+- 500KB) by stripping debug symbols, taken from bsd.gz target in |
|
|
|
623 <a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/distrib/amd64/iso/Makefile">this Makefile</a>.</p> |
|
|
|
624 |
|
|
|
625 <pre><code>$ cp bsd.rd bsd.strip |
|
|
|
626 $ strip bsd.strip |
|
|
|
627 $ strip -R .comment -R .SUNW_ctf bsd.strip |
|
|
|
628 $ gzip -c9n bsd.strip > bsd.gz |
|
|
|
629 $ cp bsd.gz mount/bsd</code></pre> |
|
|
|
630 |
|
|
|
631 |
|
|
|
632 <p>Now unmount and detach:</p> |
|
|
|
633 |
|
|
|
634 <pre><code># umount mount/ |
|
|
|
635 # vnconfig -u vnd0</code></pre> |
|
|
|
636 |
|
|
|
637 <p>Now you can <a href="https://man.openbsd.org/dd.1">dd(1)</a> the image new.fs to your bootable (USB) medium.</p> |
|
|
|
638 |
|
|
|
639 |
|
|
|
640 <h2>Adding custom sets (optional)</h2> |
|
|
|
641 |
|
|
|
642 <p>For patching <a href="https://man.openbsd.org/rc.firsttime.8">/etc/rc.firsttime</a> and other |
|
|
|
643 system files it is useful to use a customized installation set like siteVERSION.tgz, for example: site65.tgz. |
|
|
|
644 The sets can even be specified per host/MAC address like: siteVERSION-$(hostname -s).tgz so for |
|
|
|
645 example: site65-testvm.tgz</p> |
|
|
|
646 |
|
|
|
647 <p>When the installer checks the base sets of the mirror it looks for a file index.txt. |
|
|
|
648 To add custom sets the site entries have to be added.</p> |
|
|
|
649 |
|
|
|
650 <p>For example:</p> |
|
|
|
651 <pre><code>-rw-r--r-- 1 1001 0 4538975 Oct 11 13:58:26 2018 site65-testvm.tgz</code></pre> |
|
|
|
652 |
|
|
|
653 <p>The filesize, permissions etc do not matter and are not checked by the installer. |
|
|
|
654 Only the filename is matched by a regular expression.</p> |
|
|
|
655 |
|
|
|
656 |
|
|
|
657 <h2>Sign custom site* tarball sets (optional)</h2> |
|
|
|
658 |
|
|
|
659 <p>If you have custom sets without creating a signed custom release you will be |
|
|
|
660 prompted for the messages:</p> |
|
|
|
661 <pre><code>checksum test failed</code></pre> |
|
|
|
662 <p>and:</p> |
|
|
|
663 <pre><code>unverified sets: continue without verification</code></pre> |
|
|
|
664 |
|
|
|
665 <p>OpenBSD uses the program <a href="https://man.openbsd.org/signify.1">signify(1)</a> |
|
|
|
666 to cryptographically sign and verify filesets.</p> |
|
|
|
667 |
|
|
|
668 <p>To create a custom public/private keypair (ofcourse make sure to store the private key privately):</p> |
|
|
|
669 <pre><code>$ signify -G -n -c "Custom 6.5 install" -p custom-65-base.pub -s custom-65-base.sec</code></pre> |
|
|
|
670 |
|
|
|
671 <p>Create new checksum file with filelist of the current directory (except SHA256* files):</p> |
|
|
|
672 <pre><code>$ printf '%s\n' * | grep -v SHA256 | xargs sha256 > SHA256</code></pre> |
|
|
|
673 |
|
|
|
674 <p>Sign SHA256 and store as SHA256.sig, embed signature:</p> |
|
|
|
675 <pre><code>$ signify -S -e -s /privatedir/custom-65-base.sec -m SHA256 -x SHA256.sig</code></pre> |
|
|
|
676 |
|
|
|
677 <p>Verify the created signature and data is correct:</p> |
|
|
|
678 <pre><code>$ signify -C -p /somelocation/custom-65-base.pub -x SHA256.sig</code></pre> |
|
|
|
679 |
|
|
|
680 <p>Copy <b>only</b> the <b>public</b> key to the RAMDISK:</p> |
|
|
|
681 <pre><code>$ cp custom-65-base.pub mount/etc/signify/custom-65-base.pub</code></pre> |
|
|
|
682 |
|
|
|
683 <p>Now we have to patch the install.sub file to check our public key. |
|
|
|
684 If you know a better way without having to patch this script, please let me know.</p> |
|
|
|
685 |
|
|
|
686 <p>Change the variable PUB_KEY in the shellscript mount/install.sub from:</p> |
|
|
|
687 |
|
|
|
688 <pre><code>PUB_KEY=/etc/signify/<b>openbsd</b>-${VERSION}-base.pub</code></pre> |
|
|
|
689 |
|
|
|
690 <p>To:</p> |
|
|
|
691 |
|
|
|
692 <pre><code>PUB_KEY=/etc/signify/<b>custom</b>-${VERSION}-base.pub</code></pre> |
|
|
|
693 |
|
|
|
694 <p>And for upgrades from:</p> |
|
|
|
695 |
|
|
|
696 <pre><code>$UPGRADE_BSDRD && |
|
|
|
697 PUB_KEY=/mnt/etc/signify/<b>openbsd</b>-$((VERSION + 1))-base.pub</code></pre> |
|
|
|
698 |
|
|
|
699 <p>To:</p> |
|
|
|
700 |
|
|
|
701 <pre><code>$UPGRADE_BSDRD && |
|
|
|
702 PUB_KEY=/mnt/etc/signify/<b>custom</b>-$((VERSION + 1))-base.pub</code></pre> |
|
|
|
703 |
|
|
|
704 |
|
|
|
705 <h2>Ideas</h2> |
|
|
|
706 <ul> |
|
|
|
707 <li>Patch <a href="https://man.openbsd.org/rc.firsttime.8">rc.firsttime(8)</a>: and run syspatch, add ports, setup xenodm etc.</li> |
|
|
|
708 <li>Custom partitioning scheme, see <a href="https://man.openbsd.org/autoinstall.8">autoinstall(8)</a> |
|
|
|
709 "URL to autopartitioning template for disklabel = url".</li> |
|
|
|
710 <li>Setup <a href="https://man.openbsd.org/pxeboot.8">pxeboot(8)</a> to boot and install over the network using |
|
|
|
711 <a href="https://man.openbsd.org/dhcpd.8">dhcpd(8)</a> and <a href="https://man.openbsd.org/tftpd.8">tftpd(8)</a> |
|
|
|
712 then not even some USB stick is required.</li> |
|
|
|
713 </ul> |
|
|
|
714 |
|
|
|
715 |
|
|
|
716 <h2>References</h2> |
|
|
|
717 <ul> |
|
|
|
718 <li>Main OpenBSD installation and upgrade shellscript: <a href="https://cvsweb.openbsd.org/src/distrib/miniroot/install.sub">/usr/src/distrib/miniroot/install.sub</a></li> |
|
|
|
719 </ul> |
|
|
|
720 ]]></content> |
|
|
|
721 </entry> |
|
|
|
722 <entry> |
|
|
|
723 <title type="text">Idiotbox: Youtube interface</title> |
|
|
|
724 <link rel="alternate" type="text/html" href="https://www.codemadness.org/idiotbox.html" /> |
|
|
|
725 <id>https://www.codemadness.org/idiotbox.html</id> |
|
|
|
726 <updated>2020-09-03T00:00:00Z</updated> |
|
|
|
727 <published>2019-02-10T00:00:00Z</published> |
|
|
|
728 <author> |
|
|
|
729 <name>hiltjo</name> |
|
|
|
730 <uri>https://www.codemadness.org</uri> |
|
|
|
731 </author> |
|
|
|
732 <summary type="text">Idiotbox: Youtube interface</summary> |
|
|
|
733 <content type="html"><![CDATA[<h1>Idiotbox: Youtube interface</h1> |
|
|
|
734 <p><strong>Last modification on </strong> <time>2020-09-03</time></p> |
|
|
|
735 <p> |
|
|
|
736 Idiotbox is a less resource-heavy Youtube interface. |
|
|
|
737 For viewing videos it is recommended to use it with |
|
|
|
738 <a href="https://mpv.io/">mpv</a> + |
|
|
|
739 <a href="https://rg3.github.io/youtube-dl/">youtube-dl</a>. |
|
|
|
740 </p> |
|
|
|
741 |
|
|
|
742 <p>For more (up-to-date) information see the <a href="/git/frontends/file/youtube/README.html">README</a> file.</p> |
|
|
|
743 |
|
|
|
744 |
|
|
|
745 <h2>Why</h2> |
|
|
|
746 <p> |
|
|
|
747 In my opinion the standard Youtube web interface is: |
|
|
|
748 </p> |
|
|
|
749 <ul> |
|
|
|
750 <li>Non-intuitive, too much visual crap.</li> |
|
|
|
751 <li>Too resource-hungry, both in CPU and bandwidth.</li> |
|
|
|
752 <li>Doesn't work well on simpler (text-based) browsers such as netsurf and links.</li> |
|
|
|
753 </ul> |
|
|
|
754 |
|
|
|
755 |
|
|
|
756 <h2>Features</h2> |
|
|
|
757 <ul> |
|
|
|
758 <li>Doesn't use JavaScript.</li> |
|
|
|
759 <li>Doesn't use (tracking) cookies.</li> |
|
|
|
760 <li>CSS is optional.</li> |
|
|
|
761 <li>Multiple interfaces available: CGI web, CLI, gopher (gph), this is a work-in-progress.</li> |
|
|
|
762 <li>Doesn't use or require the Google API.</li> |
|
|
|
763 <li>CGI interface works nice in most browsers, including text-based ones.</li> |
|
|
|
764 <li>On OpenBSD it runs "sandboxed" and it can be compiled as a static-linked binary with |
|
|
|
765 <a href="https://man.openbsd.org/pledge">pledge(2)</a>, |
|
|
|
766 <a href="https://man.openbsd.org/unveil">unveil(2)</a> in a chroot.</li> |
|
|
|
767 </ul> |
|
|
|
768 |
|
|
|
769 |
|
|
|
770 <h2>Cons</h2> |
|
|
|
771 <ul> |
|
|
|
772 <li>Order by upload date is incorrect (same as on Youtube).</li> |
|
|
|
773 <li>Some Youtube features are not supported.</li> |
|
|
|
774 <li>Uses scraping so might break at any point.</li> |
|
|
|
775 </ul> |
|
|
|
776 |
|
|
|
777 |
|
|
|
778 <h2>Clone</h2> |
|
|
|
779 <pre><code>git clone git://<a href="//git.codemadness.org/frontends/">git.codemadness.org/frontends</a></code></pre> |
|
|
|
780 |
|
|
|
781 |
|
|
|
782 <h2>Download releases</h2> |
|
|
|
783 <p> |
|
|
|
784 Releases are available at: |
|
|
|
785 <a href="/releases/frontends/">https://codemadness.org/releases/frontends/</a>. |
|
|
|
786 </p> |
|
|
|
787 |
|
|
|
788 |
|
|
|
789 <h2>View</h2> |
|
|
|
790 <p> |
|
|
|
791 <a href="https://codemadness.org/idiotbox/">You can view it here</a>. |
|
|
|
792 </p> |
|
|
|
793 |
|
|
|
794 <p> |
|
|
|
795 <a href="https://codemadness.org/idiotbox/?q=gunther+tralala">Search example</a>. |
|
|
|
796 </p> |
|
|
|
797 ]]></content> |
|
|
|
798 </entry> |
|
|
|
799 <entry> |
|
|
|
800 <title type="text">Gopher HTTP proxy</title> |
|
|
|
801 <link rel="alternate" type="text/html" href="https://www.codemadness.org/gopher-proxy.html" /> |
|
|
|
802 <id>https://www.codemadness.org/gopher-proxy.html</id> |
|
|
|
803 <updated>2020-08-30T00:00:00Z</updated> |
|
|
|
804 <published>2018-08-17T00:00:00Z</published> |
|
|
|
805 <author> |
|
|
|
806 <name>hiltjo</name> |
|
|
|
807 <uri>https://www.codemadness.org</uri> |
|
|
|
808 </author> |
|
|
|
809 <summary type="text">Gopher HTTP proxy</summary> |
|
|
|
810 <content type="html"><![CDATA[<h1>Gopher HTTP proxy</h1> |
|
|
|
811 <p><strong>Last modification on </strong> <time>2020-08-30</time></p> |
|
|
|
812 <p> |
|
|
|
813 For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports |
|
|
|
814 the basic Gopher types and has some restrictions to prevent some abuse. |
|
|
|
815 </p> |
|
|
|
816 |
|
|
|
817 <p> |
|
|
|
818 For your regular Gopher browsing I recommend the simple Gopher client |
|
|
|
819 <a href="https://git.fifth.space/sacc/">sacc</a>. |
|
|
|
820 </p> |
|
|
|
821 |
|
|
|
822 <p> |
|
|
|
823 For more information about Gopher check out the gopherhole: |
|
|
|
824 <a href="http://gopherproject.org/">gopherproject.org</a>. |
|
|
|
825 </p> |
|
|
|
826 |
|
|
|
827 |
|
|
|
828 <h2>Clone</h2> |
|
|
|
829 <pre><code>git clone git://<a href="//git.codemadness.org/gopherproxy-c/">git.codemadness.org/gopherproxy-c</a></code></pre> |
|
|
|
830 |
|
|
|
831 |
|
|
|
832 <h2>View</h2> |
|
|
|
833 <p> |
|
|
|
834 <a href="https://codemadness.org/gopherproxy/">You can view it here</a>. |
|
|
|
835 </p> |
|
|
|
836 |
|
|
|
837 <p> |
|
|
|
838 <a href="/gopherproxy/?q=codemadness.org">My gopherhole using the proxy.</a> |
|
|
|
839 </p> |
|
|
|
840 ]]></content> |
|
|
|
841 </entry> |
|
|
|
842 <entry> |
|
|
|
843 <title type="text">Setup your own file paste service</title> |
|
|
|
844 <link rel="alternate" type="text/html" href="https://www.codemadness.org/paste-service.html" /> |
|
|
|
845 <id>https://www.codemadness.org/paste-service.html</id> |
|
|
|
846 <updated>2018-03-10T00:00:00Z</updated> |
|
|
|
847 <published>2018-03-10T00:00:00Z</published> |
|
|
|
848 <author> |
|
|
|
849 <name>hiltjo</name> |
|
|
|
850 <uri>https://www.codemadness.org</uri> |
|
|
|
851 </author> |
|
|
|
852 <summary type="text">Howto setup your own secure file paste service</summary> |
|
|
|
853 <content type="html"><![CDATA[<h1>Setup your own file paste service</h1> |
|
|
|
854 <p><strong>Last modification on </strong> <time>2018-03-10</time></p> |
|
|
|
855 <h2 id="SSH">Setup SSH authentication</h2> |
|
|
|
856 |
|
|
|
857 <p>Make sure to setup SSH public key authentication so you don't need to enter |
|
|
|
858 a password each time and have a more secure authentication.</p> |
|
|
|
859 |
|
|
|
860 <p>For example in the file $HOME/.ssh/config:</p> |
|
|
|
861 |
|
|
|
862 <pre><code>Host codemadness |
|
|
|
863 Hostname codemadness.org |
|
|
|
864 Port 22 |
|
|
|
865 IdentityFile ~/.ssh/codemadness/id_rsa |
|
|
|
866 </code></pre> |
|
|
|
867 |
|
|
|
868 <p>Of course also make sure to generate the private and public keys.</p> |
|
|
|
869 |
|
|
|
870 |
|
|
|
871 <h2 id="alias">Shell alias</h2> |
|
|
|
872 |
|
|
|
873 <p>Make an alias or function in your shell config:</p> |
|
|
|
874 <pre><code>pastesrv() { |
|
|
|
875 ssh user@codemadness "cat > /home/www/domains/codemadness.org/htdocs/paste/$1" |
|
|
|
876 echo "https://codemadness.org/paste/$1" |
|
|
|
877 }</code></pre> |
|
|
|
878 |
|
|
|
879 <p> |
|
|
|
880 This function reads any data from stdin and transfers the output securely via |
|
|
|
881 SSH and writes it to a file at the specified path. This path can be visible via |
|
|
|
882 HTTP, gopher or an other protocol. Then it writes the absolute url to stdout, |
|
|
|
883 this url can be copied to the clipboard and pasted anywhere like to an e-mail, |
|
|
|
884 IRC etc. |
|
|
|
885 </p> |
|
|
|
886 |
|
|
|
887 |
|
|
|
888 <h2 id="usage">Usage and examples</h2> |
|
|
|
889 |
|
|
|
890 <p>To use it, here are some examples:</p> |
|
|
|
891 |
|
|
|
892 <p>Create a patch of the last commit in the git repo and store it:</p> |
|
|
|
893 <pre><code>git format-patch --stdout HEAD^ | pastesrv 'somepatch.diff'</code></pre> |
|
|
|
894 |
|
|
|
895 <p>Create a screenshot of your current desktop and paste it:</p> |
|
|
|
896 <pre><code>xscreenshot | ff2png | pastesrv 'screenshot.png'</code></pre> |
|
|
|
897 |
|
|
|
898 <p>There are many other uses of course, use your imagination :)</p> |
|
|
|
899 ]]></content> |
|
|
|
900 </entry> |
|
|
|
901 <entry> |
|
|
|
902 <title type="text">Setup your own git hosting service</title> |
|
|
|
903 <link rel="alternate" type="text/html" href="https://www.codemadness.org/setup-git-hosting.html" /> |
|
|
|
904 <id>https://www.codemadness.org/setup-git-hosting.html</id> |
|
|
|
905 <updated>2019-12-06T00:00:00Z</updated> |
|
|
|
906 <published>2018-02-25T00:00:00Z</published> |
|
|
|
907 <author> |
|
|
|
908 <name>hiltjo</name> |
|
|
|
909 <uri>https://www.codemadness.org</uri> |
|
|
|
910 </author> |
|
|
|
911 <summary type="text">Howto setup your own git hosting service</summary> |
|
|
|
912 <content type="html"><![CDATA[<h1>Setup your own git hosting service</h1> |
|
|
|
913 <p><strong>Last modification on </strong> <time>2019-12-06</time></p> |
|
|
|
914 <p> |
|
|
|
915 <strong>This article assumes you use OpenBSD for the service files and OS-specific examples.</strong> |
|
|
|
916 </p> |
|
|
|
917 |
|
|
|
918 |
|
|
|
919 <h2>Why</h2> |
|
|
|
920 |
|
|
|
921 <p>A good reason to host your own git repositories is because of having control |
|
|
|
922 over your own computing. |
|
|
|
923 Assuming your hosting is secure you can be sure noone tampers with the data.</p> |
|
|
|
924 |
|
|
|
925 <p>A particular disturbing example was |
|
|
|
926 <a href="https://en.wikipedia.org/wiki/SourceForge#Controversies">the SourceForge ads/malware/hijack controversies</a>. |
|
|
|
927 <br/> |
|
|
|
928 <a href="https://gitlab.com/gitlab-org/gitaly/issues/2113">As of 2019-10-23 Gitlab added telemetry to their software</a>. |
|
|
|
929 <a href="https://about.gitlab.com/blog/2019/10/10/update-free-software-and-telemetry/">On 2019-10-24 they reverted it again because many people complained</a>. |
|
|
|
930 </p> |
|
|
|
931 |
|
|
|
932 <p>The same thing can happen with Github, Bitbucket or other similar services. |
|
|
|
933 After all: they are just a company with commercial interests.</p> |
|
|
|
934 |
|
|
|
935 <p>Always make sure you truly own the software and can host it yourself, this will keep you |
|
|
|
936 in control.</p> |
|
|
|
937 |
|
|
|
938 <p>These online services also have different pricing plans and various |
|
|
|
939 (arbitrary) restrictions. When you host it yourself the restrictions are the |
|
|
|
940 resource limits of the system and your connection, therefore it is a much more |
|
|
|
941 flexible solution.</p> |
|
|
|
942 |
|
|
|
943 |
|
|
|
944 <h2>Creating repositories</h2> |
|
|
|
945 |
|
|
|
946 <p>For the hosting it is recommended to use a so-called "bare" repository. |
|
|
|
947 A bare repository means no files are checked out in the folder itself. |
|
|
|
948 To create a bare repository use git init with the --bare argument:</p> |
|
|
|
949 |
|
|
|
950 <pre><code>$ git init --bare</code></pre> |
|
|
|
951 |
|
|
|
952 <p>I recommend to create a separate user and group for the source-code repositories. |
|
|
|
953 In the examples we will assume the user is called "src".</p> |
|
|
|
954 |
|
|
|
955 <p>Login as the src user and create the files. To create a directory for |
|
|
|
956 the repos, in this example /home/src/src:</p> |
|
|
|
957 |
|
|
|
958 <pre><code>$ mkdir -p /home/src/src |
|
|
|
959 $ cd /home/src/src |
|
|
|
960 $ git init --bare someproject |
|
|
|
961 $ $EDITOR someproject/description</code></pre> |
|
|
|
962 |
|
|
|
963 <p>Make sure the git-daemon process has access permissions to these repositories.</p> |
|
|
|
964 |
|
|
|
965 |
|
|
|
966 <h2>Install git-daemon (optional)</h2> |
|
|
|
967 |
|
|
|
968 <p>Using git-daemon you can clone the repositories publicly using the efficient |
|
|
|
969 git:// protocol. An alternative without having to use git-daemon is by using anonymous SSH, |
|
|
|
970 HTTPS or any public shared filesystem.</p> |
|
|
|
971 |
|
|
|
972 <p>When you use a private-only repository I recommend to just use SSH without |
|
|
|
973 git-daemon because it is secure.</p> |
|
|
|
974 |
|
|
|
975 <p>Install the git package. The package should contain "git daemon":</p> |
|
|
|
976 <pre><code># pkg_add git</code></pre> |
|
|
|
977 |
|
|
|
978 <p>Enable the daemon:</p> |
|
|
|
979 <pre><code># rcctl enable gitdaemon</code></pre> |
|
|
|
980 |
|
|
|
981 <p>Set the gitdaemon service flags to use the src directory and use all the available |
|
|
|
982 repositories in this directory. The command-line flags "--export-all" exports all |
|
|
|
983 repositories in the base path. Alternatively you can use the "git-daemon-export-ok" |
|
|
|
984 file (see the git-daemon man page). |
|
|
|
985 </p> |
|
|
|
986 |
|
|
|
987 <pre><code># rcctl set gitdaemon flags --export-all --base-path="/home/src/src"</code></pre> |
|
|
|
988 |
|
|
|
989 <p>To configure the service to run as the user _gitdaemon:</p> |
|
|
|
990 <pre><code># rcctl set gitdaemon user _gitdaemon</code></pre> |
|
|
|
991 |
|
|
|
992 <p>To run the daemon directly as the user _gitdaemon (without dropping priviledges from root |
|
|
|
993 to the user) set the following flags in /etc/rc.d/gitdaemon:</p> |
|
|
|
994 <pre><code>daemon_flags="--user=_gitdaemon"</code></pre> |
|
|
|
995 |
|
|
|
996 <p>Which will also avoid this warning while cloning:</p> |
|
|
|
997 <pre><code>"can't access /root/.git/config"</code></pre> |
|
|
|
998 |
|
|
|
999 |
|
|
|
1000 <p>Now start the daemon:</p> |
|
|
|
1001 <pre><code># rcctl start gitdaemon</code></pre> |
|
|
|
1002 |
|
|
|
1003 |
|
|
|
1004 <h2>Cloning and fetching changes</h2> |
|
|
|
1005 |
|
|
|
1006 <p>To test and clone the repository do:</p> |
|
|
|
1007 <pre><code>$ git clone git://yourdomain/someproject</code></pre> |
|
|
|
1008 |
|
|
|
1009 <p>if you skipped the optional git-daemon installation then just clone via SSH:</p> |
|
|
|
1010 <pre><code>$ git clone ssh://youraccount@yourdomain:/home/src/src/someproject</code></pre> |
|
|
|
1011 |
|
|
|
1012 <p>When cloning via SSH make sure to setup private/public key authentication for security |
|
|
|
1013 and convenience.</p> |
|
|
|
1014 |
|
|
|
1015 |
|
|
|
1016 <h2>Pushing changes</h2> |
|
|
|
1017 |
|
|
|
1018 <p>Add the repository as a remote:</p> |
|
|
|
1019 <pre><code>$ git remote add myremote ssh://youraccount@yourdomain:/home/src/src/someproject</code></pre> |
|
|
|
1020 |
|
|
|
1021 <p>Then push the changes:</p> |
|
|
|
1022 <pre><code>$ git push myremote master:master</code></pre> |
|
|
|
1023 |
|
|
|
1024 |
|
|
|
1025 <h2>Git history web browsing (optional)</h2> |
|
|
|
1026 |
|
|
|
1027 <p>Sometimes it's nice to browse the git history log of the repository in a |
|
|
|
1028 web browser or some other program without having to look at the local |
|
|
|
1029 repository.</p> |
|
|
|
1030 |
|
|
|
1031 <ul> |
|
|
|
1032 <li><a href="stagit.html">Stagit</a> is a static HTML page generator for git.</li> |
|
|
|
1033 <li><a href="stagit-gopher.html">Stagit-gopher</a> is a static page generator for |
|
|
|
1034 <a href="http://gopherproject.org/">gopher</a> and |
|
|
|
1035 <a href="gopher://bitreich.org/1/scm/geomyidae">geomyidae</a>.</li> |
|
|
|
1036 <li>cgit is a CGI-based program which shows HTML views of your repository, |
|
|
|
1037 see also the page: <a href="openbsd-httpd-and-cgit.html">OpenBSD httpd, slowcgi and cgit</a>.</li> |
|
|
|
1038 </ul> |
|
|
|
1039 |
|
|
|
1040 <p>It's also possible with these tools to generate an Atom feed and then use a RSS/Atom reader |
|
|
|
1041 to track the git history:</p> |
|
|
|
1042 |
|
|
|
1043 <ul> |
|
|
|
1044 <li>An example url from cgit: |
|
|
|
1045 <a href="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/">Linux kernel tree</a>.</li> |
|
|
|
1046 |
|
|
|
1047 <li>An example url from stagit: |
|
|
|
1048 <a href="//git.codemadness.org/www.codemadness.org/atom.xml">www.codemadness.org</a>.</li> |
|
|
|
1049 </ul> |
|
|
|
1050 |
|
|
|
1051 <p> |
|
|
|
1052 My <a href="sfeed-simple-feed-parser.html">sfeed</a> program can be used as a RSS/Atom reader. |
|
|
|
1053 </p> |
|
|
|
1054 |
|
|
|
1055 |
|
|
|
1056 <h2>Setting up git hooks (optional)</h2> |
|
|
|
1057 |
|
|
|
1058 <p> |
|
|
|
1059 Using git hooks you can setup automated triggers, for example when pushing to a repository. |
|
|
|
1060 Some useful examples can be: |
|
|
|
1061 </p> |
|
|
|
1062 |
|
|
|
1063 <ul> |
|
|
|
1064 <li><a href="/git/stagit/file/example_post-receive.sh.html">For |
|
|
|
1065 stagit: update the repo files (example post-receive hook).</a></li> |
|
|
|
1066 <li>Send an e-mail with the commit subject and message.</li> |
|
|
|
1067 <li>Log/notify commits and changes to an IRC channel using |
|
|
|
1068 <a href="https://tools.suckless.org/ii/">ii</a>.</li> |
|
|
|
1069 <li>Create a release tarball and checksum file on a tag push/change.</li> |
|
|
|
1070 <li>Checkout files for website content.</li> |
|
|
|
1071 </ul> |
|
|
|
1072 |
|
|
|
1073 |
|
|
|
1074 <p>I hope this is useful. Have fun.</p> |
|
|
|
1075 ]]></content> |
|
|
|
1076 </entry> |
|
|
|
1077 <entry> |
|
|
|
1078 <title type="text">Setup an OpenBSD SPARC64 VM in QEMU</title> |
|
|
|
1079 <link rel="alternate" type="text/html" href="https://www.codemadness.org/openbsd-sparc64-vm.html" /> |
|
|
|
1080 <id>https://www.codemadness.org/openbsd-sparc64-vm.html</id> |
|
|
|
1081 <updated>2020-04-18T00:00:00Z</updated> |
|
|
|
1082 <published>2017-12-11T00:00:00Z</published> |
|
|
|
1083 <author> |
|
|
|
1084 <name>hiltjo</name> |
|
|
|
1085 <uri>https://www.codemadness.org</uri> |
|
|
|
1086 </author> |
|
|
|
1087 <summary type="text">Setup an OpenBSD SPARC64 VM in QEMU</summary> |
|
|
|
1088 <content type="html"><![CDATA[<h1>Setup an OpenBSD SPARC64 VM in QEMU</h1> |
|
|
|
1089 <p><strong>Last modification on </strong> <time>2020-04-18</time></p> |
|
|
|
1090 <p>This describes how to setup an OpenBSD SPARC64 VM in QEMU.</p> |
|
|
|
1091 |
|
|
|
1092 |
|
|
|
1093 <h2>Create a disk image</h2> |
|
|
|
1094 <p>To create a 5GB disk image:</p> |
|
|
|
1095 <pre><code>qemu-img create -f qcow2 fs.qcow2 5G</code></pre> |
|
|
|
1096 |
|
|
|
1097 |
|
|
|
1098 <h2>Install</h2> |
|
|
|
1099 <p>In this guide we'll use the installation ISO to install OpenBSD. Make sure |
|
|
|
1100 to download the latest (stable) OpenBSD ISO, for example install62.iso.</p> |
|
|
|
1101 |
|
|
|
1102 <ul> |
|
|
|
1103 <li>Change -boot c to -boot d to boot from the CD-ROM and do a clean install.</li> |
|
|
|
1104 <li>Change -cdrom install62.iso to the location of your ISO file.</li> |
|
|
|
1105 <li>When the install is done type: halt -p</li> |
|
|
|
1106 <li>Change -boot d back to -boot c.</li> |
|
|
|
1107 </ul> |
|
|
|
1108 |
|
|
|
1109 <p>Start the VM:</p> |
|
|
|
1110 |
|
|
|
1111 <pre><code>#!/bin/sh |
|
|
|
1112 LC_ALL=C QEMU_AUDIO_DRV=none \ |
|
|
|
1113 qemu-system-sparc64 \ |
|
|
|
1114 -machine sun4u,usb=off \ |
|
|
|
1115 -realtime mlock=off \ |
|
|
|
1116 -smp 1,sockets=1,cores=1,threads=1 \ |
|
|
|
1117 -rtc base=utc \ |
|
|
|
1118 -m 1024 \ |
|
|
|
1119 -boot c \ |
|
|
|
1120 -drive file=fs.qcow2,if=none,id=drive-ide0-0-1,format=qcow2,cache=none \ |
|
|
|
1121 -cdrom install62.iso \ |
|
|
|
1122 -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-1,id=ide0-0-1 \ |
|
|
|
1123 -msg timestamp=on \ |
|
|
|
1124 -serial pty -nographic \ |
|
|
|
1125 -net nic,model=ne2k_pci -net user |
|
|
|
1126 </code></pre> |
|
|
|
1127 |
|
|
|
1128 <p>The VM has the following properties:</p> |
|
|
|
1129 <ul> |
|
|
|
1130 <li>No audio.</li> |
|
|
|
1131 <li>No USB.</li> |
|
|
|
1132 <li>No VGA graphics: serial console.</li> |
|
|
|
1133 <li>Netdev is ne0 (Realtek 8029).</li> |
|
|
|
1134 <li>1024MB memory.</li> |
|
|
|
1135 </ul> |
|
|
|
1136 |
|
|
|
1137 <p>From your host connect to the serial device indicated by QEMU, for example:</p> |
|
|
|
1138 <pre><code>(qemu) 2017-11-19T15:14:20.884312Z qemu-system-sparc64: -serial pty: char device redirected to <strong>/dev/ttyp0</strong> (label serial0)</code></pre> |
|
|
|
1139 |
|
|
|
1140 <p>Then you can use the serial terminal emulator <strong>cu</strong> to attach:</p> |
|
|
|
1141 <pre><code>cu -l <strong>/dev/ttyp0</strong></code></pre> |
|
|
|
1142 |
|
|
|
1143 <p>Another option could be using the <a href="https://git.suckless.org/st/">simple terminal (st)</a> from <a href="https://suckless.org/">suckless</a>:</p> |
|
|
|
1144 <pre><code>st -l <strong>/dev/ttyp0</strong></code></pre> |
|
|
|
1145 |
|
|
|
1146 <p>using cu to detach the <a href="https://man.openbsd.org/cu#~^D">cu(1) man page</a> says:</p> |
|
|
|
1147 |
|
|
|
1148 <pre><code>Typed characters are normally transmitted directly to the remote machine (which |
|
|
|
1149 does the echoing as well). A tilde ('~') appearing as the first character of a |
|
|
|
1150 line is an escape signal; the following are recognized: |
|
|
|
1151 |
|
|
|
1152 ~^D or ~. Drop the connection and exit. Only the connection is |
|
|
|
1153 the login session is not terminated.</code></pre> |
|
|
|
1154 |
|
|
|
1155 <p>On boot you have to type:</p> |
|
|
|
1156 |
|
|
|
1157 <pre><code>root device: <strong>wd0a</strong> |
|
|
|
1158 for swap use the default (wd0b) <strong>Press enter</strong></code></pre> |
|
|
|
1159 |
|
|
|
1160 |
|
|
|
1161 <h2>Initial settings on first boot (optional)</h2> |
|
|
|
1162 |
|
|
|
1163 <p>Automatic network configuration using DHCP</p> |
|
|
|
1164 <pre><code>echo "dhcp" > /etc/hostname.ne0</code></pre> |
|
|
|
1165 |
|
|
|
1166 <p>To bring up the interface (will be automatic on the next boot):</p> |
|
|
|
1167 <pre><code>sh /etc/netstart</code></pre> |
|
|
|
1168 |
|
|
|
1169 <p>Add a mirror to /etc/installurl for package installation. Make sure to lookup |
|
|
|
1170 the most efficient/nearby mirror site on the OpenBSD mirror page.</p> |
|
|
|
1171 <pre><code>echo "https://ftp.hostserver.de/pub/OpenBSD" > /etc/installurl</code></pre> |
|
|
|
1172 |
|
|
|
1173 |
|
|
|
1174 <p>I hope this is useful. Have fun.</p> |
|
|
|
1175 ]]></content> |
|
|
|
1176 </entry> |
|
|
|
1177 <entry> |
|
|
|
1178 <title type="text">Tscrape: a Twitter scraper</title> |
|
|
|
1179 <link rel="alternate" type="text/html" href="https://www.codemadness.org/tscrape.html" /> |
|
|
|
1180 <id>https://www.codemadness.org/tscrape.html</id> |
|
|
|
1181 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
1182 <published>2017-09-24T00:00:00Z</published> |
|
|
|
1183 <author> |
|
|
|
1184 <name>hiltjo</name> |
|
|
|
1185 <uri>https://www.codemadness.org</uri> |
|
|
|
1186 </author> |
|
|
|
1187 <summary type="text">Tscrape: a Twitter scraper</summary> |
|
|
|
1188 <content type="html"><![CDATA[<h1>Tscrape: a Twitter scraper</h1> |
|
|
|
1189 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
1190 <p>Tscrape is a Twitter web scraper and archiver.</p> |
|
|
|
1191 |
|
|
|
1192 <p>Twitter removed the functionality to follow users using a RSS feed without |
|
|
|
1193 authenticating or using their API. With this program you can format tweets in |
|
|
|
1194 any way you like relatively anonymously.</p> |
|
|
|
1195 |
|
|
|
1196 <p>For more (up-to-date) information see the <a href="/git/tscrape/file/README.html">README</a> file.</p> |
|
|
|
1197 |
|
|
|
1198 |
|
|
|
1199 <h2>Clone</h2> |
|
|
|
1200 <pre><code>git clone git://<a href="//git.codemadness.org/tscrape/">git.codemadness.org/tscrape</a></code></pre> |
|
|
|
1201 |
|
|
|
1202 |
|
|
|
1203 <h2>Download releases</h2> |
|
|
|
1204 <p> |
|
|
|
1205 Releases are available at: |
|
|
|
1206 <a href="/releases/tscrape/">https://codemadness.org/releases/tscrape/</a>. |
|
|
|
1207 </p> |
|
|
|
1208 |
|
|
|
1209 |
|
|
|
1210 <h2>Examples</h2> |
|
|
|
1211 <p>Output format examples</p> |
|
|
|
1212 |
|
|
|
1213 <ul> |
|
|
|
1214 <li><a href="tscrape/tscrape_html.html">tscrape_html: HTML</a></li> |
|
|
|
1215 <li><a href="tscrape/tscrape_plain.txt">tscrape_plain: Text</a></li> |
|
|
|
1216 </ul> |
|
|
|
1217 ]]></content> |
|
|
|
1218 </entry> |
|
|
|
1219 <entry> |
|
|
|
1220 <title type="text">jsdatatable: a small datatable Javascript</title> |
|
|
|
1221 <link rel="alternate" type="text/html" href="https://www.codemadness.org/datatable.html" /> |
|
|
|
1222 <id>https://www.codemadness.org/datatable.html</id> |
|
|
|
1223 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
1224 <published>2017-09-24T00:00:00Z</published> |
|
|
|
1225 <author> |
|
|
|
1226 <name>hiltjo</name> |
|
|
|
1227 <uri>https://www.codemadness.org</uri> |
|
|
|
1228 </author> |
|
|
|
1229 <summary type="text">jsdatatable: a small datatable Javascript</summary> |
|
|
|
1230 <content type="html"><![CDATA[<h1>jsdatatable: a small datatable Javascript</h1> |
|
|
|
1231 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
1232 <p>This is a small datatable Javascript with no dependencies.</p> |
|
|
|
1233 |
|
|
|
1234 |
|
|
|
1235 <h2>Features</h2> |
|
|
|
1236 |
|
|
|
1237 <ul> |
|
|
|
1238 <li>Small: |
|
|
|
1239 <ul> |
|
|
|
1240 <li>Filesize: +- 9.1KB.</li> |
|
|
|
1241 <li>Lines: +- 300, not much code, so hopefully easy to understand.</li> |
|
|
|
1242 <li>No dependencies on other libraries like jQuery.</li> |
|
|
|
1243 </ul> |
|
|
|
1244 </li> |
|
|
|
1245 <li>Sorting on columns, multi-column support with shift-click.</li> |
|
|
|
1246 <li>Filtering values: case-insensitively, tokenized (separated by space).</li> |
|
|
|
1247 <li>Able to add custom filtering, parsing and sorting functions.</li> |
|
|
|
1248 <li>Helper function for delayed (150ms) filtering, so filtering feels more |
|
|
|
1249 responsive for big datasets.</li> |
|
|
|
1250 <li>Permissive ISC license, see LICENSE file.</li> |
|
|
|
1251 <li>"Lazy scroll" mode: |
|
|
|
1252 <ul> |
|
|
|
1253 <li>fixed column headers and renders only visible rows, this allows you to |
|
|
|
1254 "lazily" render millions of rows.</li> |
|
|
|
1255 </ul> |
|
|
|
1256 </li> |
|
|
|
1257 <li>Officially supported browsers are: |
|
|
|
1258 <ul> |
|
|
|
1259 <li>Firefox and Firefox ESR.</li> |
|
|
|
1260 <li>Chrome and most recent webkit-based browsers.</li> |
|
|
|
1261 <li>IE10+.</li> |
|
|
|
1262 </ul> |
|
|
|
1263 </li> |
|
|
|
1264 </ul> |
|
|
|
1265 |
|
|
|
1266 |
|
|
|
1267 <h2>Why? and a comparison</h2> |
|
|
|
1268 |
|
|
|
1269 <p> |
|
|
|
1270 It was created because all the other datatable scripts suck balls. |
|
|
|
1271 </p> |
|
|
|
1272 |
|
|
|
1273 <p> |
|
|
|
1274 Most Javascripts nowadays have a default dependency on jQuery, Bootstrap or other frameworks. |
|
|
|
1275 </p> |
|
|
|
1276 |
|
|
|
1277 <p> |
|
|
|
1278 jQuery adds about 97KB and Bootstrap adds about 100KB to your scripts and CSS as a dependency. |
|
|
|
1279 This increases the CPU, memory and bandwidth consumption and latency. It also adds |
|
|
|
1280 complexity to your scripts. |
|
|
|
1281 </p> |
|
|
|
1282 |
|
|
|
1283 <p> |
|
|
|
1284 jQuery was mostly used for backwards-compatibility in the Internet Explorer days, but is |
|
|
|
1285 most often not needed anymore. It contains functionality to query the DOM using CSS-like |
|
|
|
1286 selectors, but this is now supported with for example document.querySelectorAll. |
|
|
|
1287 Functionality like a JSON parser is standard available now: JSON.parse(). |
|
|
|
1288 </p> |
|
|
|
1289 |
|
|
|
1290 |
|
|
|
1291 <h3>Size comparison</h3> |
|
|
|
1292 |
|
|
|
1293 <p>All sizes are not "minified" or gzipped.</p> |
|
|
|
1294 |
|
|
|
1295 <table class="datatable"> |
|
|
|
1296 <thead> |
|
|
|
1297 <tr> |
|
|
|
1298 <th>Name</th> |
|
|
|
1299 <th class="a-r" data-parse="int">Total</th> |
|
|
|
1300 <th class="a-r" data-parse="int">JS</th> |
|
|
|
1301 <th class="a-r" data-parse="int">CSS</th> |
|
|
|
1302 <th class="a-r" data-parse="int">Images</th> |
|
|
|
1303 <th class="a-r" data-parse="int">jQuery</th> |
|
|
|
1304 </tr> |
|
|
|
1305 </thead> |
|
|
|
1306 <tbody> |
|
|
|
1307 <tr> |
|
|
|
1308 <td><a href="/git/jscancer/">jsdatatable</a></td> |
|
|
|
1309 <td class="a-r g" data-value="12900">12.9KB</td> |
|
|
|
1310 <td class="a-r g" data-value="9100">9.1KB</td> |
|
|
|
1311 <td class="a-r g" data-value="2500">2.5KB</td> |
|
|
|
1312 <td class="a-r g" data-value="1300">1.3KB</td> |
|
|
|
1313 <td class="a-r g" data-value="0">-</td> |
|
|
|
1314 </tr> |
|
|
|
1315 <tr> |
|
|
|
1316 <td><a href="https://datatables.net/">datatables.net</a> (without plugins)</td> |
|
|
|
1317 <td class="a-r r" data-value="563400">563.4KB</td> |
|
|
|
1318 <td class="a-r r" data-value="449300">449.3KB</td> |
|
|
|
1319 <td class="a-r r" data-value="16000">16KB</td> |
|
|
|
1320 <td class="a-r g" data-value="800">0.8KB</td> |
|
|
|
1321 <td class="a-r r" data-value="97300">97.3KB</td> |
|
|
|
1322 </tr> |
|
|
|
1323 <tr> |
|
|
|
1324 <td><a href="https://plugins.jquery.com/jdatatable/">jdatatable</a></td> |
|
|
|
1325 <td class="a-r r" data-value="154600">154.6KB</td> |
|
|
|
1326 <td class="a-r r" data-value="53000">53KB</td> |
|
|
|
1327 <td class="a-r g" data-value="1000">1KB</td> |
|
|
|
1328 <td class="a-r g" data-value="3300">3.3KB</td> |
|
|
|
1329 <td class="a-r r" data-value="97300">97.3KB</td> |
|
|
|
1330 </tr> |
|
|
|
1331 </tbody> |
|
|
|
1332 </table> |
|
|
|
1333 |
|
|
|
1334 <p> |
|
|
|
1335 Of course jsdatatable has less features (less is more!), but it does 90% of what's needed. |
|
|
|
1336 Because it is so small it is also much simpler understand and extend with required features |
|
|
|
1337 if needed. |
|
|
|
1338 </p> |
|
|
|
1339 |
|
|
|
1340 <p> |
|
|
|
1341 See also: <a href="http://idlewords.com/talks/website_obesity.htm">The website obesity crisis</a> |
|
|
|
1342 </p> |
|
|
|
1343 |
|
|
|
1344 |
|
|
|
1345 <h2>Clone</h2> |
|
|
|
1346 |
|
|
|
1347 <pre><code>git clone git://<a href="//git.codemadness.org/jscancer/">git.codemadness.org/jscancer</a></code></pre> |
|
|
|
1348 <p> |
|
|
|
1349 It is in the datatable directory. |
|
|
|
1350 </p> |
|
|
|
1351 |
|
|
|
1352 |
|
|
|
1353 <h2>Download releases</h2> |
|
|
|
1354 <p> |
|
|
|
1355 Releases are available at: |
|
|
|
1356 <a href="/releases/jscancer/">https://codemadness.org/releases/jscancer/</a>. |
|
|
|
1357 </p> |
|
|
|
1358 |
|
|
|
1359 |
|
|
|
1360 <h2>Usage</h2> |
|
|
|
1361 |
|
|
|
1362 <h3>Examples</h3> |
|
|
|
1363 |
|
|
|
1364 <p> |
|
|
|
1365 See example.html for an example. A stylesheet file datatable.css is also |
|
|
|
1366 included, it contains the icons as embedded images. |
|
|
|
1367 </p> |
|
|
|
1368 |
|
|
|
1369 <p> |
|
|
|
1370 A table should have the classname "datatable" set, it must contain a <thead> |
|
|
|
1371 for the column headers (<td> or <th>) and <tbody> element for the data. The |
|
|
|
1372 minimal code needed for a working datatable: |
|
|
|
1373 </p> |
|
|
|
1374 |
|
|
|
1375 <pre><code><html> |
|
|
|
1376 <body> |
|
|
|
1377 <input class="filter-text" /><!-- optional --> |
|
|
|
1378 <table class="datatable"> |
|
|
|
1379 <thead><!-- columns --> |
|
|
|
1380 <tr><td>Click me</td></tr> |
|
|
|
1381 </thead> |
|
|
|
1382 <tbody><!-- data --> |
|
|
|
1383 <tr><td>a</td></tr> |
|
|
|
1384 <tr><td>b</td></tr> |
|
|
|
1385 </tbody> |
|
|
|
1386 </table> |
|
|
|
1387 <script type="text/javascript" src="datatable.js"></script> |
|
|
|
1388 <script type="text/javascript">var datatables = datatable_autoload();</script> |
|
|
|
1389 </body> |
|
|
|
1390 </html> |
|
|
|
1391 </code></pre> |
|
|
|
1392 |
|
|
|
1393 |
|
|
|
1394 <h3>Column attributes</h3> |
|
|
|
1395 |
|
|
|
1396 <p> |
|
|
|
1397 The following column attributes are supported: |
|
|
|
1398 </p> |
|
|
|
1399 |
|
|
|
1400 <table class="datatable"> |
|
|
|
1401 <thead> |
|
|
|
1402 <tr> |
|
|
|
1403 <th>Attribute name</th> |
|
|
|
1404 <th>Description</th> |
|
|
|
1405 </tr> |
|
|
|
1406 </thead> |
|
|
|
1407 <tbody> |
|
|
|
1408 <tr> |
|
|
|
1409 <td>data-filterable</td> |
|
|
|
1410 <td>If "1" or "true" specifies if the column can be filtered, |
|
|
|
1411 default: "true".</td> |
|
|
|
1412 </tr> |
|
|
|
1413 <tr> |
|
|
|
1414 <td>data-parse</td> |
|
|
|
1415 <td>Specifies how to parse the values, default: "string", |
|
|
|
1416 which is datatable_parse_string(). See PARSING section |
|
|
|
1417 below.</td> |
|
|
|
1418 </tr> |
|
|
|
1419 <tr> |
|
|
|
1420 <td>data-sort</td> |
|
|
|
1421 <td>Specifies how to sort the values: default: "default", |
|
|
|
1422 which is datatable_sort_default(). See SORTING section |
|
|
|
1423 below.</td> |
|
|
|
1424 </tr> |
|
|
|
1425 <tr> |
|
|
|
1426 <td>data-sortable</td> |
|
|
|
1427 <td>If "1" or "true" specifies if the column can be sorted, |
|
|
|
1428 default: "true".</td> |
|
|
|
1429 </tr> |
|
|
|
1430 </tbody> |
|
|
|
1431 </table> |
|
|
|
1432 |
|
|
|
1433 |
|
|
|
1434 <h3>Parsing</h3> |
|
|
|
1435 |
|
|
|
1436 <p> |
|
|
|
1437 By default only parsing for the types: date, float, int and string are |
|
|
|
1438 supported, but other types can be easily added as a function with the name: |
|
|
|
1439 datatable_parse_<typename>(). The parse functions parse the data-value |
|
|
|
1440 attribute when set or else the cell content (in order). Because of this |
|
|
|
1441 behaviour you can set the actual values as the data-value attribute and use |
|
|
|
1442 the cell content for display. This is useful to display and properly sort |
|
|
|
1443 locale-aware currency, datetimes etc. |
|
|
|
1444 </p> |
|
|
|
1445 |
|
|
|
1446 |
|
|
|
1447 <h3>Filtering</h3> |
|
|
|
1448 |
|
|
|
1449 <p> |
|
|
|
1450 Filtering will be done case-insensitively on the cell content and when set also |
|
|
|
1451 on the data-value attribute. The filter string is split up as tokens separated |
|
|
|
1452 by space. Each token must match atleast once per row to display it. |
|
|
|
1453 </p> |
|
|
|
1454 |
|
|
|
1455 |
|
|
|
1456 <h3>Sorting</h3> |
|
|
|
1457 |
|
|
|
1458 <p> |
|
|
|
1459 Sorting is done on the parsed values by default with the function: |
|
|
|
1460 datatable_sort_default(). To change this you can set a customname string on |
|
|
|
1461 the data-sort attribute on the column which translates to the function: |
|
|
|
1462 datatable_sort_<customname>(). |
|
|
|
1463 </p> |
|
|
|
1464 |
|
|
|
1465 <p> |
|
|
|
1466 In some applications locale values are used, like for currency, decimal numbers |
|
|
|
1467 datetimes. Some people also like to use icons or extended HTML elements inside |
|
|
|
1468 the cell. Because jsdatatable sorts on the parsed value (see section PARSING) |
|
|
|
1469 it is possible to sort on the data-value attribute values and use the cell |
|
|
|
1470 content for display. |
|
|
|
1471 </p> |
|
|
|
1472 |
|
|
|
1473 <p>For example:</p> |
|
|
|
1474 |
|
|
|
1475 <p> |
|
|
|
1476 currency, decimal numbers: |
|
|
|
1477 use data-value attribute with floating-point number, set data-parse |
|
|
|
1478 column to "float". |
|
|
|
1479 date/datetimes: |
|
|
|
1480 use data-value attribute with UNIX timestamps (type int), set |
|
|
|
1481 data-parse on column to "int" or set the data-parse attribute on |
|
|
|
1482 column to "date" which is datatable_parse_date(), then make sure to |
|
|
|
1483 use Zulu times, like: "2016-01-01T01:02:03Z" or other |
|
|
|
1484 time strings that are parsable as the data-value attribute. |
|
|
|
1485 icons: |
|
|
|
1486 generally use data-value attribute with integer as weight value to sort |
|
|
|
1487 on, set data-parse column to "int". |
|
|
|
1488 </p> |
|
|
|
1489 |
|
|
|
1490 |
|
|
|
1491 <h3>Dynamically update data</h3> |
|
|
|
1492 <p> |
|
|
|
1493 To update data dynamically see example-ajax.html for an example how to do this. |
|
|
|
1494 </p> |
|
|
|
1495 |
|
|
|
1496 |
|
|
|
1497 <h3>Caveats</h3> |
|
|
|
1498 <ul> |
|
|
|
1499 <li>A date, integer, float or other values must be able to parse properly, when |
|
|
|
1500 the parse function returns NaN, null or undefined etc. the sorting behaviour |
|
|
|
1501 is also undefined. It is recommended to always set a zero value for each |
|
|
|
1502 type.</li> |
|
|
|
1503 <li><tfoot> is not supported in datatables in "lazy" mode.</li> |
|
|
|
1504 </ul> |
|
|
|
1505 |
|
|
|
1506 |
|
|
|
1507 <h2>Demo / example</h2> |
|
|
|
1508 |
|
|
|
1509 <noscript> |
|
|
|
1510 <p> |
|
|
|
1511 <strong>For the below example to work you need to have Javascript enabled.</strong> |
|
|
|
1512 </p> |
|
|
|
1513 </noscript> |
|
|
|
1514 |
|
|
|
1515 <p> |
|
|
|
1516 <a href="datatable-example.html">datatable-example.html</a> |
|
|
|
1517 </p> |
|
|
|
1518 |
|
|
|
1519 <link rel="stylesheet" type="text/css" href="datatable.css" /> |
|
|
|
1520 <style type="text/css"> |
|
|
|
1521 th { text-align: left; } |
|
|
|
1522 .a-r { text-align: right; } |
|
|
|
1523 .no-stock { background-color: #ffcccc !important; } |
|
|
|
1524 .r { background-color: #ffcccc !important; } |
|
|
|
1525 .g { background-color: #ccffcc !important; } |
|
|
|
1526 |
|
|
|
1527 /* @media (prefers-color-scheme: dark) { |
|
|
|
1528 .r { background-color: #700 !important; } |
|
|
|
1529 .g { background-color: #070 !important; } |
|
|
|
1530 }*/ |
|
|
|
1531 </style> |
|
|
|
1532 ]]></content> |
|
|
|
1533 </entry> |
|
|
|
1534 <entry> |
|
|
|
1535 <title type="text">Stagit-gopher: a static git page generator for gopher</title> |
|
|
|
1536 <link rel="alternate" type="text/html" href="https://www.codemadness.org/stagit-gopher.html" /> |
|
|
|
1537 <id>https://www.codemadness.org/stagit-gopher.html</id> |
|
|
|
1538 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
1539 <published>2017-08-04T00:00:00Z</published> |
|
|
|
1540 <author> |
|
|
|
1541 <name>hiltjo</name> |
|
|
|
1542 <uri>https://www.codemadness.org</uri> |
|
|
|
1543 </author> |
|
|
|
1544 <summary type="text">a static git page generator for gopher</summary> |
|
|
|
1545 <content type="html"><![CDATA[<h1>Stagit-gopher: a static git page generator for gopher</h1> |
|
|
|
1546 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
1547 <p> |
|
|
|
1548 stagit-gopher is a static page generator for Gopher. |
|
|
|
1549 It creates the pages as static <a href="http://git.r-36.net/geomyidae/">geomyidae</a> .gph files. |
|
|
|
1550 stagit-gopher is a modified version from the HTML version of stagit. |
|
|
|
1551 </p> |
|
|
|
1552 |
|
|
|
1553 <p> |
|
|
|
1554 <a href="/git/stagit-gopher/file/README.html">Read the README for more information about it</a>. |
|
|
|
1555 </p> |
|
|
|
1556 |
|
|
|
1557 <p> |
|
|
|
1558 I also run a gopherhole and stagit-gopher, you can see how it looks here: |
|
|
|
1559 <a href="gopher://codemadness.org/">gopher://codemadness.org/</a>. |
|
|
|
1560 </p> |
|
|
|
1561 |
|
|
|
1562 <p> |
|
|
|
1563 <a href="https://git.fifth.space/sacc/log.html">sacc</a> is a good Gopher client to view it. |
|
|
|
1564 </p> |
|
|
|
1565 |
|
|
|
1566 |
|
|
|
1567 <h2>Features</h2> |
|
|
|
1568 <ul> |
|
|
|
1569 <li>Log of all commits from HEAD.</li> |
|
|
|
1570 <li>Log and diffstat per commit.</li> |
|
|
|
1571 <li>Show file tree with line numbers.</li> |
|
|
|
1572 <li>Show references: local branches and tags.</li> |
|
|
|
1573 <li>Detect README and LICENSE file from HEAD and link it as a webpage.</li> |
|
|
|
1574 <li>Detect submodules (.gitmodules file) from HEAD and link it as a webpage.</li> |
|
|
|
1575 <li>Atom feed log (atom.xml).</li> |
|
|
|
1576 <li>Make index page for multiple repositories with stagit-gopher-index.</li> |
|
|
|
1577 <li>After generating the pages (relatively slow) serving the files is very fast, |
|
|
|
1578 simple and requires little resources (because the content is static), a |
|
|
|
1579 <a href="http://git.r-36.net/geomyidae/">geomyidae</a> Gopher server is required.</li> |
|
|
|
1580 <li>Security: all pages are static. No CGI or dynamic code is run for the interface. |
|
|
|
1581 Using it with a secure Gopher server such as |
|
|
|
1582 <a href="http://git.r-36.net/geomyidae/">geomyidae</a> it is privilege-dropped and chroot(2)'d.</li> |
|
|
|
1583 <li>Simple to setup: the content generation is clearly separated from serving it. This makes configuration as simple as copying a few directories |
|
|
|
1584 and scripts.</li> |
|
|
|
1585 <li>Usable with Gopher clients such as lynx and |
|
|
|
1586 <a href="https://git.fifth.space/sacc/log.html">sacc</a>. |
|
|
|
1587 </li> |
|
|
|
1588 </ul> |
|
|
|
1589 |
|
|
|
1590 |
|
|
|
1591 <h2>Cons</h2> |
|
|
|
1592 <ul> |
|
|
|
1593 <li>Not suitable for large repositories (2000+ commits), because diffstats are |
|
|
|
1594 an expensive operation, the cache (-c flag) is a workaround for this in |
|
|
|
1595 some cases.</li> |
|
|
|
1596 <li>Not suitable for large repositories with many files, because all files are |
|
|
|
1597 written for each execution of stagit. This is because stagit shows the lines |
|
|
|
1598 of textfiles and there is no "cache" for file metadata (this would add more |
|
|
|
1599 complexity to the code).</li> |
|
|
|
1600 <li>Not suitable for repositories with many branches, a quite linear history is |
|
|
|
1601 assumed (from HEAD).</li> |
|
|
|
1602 <li>Relatively slow to run the first time (about 3 seconds for sbase, |
|
|
|
1603 1500+ commits), incremental updates are faster.</li> |
|
|
|
1604 <li>Does not support some of the dynamic features cgit has (for HTTP), like: |
|
|
|
1605 <ul> |
|
|
|
1606 <li>Snapshot tarballs per commit.</li> |
|
|
|
1607 <li>File tree per commit.</li> |
|
|
|
1608 <li>History log of branches diverged from HEAD.</li> |
|
|
|
1609 <li>Stats (git shortlog -s).</li> |
|
|
|
1610 </ul> |
|
|
|
1611 </li> |
|
|
|
1612 </ul> |
|
|
|
1613 |
|
|
|
1614 <p>This is by design, just use git locally.</p> |
|
|
|
1615 |
|
|
|
1616 |
|
|
|
1617 <h2>Clone</h2> |
|
|
|
1618 <pre><code>git clone git://<a href="//git.codemadness.org/stagit-gopher/">git.codemadness.org/stagit-gopher</a></code></pre> |
|
|
|
1619 |
|
|
|
1620 |
|
|
|
1621 <h2>Download releases</h2> |
|
|
|
1622 <p>Releases are available at: |
|
|
|
1623 |
|
|
|
1624 <a href="/releases/stagit-gopher/">https://codemadness.org/releases/stagit-gopher/</a> |
|
|
|
1625 and |
|
|
|
1626 <a href="https://dl.2f30.org/releases/">https://dl.2f30.org/releases/</a>stagit-gopher-*.tar.gz</p> |
|
|
|
1627 ]]></content> |
|
|
|
1628 </entry> |
|
|
|
1629 <entry> |
|
|
|
1630 <title type="text">Saait: a boring HTML page generator</title> |
|
|
|
1631 <link rel="alternate" type="text/html" href="https://www.codemadness.org/saait.html" /> |
|
|
|
1632 <id>https://www.codemadness.org/saait.html</id> |
|
|
|
1633 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
1634 <published>2017-06-10T00:00:00Z</published> |
|
|
|
1635 <author> |
|
|
|
1636 <name>hiltjo</name> |
|
|
|
1637 <uri>https://www.codemadness.org</uri> |
|
|
|
1638 </author> |
|
|
|
1639 <summary type="text">Saait: a boring HTML page generator</summary> |
|
|
|
1640 <content type="html"><![CDATA[<h1>Saait: a boring HTML page generator</h1> |
|
|
|
1641 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
1642 <p>Saait is the most boring static HTML page generator.</p> |
|
|
|
1643 |
|
|
|
1644 <p>Meaning of saai (dutch): boring. Pronunciation: site</p> |
|
|
|
1645 |
|
|
|
1646 <p><a href="/git/saait/file/README.html">Read the README for more information about it</a>.</p> |
|
|
|
1647 |
|
|
|
1648 <p> |
|
|
|
1649 I used to use <a href="/git/static-site-scripts/files.html">shellscripts</a> to generate the static pages, |
|
|
|
1650 but realised I wanted a small program that works on each platform consistently. |
|
|
|
1651 There are many incompatibilities or unimplemented features in base tools across different platforms: Linux, UNIX, Windows. |
|
|
|
1652 </p> |
|
|
|
1653 |
|
|
|
1654 <p>This site is created using saait.</p> |
|
|
|
1655 |
|
|
|
1656 |
|
|
|
1657 <h2>Features</h2> |
|
|
|
1658 <ul> |
|
|
|
1659 <li>Single small binary that handles all the things. At run-time no dependency on other tools.</li> |
|
|
|
1660 <li>Few lines of code (about 575 lines of C) and no dependencies except: a C compiler and libc.</li> |
|
|
|
1661 <li>Works on most platforms: tested on Linux, *BSD, Windows.</li> |
|
|
|
1662 <li>Simple template syntax.</li> |
|
|
|
1663 <li>Uses HTML output by default, but can easily be modified to generate any textual content, like gopher pages, wiki pages or other kinds of documents.</li> |
|
|
|
1664 <li>Out-of-the-box supports: creating an index page of all pages, Atom feed, twtxt.txt feed, sitemap.xml and urllist.txt.</li> |
|
|
|
1665 </ul> |
|
|
|
1666 |
|
|
|
1667 |
|
|
|
1668 <h2>Cons</h2> |
|
|
|
1669 <ul> |
|
|
|
1670 <li>Simple template syntax, but very basic. Requires C knowledge to extend it if needed.</li> |
|
|
|
1671 <li>Only basic (no nested) template blocks supported.</li> |
|
|
|
1672 </ul> |
|
|
|
1673 |
|
|
|
1674 |
|
|
|
1675 <h2>Clone</h2> |
|
|
|
1676 <pre><code>git clone git://<a href="//git.codemadness.org/saait/">git.codemadness.org/saait</a></code></pre> |
|
|
|
1677 |
|
|
|
1678 |
|
|
|
1679 <h2>Download releases</h2> |
|
|
|
1680 <p> |
|
|
|
1681 Releases are available at: |
|
|
|
1682 <a href="/releases/saait/">https://codemadness.org/releases/saait/</a>. |
|
|
|
1683 </p> |
|
|
|
1684 |
|
|
|
1685 |
|
|
|
1686 <h2>Documentation / man page</h2> |
|
|
|
1687 <p> |
|
|
|
1688 Below is the saait(1) man page, which includes usage examples. |
|
|
|
1689 </p> |
|
|
|
1690 |
|
|
|
1691 <pre><code>SAAIT(1) General Commands Manual SAAIT(1) |
|
|
|
1692 |
|
|
|
1693 NAME |
|
|
|
1694 saait the most boring static page generator |
|
|
|
1695 |
|
|
|
1696 SYNOPSIS |
|
|
|
1697 saait [-c configfile] [-o outputdir] [-t templatesdir] pages... |
|
|
|
1698 |
|
|
|
1699 DESCRIPTION |
|
|
|
1700 saait writes HTML pages to the output directory. |
|
|
|
1701 |
|
|
|
1702 The arguments pages are page config files, which are processed in the |
|
|
|
1703 given order. |
|
|
|
1704 |
|
|
|
1705 The options are as follows: |
|
|
|
1706 |
|
|
|
1707 -c configfile |
|
|
|
1708 The global configuration file, the default is "config.cfg". Each |
|
|
|
1709 page configuration file inherits variables from this file. These |
|
|
|
1710 variables can be overwritten per page. |
|
|
|
1711 |
|
|
|
1712 -o outputdir |
|
|
|
1713 The output directory, the default is "output". |
|
|
|
1714 |
|
|
|
1715 -t templatesdir |
|
|
|
1716 The templates directory, the default is "templates". |
|
|
|
1717 |
|
|
|
1718 DIRECTORY AND FILE STRUCTURE |
|
|
|
1719 A recommended directory structure for pages, although the names can be |
|
|
|
1720 anything: |
|
|
|
1721 pages/001-page.cfg |
|
|
|
1722 pages/001-page.html |
|
|
|
1723 pages/002-page.cfg |
|
|
|
1724 pages/002-page.html |
|
|
|
1725 |
|
|
|
1726 The directory and file structure for templates must be: |
|
|
|
1727 templates/<templatename>/header.ext |
|
|
|
1728 templates/<templatename>/item.ext |
|
|
|
1729 templates/<templatename>/footer.ext |
|
|
|
1730 |
|
|
|
1731 The following filename prefixes are detected for template blocks and |
|
|
|
1732 processed in this order: |
|
|
|
1733 |
|
|
|
1734 "header." |
|
|
|
1735 Header block. |
|
|
|
1736 |
|
|
|
1737 "item." |
|
|
|
1738 Item block. |
|
|
|
1739 |
|
|
|
1740 "footer." |
|
|
|
1741 Footer block. |
|
|
|
1742 |
|
|
|
1743 The files are saved as output/<templatename>, for example |
|
|
|
1744 templates/atom.xml/* will become: output/atom.xml. If a template block |
|
|
|
1745 file does not exist then it is treated as if it was empty. |
|
|
|
1746 |
|
|
|
1747 Template directories starting with a dot (".") are ignored. |
|
|
|
1748 |
|
|
|
1749 The "page" templatename is special and will be used per page. |
|
|
|
1750 |
|
|
|
1751 CONFIG FILE |
|
|
|
1752 A config file has a simple key=value configuration syntax, for example: |
|
|
|
1753 |
|
|
|
1754 # this is a comment line. |
|
|
|
1755 filename = example.html |
|
|
|
1756 title = Example page |
|
|
|
1757 description = This is an example page |
|
|
|
1758 created = 2009-04-12 |
|
|
|
1759 updated = 2009-04-14 |
|
|
|
1760 |
|
|
|
1761 The following variable names are special with their respective defaults: |
|
|
|
1762 |
|
|
|
1763 contentfile |
|
|
|
1764 Path to the input content filename, by default this is the path |
|
|
|
1765 of the config file with the last extension replaced to ".html". |
|
|
|
1766 |
|
|
|
1767 filename |
|
|
|
1768 The filename or relative file path for the output file for this |
|
|
|
1769 page. By default the value is the basename of the contentfile. |
|
|
|
1770 The path of the written output file is the value of filename |
|
|
|
1771 appended to the outputdir path. |
|
|
|
1772 |
|
|
|
1773 A line starting with # is a comment and is ignored. |
|
|
|
1774 |
|
|
|
1775 TABs and spaces before and after a variable name are ignored. TABs and |
|
|
|
1776 spaces before a value are ignored. |
|
|
|
1777 |
|
|
|
1778 TEMPLATES |
|
|
|
1779 A template (block) is text. Variables are replaced with the values set |
|
|
|
1780 in the config files. |
|
|
|
1781 |
|
|
|
1782 The possible operators for variables are: |
|
|
|
1783 |
|
|
|
1784 $ Escapes a XML string, for example: < to the entity &lt;. |
|
|
|
1785 |
|
|
|
1786 # Literal raw string value. |
|
|
|
1787 |
|
|
|
1788 % Insert contents of file of the value of the variable. |
|
|
|
1789 |
|
|
|
1790 For example in a HTML item template: |
|
|
|
1791 |
|
|
|
1792 <article> |
|
|
|
1793 <header> |
|
|
|
1794 <h1><a href="">${title}</a></h1> |
|
|
|
1795 <p> |
|
|
|
1796 <strong>Last modification on </strong> |
|
|
|
1797 <time datetime="${updated}">${updated}</time> |
|
|
|
1798 </p> |
|
|
|
1799 </header> |
|
|
|
1800 %{contentfile} |
|
|
|
1801 </article> |
|
|
|
1802 |
|
|
|
1803 EXIT STATUS |
|
|
|
1804 The saait utility exits 0 on success, and >0 if an error occurs. |
|
|
|
1805 |
|
|
|
1806 EXAMPLES |
|
|
|
1807 A basic usage example: |
|
|
|
1808 |
|
|
|
1809 1. Create a directory for a new site: |
|
|
|
1810 |
|
|
|
1811 mkdir newsite |
|
|
|
1812 |
|
|
|
1813 2. Copy the example pages, templates, global config file and example |
|
|
|
1814 stylesheets to a directory: |
|
|
|
1815 |
|
|
|
1816 cp -r pages templates config.cfg style.css print.css newsite/ |
|
|
|
1817 |
|
|
|
1818 3. Change the current directory to the created directory. |
|
|
|
1819 |
|
|
|
1820 cd newsite/ |
|
|
|
1821 |
|
|
|
1822 4. Change the values in the global config.cfg file. |
|
|
|
1823 |
|
|
|
1824 5. If you want to modify parts of the header, like the navigation menu |
|
|
|
1825 items, you can change the following two template files: |
|
|
|
1826 templates/page/header.html |
|
|
|
1827 templates/index.html/header.html |
|
|
|
1828 |
|
|
|
1829 6. Create any new pages in the pages directory. For each config file |
|
|
|
1830 there has to be a corresponding HTML file. By default this HTML |
|
|
|
1831 file has the path of the config file, but with the last extension |
|
|
|
1832 (".cfg" in this case) replaced to ".html". |
|
|
|
1833 |
|
|
|
1834 7. Create an output directory: |
|
|
|
1835 |
|
|
|
1836 mkdir -p output |
|
|
|
1837 |
|
|
|
1838 8. After any modifications the following commands can be used to |
|
|
|
1839 generate the output and process the pages in descending order: |
|
|
|
1840 |
|
|
|
1841 find pages -type f -name '*.cfg' -print0 | sort -zr | xargs -0 saait |
|
|
|
1842 |
|
|
|
1843 9. Copy the modified stylesheets to the output directory also: |
|
|
|
1844 |
|
|
|
1845 cp style.css print.css output/ |
|
|
|
1846 |
|
|
|
1847 10. Open output/index.html locally in your webbrowser to review the |
|
|
|
1848 changes. |
|
|
|
1849 |
|
|
|
1850 11. To synchronize files, you can securely transfer them via SSH using |
|
|
|
1851 rsync: |
|
|
|
1852 |
|
|
|
1853 rsync -av output/ user@somehost:/var/www/htdocs/ |
|
|
|
1854 |
|
|
|
1855 TRIVIA |
|
|
|
1856 The most boring static page generator. |
|
|
|
1857 |
|
|
|
1858 Meaning of saai (dutch): boring, pronunciation of saait: site |
|
|
|
1859 |
|
|
|
1860 SEE ALSO |
|
|
|
1861 find(1), sort(1), xargs(1) |
|
|
|
1862 |
|
|
|
1863 AUTHORS |
|
|
|
1864 Hiltjo Posthuma <hiltjo@codemadness.org></code></pre> |
|
|
|
1865 ]]></content> |
|
|
|
1866 </entry> |
|
|
|
1867 <entry> |
|
|
|
1868 <title type="text">Stagit: a static git page generator</title> |
|
|
|
1869 <link rel="alternate" type="text/html" href="https://www.codemadness.org/stagit.html" /> |
|
|
|
1870 <id>https://www.codemadness.org/stagit.html</id> |
|
|
|
1871 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
1872 <published>2017-05-10T00:00:00Z</published> |
|
|
|
1873 <author> |
|
|
|
1874 <name>hiltjo</name> |
|
|
|
1875 <uri>https://www.codemadness.org</uri> |
|
|
|
1876 </author> |
|
|
|
1877 <summary type="text">a static git page generator</summary> |
|
|
|
1878 <content type="html"><![CDATA[<h1>Stagit: a static git page generator</h1> |
|
|
|
1879 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
1880 <p> |
|
|
|
1881 stagit is a static page generator for git. |
|
|
|
1882 </p> |
|
|
|
1883 |
|
|
|
1884 <p> |
|
|
|
1885 <a href="/git/stagit/file/README.html">Read the README for more information about it</a>. |
|
|
|
1886 </p> |
|
|
|
1887 |
|
|
|
1888 <p> |
|
|
|
1889 My git repository uses stagit, you can see how it looks here: |
|
|
|
1890 <a href="/git/">https://codemadness.org/git/</a>. |
|
|
|
1891 </p> |
|
|
|
1892 |
|
|
|
1893 |
|
|
|
1894 <h2>Features</h2> |
|
|
|
1895 <ul> |
|
|
|
1896 <li>Log of all commits from HEAD.</li> |
|
|
|
1897 <li>Log and diffstat per commit.</li> |
|
|
|
1898 <li>Show file tree with linkable line numbers.</li> |
|
|
|
1899 <li>Show references: local branches and tags.</li> |
|
|
|
1900 <li>Detect README and LICENSE file from HEAD and link it as a webpage.</li> |
|
|
|
1901 <li>Detect submodules (.gitmodules file) from HEAD and link it as a webpage.</li> |
|
|
|
1902 <li>Atom feed log (atom.xml).</li> |
|
|
|
1903 <li>Make index page for multiple repositories with stagit-index.</li> |
|
|
|
1904 <li>After generating the pages (relatively slow) serving the files is very fast, |
|
|
|
1905 simple and requires little resources (because the content is static), only |
|
|
|
1906 a HTTP file server is required.</li> |
|
|
|
1907 <li>Security: all pages are static. No CGI or dynamic code is run for the |
|
|
|
1908 interface. Using it with a secure httpd such as OpenBSD httpd it is |
|
|
|
1909 privilege-separated, chroot(2)'d and pledge(2)'d.</li> |
|
|
|
1910 <li>Simple to setup: the content generation is clearly separated from serving |
|
|
|
1911 it. This makes configuration as simple as copying a few directories and |
|
|
|
1912 scripts.</li> |
|
|
|
1913 <li>Usable with text-browsers such as dillo, links, lynx and w3m.</li> |
|
|
|
1914 </ul> |
|
|
|
1915 |
|
|
|
1916 |
|
|
|
1917 <h2>Cons</h2> |
|
|
|
1918 <ul> |
|
|
|
1919 <li>Not suitable for large repositories (2000+ commits), because diffstats are |
|
|
|
1920 an expensive operation, the cache (-c flag) is a workaround for this in |
|
|
|
1921 some cases.</li> |
|
|
|
1922 <li>Not suitable for large repositories with many files, because all files are |
|
|
|
1923 written for each execution of stagit. This is because stagit shows the lines |
|
|
|
1924 of textfiles and there is no "cache" for file metadata (this would add more |
|
|
|
1925 complexity to the code).</li> |
|
|
|
1926 <li>Not suitable for repositories with many branches, a quite linear history is |
|
|
|
1927 assumed (from HEAD).</li> |
|
|
|
1928 </ul> |
|
|
|
1929 |
|
|
|
1930 <p> |
|
|
|
1931 In these cases it is better to use <a href="https://git.zx2c4.com/cgit/">cgit</a> or |
|
|
|
1932 possibly change stagit to run as a CGI program. |
|
|
|
1933 </p> |
|
|
|
1934 |
|
|
|
1935 <ul> |
|
|
|
1936 <li>Relatively slow to run the first time (about 3 seconds for sbase, |
|
|
|
1937 1500+ commits), incremental updates are faster.</li> |
|
|
|
1938 <li>Does not support some of the dynamic features cgit has, like: |
|
|
|
1939 <ul> |
|
|
|
1940 <li>Snapshot tarballs per commit.</li> |
|
|
|
1941 <li>File tree per commit.</li> |
|
|
|
1942 <li>History log of branches diverged from HEAD.</li> |
|
|
|
1943 <li>Stats (git shortlog -s).</li> |
|
|
|
1944 </ul> |
|
|
|
1945 </li> |
|
|
|
1946 </ul> |
|
|
|
1947 |
|
|
|
1948 <p>This is by design, just use git locally.</p> |
|
|
|
1949 |
|
|
|
1950 |
|
|
|
1951 <h2>Clone</h2> |
|
|
|
1952 <pre><code>git clone git://<a href="//git.codemadness.org/stagit/">git.codemadness.org/stagit</a></code></pre> |
|
|
|
1953 |
|
|
|
1954 |
|
|
|
1955 <h2>Download releases</h2> |
|
|
|
1956 <p>Releases are available at: |
|
|
|
1957 |
|
|
|
1958 <a href="https://codemadness.org/releases/stagit/">https://codemadness.org/releases/stagit/</a> |
|
|
|
1959 and a mirror at |
|
|
|
1960 <a href="https://dl.2f30.org/releases/">https://dl.2f30.org/releases/</a>stagit-*.tar.gz</p> |
|
|
|
1961 ]]></content> |
|
|
|
1962 </entry> |
|
|
|
1963 <entry> |
|
|
|
1964 <title type="text">OpenBSD httpd, slowcgi and cgit</title> |
|
|
|
1965 <link rel="alternate" type="text/html" href="https://www.codemadness.org/openbsd-httpd-and-cgit.html" /> |
|
|
|
1966 <id>https://www.codemadness.org/openbsd-httpd-and-cgit.html</id> |
|
|
|
1967 <updated>2015-07-05T00:00:00Z</updated> |
|
|
|
1968 <published>2015-07-05T00:00:00Z</published> |
|
|
|
1969 <author> |
|
|
|
1970 <name>hiltjo</name> |
|
|
|
1971 <uri>https://www.codemadness.org</uri> |
|
|
|
1972 </author> |
|
|
|
1973 <summary type="text">OpenBSD httpd, slowcgi and cgit</summary> |
|
|
|
1974 <content type="html"><![CDATA[<h1>OpenBSD httpd, slowcgi and cgit</h1> |
|
|
|
1975 <p><strong>Last modification on </strong> <time>2015-07-05</time></p> |
|
|
|
1976 <p> |
|
|
|
1977 This is a guide to get <a href="https://git.zx2c4.com/cgit/">cgit</a> working with the |
|
|
|
1978 relatively new <a href="https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/httpd.8">OpenBSD httpd(8)</a> and |
|
|
|
1979 <a href="https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/slowcgi.8">slowcgi(8)</a> in base. |
|
|
|
1980 OpenBSD httpd is very simple to setup, but nevertheless this guide might help someone out there. |
|
|
|
1981 </p> |
|
|
|
1982 |
|
|
|
1983 |
|
|
|
1984 <h2>Installation</h2> |
|
|
|
1985 |
|
|
|
1986 <p>Install the cgit package:</p> |
|
|
|
1987 <pre><code># pkg_add cgit</code></pre> |
|
|
|
1988 |
|
|
|
1989 <p>or build it from ports:</p> |
|
|
|
1990 <pre><code># cd /usr/ports/www/cgit && make && make install</code></pre> |
|
|
|
1991 |
|
|
|
1992 |
|
|
|
1993 <h2>Configuration</h2> |
|
|
|
1994 |
|
|
|
1995 |
|
|
|
1996 <h3>httpd</h3> |
|
|
|
1997 <p>An example of <a href="https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/httpd.conf.5">httpd.conf(5)</a>: |
|
|
|
1998 <a href="downloads/openbsd-httpd/httpd.conf">httpd.conf</a>.</p> |
|
|
|
1999 |
|
|
|
2000 |
|
|
|
2001 <h3>slowcgi</h3> |
|
|
|
2002 <p>By default the slowcgi UNIX domain socket is located at: /var/www/run/slowcgi.sock. |
|
|
|
2003 For this example we use the defaults.</p> |
|
|
|
2004 |
|
|
|
2005 |
|
|
|
2006 <h3>cgit</h3> |
|
|
|
2007 <p>The cgit binary should be located at: /var/www/cgi-bin/cgit.cgi (default).</p> |
|
|
|
2008 |
|
|
|
2009 <p>cgit uses the $CGIT_CONFIG environment variable to locate it's config. |
|
|
|
2010 By default on OpenBSD this is set to /conf/cgitrc (chroot), which is /var/www/conf/cgitrc. |
|
|
|
2011 An example of cgitrc is here: <a href="downloads/openbsd-httpd/cgitrc">cgitrc</a>.</p> |
|
|
|
2012 |
|
|
|
2013 <p>In this example the cgit cache directory is set to /cgit/cache (chroot), which is /var/www/cgit/cache. |
|
|
|
2014 Make sure to give this path read and write permissions for cgit (www:daemon).</p> |
|
|
|
2015 |
|
|
|
2016 <p>In the example the repository path (scan-path) is set to /htdocs/src (chroot), which is /var/www/htdocs/src.</p> |
|
|
|
2017 |
|
|
|
2018 <p>The footer file is set to /conf/cgit.footer. Make sure this file exists or you will get warnings:</p> |
|
|
|
2019 <pre><code># >/var/www/conf/cgit.footer</code></pre> |
|
|
|
2020 |
|
|
|
2021 <p>Make sure cgit.css (stylesheet) and cgit.png (logo) are accessible, by default: /var/www/cgit/cgit.{css,png} |
|
|
|
2022 (location can be changed in httpd.conf).</p> |
|
|
|
2023 |
|
|
|
2024 <p>To support .tar.gz snapshots a static gzip binary is required in the chroot /bin directory:</p> |
|
|
|
2025 |
|
|
|
2026 <pre><code>cd /usr/src/usr.bin/compress |
|
|
|
2027 make clean && make LDFLAGS="-static -pie" |
|
|
|
2028 cp obj/compress /var/www/bin/gzip</code></pre> |
|
|
|
2029 |
|
|
|
2030 |
|
|
|
2031 <h2>Running the services</h2> |
|
|
|
2032 |
|
|
|
2033 <p>Enable the httpd and slowcgi services to automatically start them at boot:</p> |
|
|
|
2034 |
|
|
|
2035 <pre><code># rcctl enable httpd slowcgi</code></pre> |
|
|
|
2036 |
|
|
|
2037 <p>Start the services:</p> |
|
|
|
2038 |
|
|
|
2039 <pre><code># rcctl start httpd slowcgi</code></pre> |
|
|
|
2040 ]]></content> |
|
|
|
2041 </entry> |
|
|
|
2042 <entry> |
|
|
|
2043 <title type="text">twitch: application to watch Twitch streams</title> |
|
|
|
2044 <link rel="alternate" type="text/html" href="https://www.codemadness.org/twitch-interface.html" /> |
|
|
|
2045 <id>https://www.codemadness.org/twitch-interface.html</id> |
|
|
|
2046 <updated>2020-05-06T00:00:00Z</updated> |
|
|
|
2047 <published>2014-11-23T00:00:00Z</published> |
|
|
|
2048 <author> |
|
|
|
2049 <name>hiltjo</name> |
|
|
|
2050 <uri>https://www.codemadness.org</uri> |
|
|
|
2051 </author> |
|
|
|
2052 <summary type="text">twitch: application to watch Twitch streams</summary> |
|
|
|
2053 <content type="html"><![CDATA[<h1>twitch: application to watch Twitch streams</h1> |
|
|
|
2054 <p><strong>Last modification on </strong> <time>2020-05-06</time></p> |
|
|
|
2055 <p> |
|
|
|
2056 <strong>Update: as of 2020-05-06:</strong> I stopped maintaining it. |
|
|
|
2057 Twitch now requires OAUTH and 2-factor authentication. It requires me to expose |
|
|
|
2058 personal information such as my phone number. |
|
|
|
2059 </p> |
|
|
|
2060 |
|
|
|
2061 <p> |
|
|
|
2062 <strong>Update: as of ~2020-01-03:</strong> I rewrote this application from Golang to C. |
|
|
|
2063 The Twitch Kraken API used by the Golang version was deprecated. |
|
|
|
2064 It is now rewritten to use the <a href="https://dev.twitch.tv/docs/api/reference">Helix API</a>. |
|
|
|
2065 It also has a <a href="gopher://codemadness.org/1/twitch.cgi">Gopher version</a> now. |
|
|
|
2066 You can still find the old code here: |
|
|
|
2067 <a href="https://git.codemadness.org/twitch-go/file/README.html">twitch-go</a>. |
|
|
|
2068 </p> |
|
|
|
2069 |
|
|
|
2070 <p> |
|
|
|
2071 This script allows to view streams in your own video player like |
|
|
|
2072 <a href="https://mpv.io/">mpv</a>, so the bloated Twitch interface is not needed. |
|
|
|
2073 It uses the Twitch Helix API and is written in C. |
|
|
|
2074 </p> |
|
|
|
2075 |
|
|
|
2076 |
|
|
|
2077 <h2 id="features">Features</h2> |
|
|
|
2078 <ul> |
|
|
|
2079 <li>No Javascript, cookies, CSS optional.</li> |
|
|
|
2080 <li>Works well in all browsers, including text-based ones.</li> |
|
|
|
2081 <li>Has a HTTP CGI and Gopher CGI version.</li> |
|
|
|
2082 <li>Atom feed for VODs.</li> |
|
|
|
2083 </ul> |
|
|
|
2084 |
|
|
|
2085 |
|
|
|
2086 <h2>Clone</h2> |
|
|
|
2087 <pre><code>git clone git://<a href="//git.codemadness.org/frontends/">git.codemadness.org/frontends</a></code></pre> |
|
|
|
2088 |
|
|
|
2089 |
|
|
|
2090 <h2>View</h2> |
|
|
|
2091 <ul> |
|
|
|
2092 <li><s><a href="https://twitch.codemadness.org/">You can view the HTTP CGI version here</a>.</s></li> |
|
|
|
2093 <li><s><a href="gopher://codemadness.org/1/twitch.cgi">You can view the Gopher CGI version here</a>.</s></li> |
|
|
|
2094 </ul> |
|
|
|
2095 ]]></content> |
|
|
|
2096 </entry> |
|
|
|
2097 <entry> |
|
|
|
2098 <title type="text">Userscript: focus input field</title> |
|
|
|
2099 <link rel="alternate" type="text/html" href="https://www.codemadness.org/userscript-focus-input-field.html" /> |
|
|
|
2100 <id>https://www.codemadness.org/userscript-focus-input-field.html</id> |
|
|
|
2101 <updated>2014-03-02T00:00:00Z</updated> |
|
|
|
2102 <published>2014-03-02T00:00:00Z</published> |
|
|
|
2103 <author> |
|
|
|
2104 <name>hiltjo</name> |
|
|
|
2105 <uri>https://www.codemadness.org</uri> |
|
|
|
2106 </author> |
|
|
|
2107 <summary type="text">Userscript to focus the first input field on a page with a hotkey</summary> |
|
|
|
2108 <content type="html"><![CDATA[<h1>Userscript: focus input field</h1> |
|
|
|
2109 <p><strong>Last modification on </strong> <time>2014-03-02</time></p> |
|
|
|
2110 <p> |
|
|
|
2111 This is an userscript I wrote a while ago which allows to focus the first input field on a page with ctrl+space. |
|
|
|
2112 This is useful if a site doesn't specify the autofocus attribute for an input field and you don't want to switch to it using the mouse. |
|
|
|
2113 </p> |
|
|
|
2114 |
|
|
|
2115 |
|
|
|
2116 <h2>Download</h2> |
|
|
|
2117 <p><a href="downloads/input_focus.user.js">Download userscript input_focus.user.js</a></p> |
|
|
|
2118 ]]></content> |
|
|
|
2119 </entry> |
|
|
|
2120 <entry> |
|
|
|
2121 <title type="text">Userscript: Youtube circumvent age verification</title> |
|
|
|
2122 <link rel="alternate" type="text/html" href="https://www.codemadness.org/userscript-youtube-circumvent-age-verification.html" /> |
|
|
|
2123 <id>https://www.codemadness.org/userscript-youtube-circumvent-age-verification.html</id> |
|
|
|
2124 <updated>2013-02-21T00:00:00Z</updated> |
|
|
|
2125 <published>2013-02-21T00:00:00Z</published> |
|
|
|
2126 <author> |
|
|
|
2127 <name>hiltjo</name> |
|
|
|
2128 <uri>https://www.codemadness.org</uri> |
|
|
|
2129 </author> |
|
|
|
2130 <summary type="text">Userscript to circumvent Youtube age verification and redirect to the video</summary> |
|
|
|
2131 <content type="html"><![CDATA[<h1>Userscript: Youtube circumvent age verification</h1> |
|
|
|
2132 <p><strong>Last modification on </strong> <time>2013-02-21</time></p> |
|
|
|
2133 <p> |
|
|
|
2134 This is an userscript I wrote a while ago which circumvents requiring to login with an account on Youtube if a video requires age verification. |
|
|
|
2135 </p> |
|
|
|
2136 |
|
|
|
2137 |
|
|
|
2138 <h2>Download</h2> |
|
|
|
2139 <p><a href="downloads/youtube_circumvent_sign_in.user.js">Download userscript Youtube_circumvent_sign_in.user.js</a></p> |
|
|
|
2140 ]]></content> |
|
|
|
2141 </entry> |
|
|
|
2142 <entry> |
|
|
|
2143 <title type="text">Userscript: block stupid fonts</title> |
|
|
|
2144 <link rel="alternate" type="text/html" href="https://www.codemadness.org/userscript-block-stupid-fonts.html" /> |
|
|
|
2145 <id>https://www.codemadness.org/userscript-block-stupid-fonts.html</id> |
|
|
|
2146 <updated>2020-03-10T00:00:00Z</updated> |
|
|
|
2147 <published>2012-10-21T00:00:00Z</published> |
|
|
|
2148 <author> |
|
|
|
2149 <name>hiltjo</name> |
|
|
|
2150 <uri>https://www.codemadness.org</uri> |
|
|
|
2151 </author> |
|
|
|
2152 <summary type="text">Userscript to whitelist your favorite fonts and block the rest</summary> |
|
|
|
2153 <content type="html"><![CDATA[<h1>Userscript: block stupid fonts</h1> |
|
|
|
2154 <p><strong>Last modification on </strong> <time>2020-03-10</time></p> |
|
|
|
2155 <p> |
|
|
|
2156 This is an userscript I wrote a while ago which white-lists fonts I like and blocks the rest. |
|
|
|
2157 The reason I made this is because I don't like the inconsistency of custom fonts used on a lot of websites. |
|
|
|
2158 </p> |
|
|
|
2159 |
|
|
|
2160 |
|
|
|
2161 <h2>Download</h2> |
|
|
|
2162 |
|
|
|
2163 <p><a href="downloads/block_stupid_fonts_v1.2.user.js">Download userscript Block_stupid_fonts_v1.2.user.js</a></p> |
|
|
|
2164 |
|
|
|
2165 <p>Old version: <a href="downloads/block_stupid_fonts.user.js">Download userscript Block_stupid_fonts.user.js</a></p> |
|
|
|
2166 ]]></content> |
|
|
|
2167 </entry> |
|
|
|
2168 <entry> |
|
|
|
2169 <title type="text">Sfeed: simple RSS and Atom parser</title> |
|
|
|
2170 <link rel="alternate" type="text/html" href="https://www.codemadness.org/sfeed-simple-feed-parser.html" /> |
|
|
|
2171 <id>https://www.codemadness.org/sfeed-simple-feed-parser.html</id> |
|
|
|
2172 <updated>2020-06-28T00:00:00Z</updated> |
|
|
|
2173 <published>2011-04-01T00:00:00Z</published> |
|
|
|
2174 <author> |
|
|
|
2175 <name>hiltjo</name> |
|
|
|
2176 <uri>https://www.codemadness.org</uri> |
|
|
|
2177 </author> |
|
|
|
2178 <summary type="text">Sfeed is a simple RSS and Atom parser (and format programs to add reader functionality)</summary> |
|
|
|
2179 <content type="html"><![CDATA[<h1>Sfeed: simple RSS and Atom parser</h1> |
|
|
|
2180 <p><strong>Last modification on </strong> <time>2020-06-28</time></p> |
|
|
|
2181 <p>Sfeed is a RSS and Atom parser (and some format programs).</p> |
|
|
|
2182 |
|
|
|
2183 <p>It converts RSS or Atom feeds from XML to a TAB-separated file. There are |
|
|
|
2184 formatting programs included to convert this TAB-separated format to various |
|
|
|
2185 other formats. There are also some programs and scripts included to import and |
|
|
|
2186 export OPML and to fetch, filter, merge and order feed items.</p> |
|
|
|
2187 |
|
|
|
2188 <p>For the most (up-to-date) information see the |
|
|
|
2189 <a href="/git/sfeed/file/README.html">README</a> file.</p> |
|
|
|
2190 |
|
|
|
2191 |
|
|
|
2192 <h2>Clone</h2> |
|
|
|
2193 <pre><code>git clone git://<a href="//git.codemadness.org/sfeed/">git.codemadness.org/sfeed</a></code></pre> |
|
|
|
2194 |
|
|
|
2195 |
|
|
|
2196 <h2>Download releases</h2> |
|
|
|
2197 <p> |
|
|
|
2198 Releases are available at: |
|
|
|
2199 <a href="/releases/sfeed/">https://codemadness.org/releases/sfeed/</a>. |
|
|
|
2200 </p> |
|
|
|
2201 |
|
|
|
2202 <p>NOTE: releases for sfeed can be seen as periodic snapshots. I recommend to |
|
|
|
2203 use the git version.</p> |
|
|
|
2204 |
|
|
|
2205 |
|
|
|
2206 <h2>Build and install</h2> |
|
|
|
2207 |
|
|
|
2208 <pre><code>$ make |
|
|
|
2209 # make install</code></pre> |
|
|
|
2210 |
|
|
|
2211 <h2>Screenshot and examples</h2> |
|
|
|
2212 <p><a href="downloads/screenshots/sfeed-screenshot.png"><img src="downloads/screenshots/sfeed-thumb.png" alt="Screenshot of sfeed piped to sfeed_plain using dmenu in vertical-list mode" width="400" height="232" loading="lazy" /></a></p> |
|
|
|
2213 |
|
|
|
2214 <p>The above screenshot uses the sfeed_plain format program with |
|
|
|
2215 <a href="https://tools.suckless.org/dmenu/">dmenu</a>. |
|
|
|
2216 This program outputs the feed items in a compact way per line as plain-text to |
|
|
|
2217 stdout. The dmenu program reads these lines from stdin and displays them as a |
|
|
|
2218 X11 list menu. When an item is selected in dmenu it prints this item to stdout. |
|
|
|
2219 A simple written script can then filter for the url in this output and do some |
|
|
|
2220 action, like opening it in some browser or open a podcast in your music player. |
|
|
|
2221 </p> |
|
|
|
2222 |
|
|
|
2223 <p>For example:</p> |
|
|
|
2224 <pre><code>#!/bin/sh |
|
|
|
2225 url=$(sfeed_plain "$HOME/.sfeed/feeds/"* | dmenu -l 35 -i | \ |
|
|
|
2226 sed -n 's@^.* \([a-zA-Z]*://\)\(.*\)$@\1\2@p') |
|
|
|
2227 test -n "${url}" && $BROWSER "${url}"</code></pre> |
|
|
|
2228 |
|
|
|
2229 <p>However this is just one way to format and interact with feed items. |
|
|
|
2230 See also the README for other practical examples.</p> |
|
|
|
2231 |
|
|
|
2232 <p>Below are some examples of output that are supported by the included format |
|
|
|
2233 programs:</p> |
|
|
|
2234 |
|
|
|
2235 <ul> |
|
|
|
2236 <li><a href="downloads/sfeed/plain/feeds.txt">plain text (UTF-8)</a></li> |
|
|
|
2237 <li><a href="downloads/sfeed/html/feeds.html">HTML (CSS)</a></li> |
|
|
|
2238 <li><a href="downloads/sfeed/frames/index.html">HTML frames</a></li> |
|
|
|
2239 <li>gopher</li> |
|
|
|
2240 <li><a href="downloads/sfeed/mbox/feeds.mbox">mbox</a></li> |
|
|
|
2241 <li><a href="downloads/sfeed/twtxt/twtxt.txt">twtxt</a></li> |
|
|
|
2242 <li><a href="downloads/sfeed/atom/feeds.xml">atom</a></li> |
|
|
|
2243 </ul> |
|
|
|
2244 |
|
|
|
2245 <p> |
|
|
|
2246 For a separate curses UI front-end, see also <a href="sfeed_curses-ui.html">sfeed_curses</a>. |
|
|
|
2247 </p> |
|
|
|
2248 ]]></content> |
|
|
|
2249 </entry> |
|
|
|
2250 <entry> |
|
|
|
2251 <title type="text">Vim theme: relaxed</title> |
|
|
|
2252 <link rel="alternate" type="text/html" href="https://www.codemadness.org/vim-theme-relaxed.html" /> |
|
|
|
2253 <id>https://www.codemadness.org/vim-theme-relaxed.html</id> |
|
|
|
2254 <updated>2011-01-07T00:00:00Z</updated> |
|
|
|
2255 <published>2011-01-07T00:00:00Z</published> |
|
|
|
2256 <author> |
|
|
|
2257 <name>hiltjo</name> |
|
|
|
2258 <uri>https://www.codemadness.org</uri> |
|
|
|
2259 </author> |
|
|
|
2260 <summary type="text">a dark VIM theme I made and use on a daily basis</summary> |
|
|
|
2261 <content type="html"><![CDATA[<h1>Vim theme: relaxed</h1> |
|
|
|
2262 <p><strong>Last modification on </strong> <time>2011-01-07</time></p> |
|
|
|
2263 <p>This is a dark theme I made for <a href="http://www.vim.org/">vim</a>. |
|
|
|
2264 This is a theme I personally used for quite a while now and over time tweaked to my liking. |
|
|
|
2265 It is made for gvim, but also works for 16-colour terminals (with small visual differences). |
|
|
|
2266 The relaxed.vim file also has my .Xdefaults file colours listed at the top for 16+-colour |
|
|
|
2267 terminals on X11.</p> |
|
|
|
2268 |
|
|
|
2269 <p>It is inspired by the "desert" theme available at <a href="https://www.vim.org/scripts/script.php?script_id=105">https://www.vim.org/scripts/script.php?script_id=105</a>, |
|
|
|
2270 although I removed the cursive and bold styles and changed some colours I didn't like.</p> |
|
|
|
2271 |
|
|
|
2272 |
|
|
|
2273 <h2>Download</h2> |
|
|
|
2274 |
|
|
|
2275 <p><a href="downloads/themes/vim/relaxed.vim">relaxed.vim</a></p> |
|
|
|
2276 |
|
|
|
2277 |
|
|
|
2278 <h2>Screenshot</h2> |
|
|
|
2279 |
|
|
|
2280 <p><a href="downloads/themes/vim/vim_relaxed_theme.png"><img src="downloads/themes/vim/vim_relaxed_theme_thumb.png" alt="Screenshot of VIM theme relaxed on the left is gvim (GUI), on the right is vim in urxvt (terminal)" width="480" height="300" loading="lazy" /></a></p> |
|
|
|
2281 ]]></content> |
|
|
|
2282 </entry> |
|
|
|
2283 <entry> |
|
|
|
2284 <title type="text">Seturgent: set urgency hints for X applications</title> |
|
|
|
2285 <link rel="alternate" type="text/html" href="https://www.codemadness.org/seturgent-set-urgency-hints-for-x-applications.html" /> |
|
|
|
2286 <id>https://www.codemadness.org/seturgent-set-urgency-hints-for-x-applications.html</id> |
|
|
|
2287 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
2288 <published>2010-10-31T00:00:00Z</published> |
|
|
|
2289 <author> |
|
|
|
2290 <name>hiltjo</name> |
|
|
|
2291 <uri>https://www.codemadness.org</uri> |
|
|
|
2292 </author> |
|
|
|
2293 <summary type="text">Seturgent is a small utility to set an application it's urgency hint</summary> |
|
|
|
2294 <content type="html"><![CDATA[<h1>Seturgent: set urgency hints for X applications</h1> |
|
|
|
2295 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
2296 <p> |
|
|
|
2297 Seturgent is a small utility to set an application it's urgency hint. |
|
|
|
2298 For most windowmanager's and panel applications this will highlight |
|
|
|
2299 the application and will allow special actions. |
|
|
|
2300 </p> |
|
|
|
2301 |
|
|
|
2302 |
|
|
|
2303 <h2>Clone</h2> |
|
|
|
2304 <pre><code>git clone git://<a href="//git.codemadness.org/seturgent/">git.codemadness.org/seturgent</a></code></pre> |
|
|
|
2305 |
|
|
|
2306 |
|
|
|
2307 <h2>Download releases</h2> |
|
|
|
2308 <p> |
|
|
|
2309 Releases are available at: |
|
|
|
2310 <a href="/releases/seturgent/">https://codemadness.org/releases/seturgent/</a>. |
|
|
|
2311 </p> |
|
|
|
2312 ]]></content> |
|
|
|
2313 </entry> |
|
|
|
2314 <entry> |
|
|
|
2315 <title type="text">GTK2 theme: gtk-murrine-rape</title> |
|
|
|
2316 <link rel="alternate" type="text/html" href="https://www.codemadness.org/gtk2-theme-gtk-murrine-rape.html" /> |
|
|
|
2317 <id>https://www.codemadness.org/gtk2-theme-gtk-murrine-rape.html</id> |
|
|
|
2318 <updated>2010-10-31T00:00:00Z</updated> |
|
|
|
2319 <published>2010-10-31T00:00:00Z</published> |
|
|
|
2320 <author> |
|
|
|
2321 <name>hiltjo</name> |
|
|
|
2322 <uri>https://www.codemadness.org</uri> |
|
|
|
2323 </author> |
|
|
|
2324 <summary type="text">A plain consistent GTK2 theme with no fluff (rounded borders, animations, etc)</summary> |
|
|
|
2325 <content type="html"><![CDATA[<h1>GTK2 theme: gtk-murrine-rape</h1> |
|
|
|
2326 <p><strong>Last modification on </strong> <time>2010-10-31</time></p> |
|
|
|
2327 <h2>Download</h2> |
|
|
|
2328 <p><a href="downloads/themes/gtk/murrine-rape/gtk-2.0/gtkrc">gtkrc</a></p> |
|
|
|
2329 |
|
|
|
2330 |
|
|
|
2331 <h2>Screenshot</h2> |
|
|
|
2332 <p><a href="downloads/themes/gtk/murrine-rape/gtk-murrine-rape.png"><img src="downloads/themes/gtk/murrine-rape/gtk-murrine-rape-thumb.png" alt="Screenshot of gtk engine murrine: murrine-rape theme" width="480" height="300" loading="lazy" /></a></p> |
|
|
|
2333 |
|
|
|
2334 |
|
|
|
2335 <h2>Features</h2> |
|
|
|
2336 <ul> |
|
|
|
2337 <li>Good contrast between UI elements and consistency (imho).</li> |
|
|
|
2338 <li>Plain colours; no bright colours and (almost) no gradients.</li> |
|
|
|
2339 <li>No rounded borders.</li> |
|
|
|
2340 <li>No animations (progressbar etc).</li> |
|
|
|
2341 <li>Uses the fast and easy customizable gtk-engine-murrine.</li> |
|
|
|
2342 </ul> |
|
|
|
2343 |
|
|
|
2344 |
|
|
|
2345 <h2>Dependency</h2> |
|
|
|
2346 <p>Depends on the git version of gtk-engine-murrine last I checked: |
|
|
|
2347 <a href="http://www.cimitan.com/murrine/">http://www.cimitan.com/murrine/</a> |
|
|
|
2348 (link broken 2017-08-04).</p> |
|
|
|
2349 ]]></content> |
|
|
|
2350 </entry> |
|
|
|
2351 <entry> |
|
|
|
2352 <title type="text">DWM-hiltjo: my windowmanager configuration</title> |
|
|
|
2353 <link rel="alternate" type="text/html" href="https://www.codemadness.org/dwm-hiltjo-my-windowmanager-configuration.html" /> |
|
|
|
2354 <id>https://www.codemadness.org/dwm-hiltjo-my-windowmanager-configuration.html</id> |
|
|
|
2355 <updated>2020-07-20T00:00:00Z</updated> |
|
|
|
2356 <published>2010-08-12T00:00:00Z</published> |
|
|
|
2357 <author> |
|
|
|
2358 <name>hiltjo</name> |
|
|
|
2359 <uri>https://www.codemadness.org</uri> |
|
|
|
2360 </author> |
|
|
|
2361 <summary type="text">My DWM configuration; a few added features to suit my needs</summary> |
|
|
|
2362 <content type="html"><![CDATA[<h1>DWM-hiltjo: my windowmanager configuration</h1> |
|
|
|
2363 <p><strong>Last modification on </strong> <time>2020-07-20</time></p> |
|
|
|
2364 <p>As you might know DWM is a very minimal windowmanager: <a href="https://dwm.suckless.org/">https://dwm.suckless.org/</a>. |
|
|
|
2365 It's known to only have the most essential features one needs, everything else is "do-it-yourself" or extending it with the |
|
|
|
2366 many available <a href="https://dwm.suckless.org/patches/">patches</a>. The vanilla version is less than 2000 SLOC, because |
|
|
|
2367 of this it's quite easy in my opinion to see how it works and modify it.</p> |
|
|
|
2368 |
|
|
|
2369 <p>I really like my configuration at the moment and want to share my changes. Some of the features listed below are patches from suckless.org I applied, but there are also some changes I made.</p> |
|
|
|
2370 |
|
|
|
2371 <p><em>Disclaimer: this configuration is entirely made for my personal preferences so you might not like it at all :)</em></p> |
|
|
|
2372 |
|
|
|
2373 |
|
|
|
2374 <h2>Features</h2> |
|
|
|
2375 <ul> |
|
|
|
2376 <li>Titlebar: |
|
|
|
2377 <ul> |
|
|
|
2378 <li>Shows all clients of the selected / active tags.</li> |
|
|
|
2379 <li>Divide application bars evenly among available space (awesomewm-like taskbar).</li> |
|
|
|
2380 <li>Colour urgent clients in the taskbar on active tags.</li> |
|
|
|
2381 <li>Left-click focuses clicked client.</li> |
|
|
|
2382 <li>Right-click toggles monocle layout.</li> |
|
|
|
2383 <li>Middle-click kills the clicked client.</li> |
|
|
|
2384 </ul> |
|
|
|
2385 </li> |
|
|
|
2386 <li>Tagbar: |
|
|
|
2387 <ul> |
|
|
|
2388 <li>Only show active tags.</li> |
|
|
|
2389 <li>Colour inactive tags with urgent clients.</li> |
|
|
|
2390 </ul> |
|
|
|
2391 </li> |
|
|
|
2392 <li>Layouts: |
|
|
|
2393 <ul> |
|
|
|
2394 <li>Cycle layouts with Modkey + Space (next) and Modkey + Control + Space (previous).</li> |
|
|
|
2395 <li>Fullscreen layout (hides topbar and removes borders).</li> |
|
|
|
2396 </ul> |
|
|
|
2397 </li> |
|
|
|
2398 <li>Other: |
|
|
|
2399 <ul> |
|
|
|
2400 <li>Move tiled clients around with the mouse (drag-move), awesomewm-like.</li> |
|
|
|
2401 <li>Add some keybinds for multimedia keyboards (audio play / pause, mute, www, volume buttons, etc).</li> |
|
|
|
2402 </ul> |
|
|
|
2403 </li> |
|
|
|
2404 <li>... and more ;) ...</li> |
|
|
|
2405 </ul> |
|
|
|
2406 |
|
|
|
2407 <p> |
|
|
|
2408 NOTES: I removed application icons (_NET_WM_ICON support), but if you want it for some reason you can find it in the history of this repo. |
|
|
|
2409 Pertag-like behaviour is also removed since it's wrong. |
|
|
|
2410 Cycling through urgent clients is also removed. |
|
|
|
2411 </p> |
|
|
|
2412 |
|
|
|
2413 |
|
|
|
2414 <h2>Clone</h2> |
|
|
|
2415 <pre><code>git clone -b hiltjo git://<a href="//git.codemadness.org/dwm/">git.codemadness.org/dwm</a></code></pre> |
|
|
|
2416 |
|
|
|
2417 |
|
|
|
2418 <h2>Screenshot</h2> |
|
|
|
2419 <p><a href="downloads/screenshots/dwm-screenshot.png"><img src="downloads/screenshots/dwm-screenshot-thumb.png" alt="Screenshot showing what dwm-hiltjo looks like" width="480" height="300" loading="lazy" /></a></p> |
|
|
|
2420 ]]></content> |
|
|
|
2421 </entry> |
|
|
|
2422 <entry> |
|
|
|
2423 <title type="text">Query unused CSS rules on current document state</title> |
|
|
|
2424 <link rel="alternate" type="text/html" href="https://www.codemadness.org/query-unused-css-rules-on-current-document-state.html" /> |
|
|
|
2425 <id>https://www.codemadness.org/query-unused-css-rules-on-current-document-state.html</id> |
|
|
|
2426 <updated>2010-04-21T00:00:00Z</updated> |
|
|
|
2427 <published>2010-04-21T00:00:00Z</published> |
|
|
|
2428 <author> |
|
|
|
2429 <name>hiltjo</name> |
|
|
|
2430 <uri>https://www.codemadness.org</uri> |
|
|
|
2431 </author> |
|
|
|
2432 <summary type="text">How to see all the rules in a stylesheet (CSS) that are not used for the current document</summary> |
|
|
|
2433 <content type="html"><![CDATA[<h1>Query unused CSS rules on current document state</h1> |
|
|
|
2434 <p><strong>Last modification on </strong> <time>2010-04-21</time></p> |
|
|
|
2435 <p> |
|
|
|
2436 Today I was doing some web development and wanted to see all the rules |
|
|
|
2437 in a stylesheet (CSS) that were not used for the current document. I |
|
|
|
2438 wrote the following Javascript code which you can paste in the Firebug |
|
|
|
2439 console and run: |
|
|
|
2440 </p> |
|
|
|
2441 |
|
|
|
2442 <pre><code>(function() { |
|
|
|
2443 for (var i=0;i<document.styleSheets.length;i++) { |
|
|
|
2444 var rules = document.styleSheets[i].cssRules || []; |
|
|
|
2445 var sheethref = document.styleSheets[i].href || 'inline'; |
|
|
|
2446 for (var r=0;r<rules.length;r++) |
|
|
|
2447 if (!document.querySelectorAll(rules[r].selectorText).length) |
|
|
|
2448 console.log(sheethref + ': "' + rules[r].selectorText + '" not found.'); |
|
|
|
2449 } |
|
|
|
2450 })(); |
|
|
|
2451 </code></pre> |
|
|
|
2452 |
|
|
|
2453 <p>This will output all the (currently) unused CSS rules per selector, the output can be for example:</p> |
|
|
|
2454 |
|
|
|
2455 <pre><code>http://www.codemadness.nl/blog/wp-content/themes/codemadness/style.css: "fieldset, a img" not found. |
|
|
|
2456 http://www.codemadness.nl/blog/wp-content/themes/codemadness/style.css: "#headerimg" not found. |
|
|
|
2457 http://www.codemadness.nl/blog/wp-content/themes/codemadness/style.css: "a:hover" not found. |
|
|
|
2458 http://www.codemadness.nl/blog/wp-content/themes/codemadness/style.css: "h2 a:hover, h3 a:hover" not found. |
|
|
|
2459 http://www.codemadness.nl/blog/wp-content/themes/codemadness/style.css: ".postmetadata-center" not found. |
|
|
|
2460 http://www.codemadness.nl/blog/wp-content/themes/codemadness/style.css: ".thread-alt" not found. |
|
|
|
2461 </code></pre> |
|
|
|
2462 |
|
|
|
2463 <p>Just a trick I wanted to share, I hope someone finds this useful :)</p> |
|
|
|
2464 |
|
|
|
2465 <p>For webkit-based browsers you can use "Developer Tools" and use "Audits" under "Web Page Performance" it says "Remove unused CSS rules". For Firefox there is also Google Page Speed: <a href="https://code.google.com/speed/page-speed/">https://code.google.com/speed/page-speed/</a> this adds an extra section under Firebug.</p> |
|
|
|
2466 |
|
|
|
2467 <p>Tested on Chrome and Firefox.</p> |
|
|
|
2468 ]]></content> |
|
|
|
2469 </entry> |
|
|
|
2470 <entry> |
|
|
|
2471 <title type="text">Driconf: enabling S3 texture compression on Linux</title> |
|
|
|
2472 <link rel="alternate" type="text/html" href="https://www.codemadness.org/driconf-enabling-s3-texture-compression-on-linux.html" /> |
|
|
|
2473 <id>https://www.codemadness.org/driconf-enabling-s3-texture-compression-on-linux.html</id> |
|
|
|
2474 <updated>2020-08-21T00:00:00Z</updated> |
|
|
|
2475 <published>2009-07-05T00:00:00Z</published> |
|
|
|
2476 <author> |
|
|
|
2477 <name>hiltjo</name> |
|
|
|
2478 <uri>https://www.codemadness.org</uri> |
|
|
|
2479 </author> |
|
|
|
2480 <summary type="text">driconf: enabling S3 texture compression</summary> |
|
|
|
2481 <content type="html"><![CDATA[<h1>Driconf: enabling S3 texture compression on Linux</h1> |
|
|
|
2482 <p><strong>Last modification on </strong> <time>2020-08-21</time></p> |
|
|
|
2483 <p><strong>Update: the DXTC patent expired on 2018-03-16, many distros enable this by default now.</strong></p> |
|
|
|
2484 |
|
|
|
2485 <p> |
|
|
|
2486 S3TC (also known as DXTn or DXTC) is a patented lossy texture compression algorithm. |
|
|
|
2487 See: <a href="https://en.wikipedia.org/wiki/S3TC">https://en.wikipedia.org/wiki/S3TC</a> for more detailed information. |
|
|
|
2488 Many games use S3TC and if you use Wine to play games you definitely want to enable it if your graphics card supports it. |
|
|
|
2489 |
|
|
|
2490 Because this algorithm was <a href="https://dri.freedesktop.org/wiki/S3TC/">patented it is disabled by default on many Linux distributions</a>. |
|
|
|
2491 </p> |
|
|
|
2492 |
|
|
|
2493 <p> |
|
|
|
2494 To enable it you can install the library "libtxc" if your favorite OS has not installed it already. |
|
|
|
2495 |
|
|
|
2496 For easy configuration you can install the optional utility DRIconf, which you can find at: <a href="http://dri.freedesktop.org/wiki/DriConf">http://dri.freedesktop.org/wiki/DriConf</a>. |
|
|
|
2497 DriConf can safely be removed after configuration. |
|
|
|
2498 </p> |
|
|
|
2499 |
|
|
|
2500 |
|
|
|
2501 <h2>Steps to enable it</h2> |
|
|
|
2502 <ol> |
|
|
|
2503 <li> |
|
|
|
2504 <p>Install libtxc_dxtn</p> |
|
|
|
2505 <p>ArchLinux:</p> |
|
|
|
2506 <pre><code># pacman -S libtxc_dxtn</code></pre> |
|
|
|
2507 <p>Debian:</p> |
|
|
|
2508 <pre><code># aptitude install libtxc-dxtn-s2tc0</code></pre> |
|
|
|
2509 </li> |
|
|
|
2510 <li> |
|
|
|
2511 <p>Install driconf (optional).</p> |
|
|
|
2512 <p>ArchLinux:</p> |
|
|
|
2513 <pre><code># pacman -S driconf</code></pre> |
|
|
|
2514 <p>Debian:</p> |
|
|
|
2515 <pre><code># aptitude install driconf</code></pre> |
|
|
|
2516 </li> |
|
|
|
2517 <li> |
|
|
|
2518 <p>Run driconf and enable S3TC</p> |
|
|
|
2519 <a href="downloads/screenshots/driconf.png"><img src="downloads/screenshots/driconf-thumb.png" alt="Screenshot of DRIconf window and it's options" width="300" height="266" loading="lazy" /></a> |
|
|
|
2520 </li> |
|
|
|
2521 </ol> |
|
|
|
2522 |
|
|
|
2523 |
|
|
|
2524 <h2>Additional links</h2> |
|
|
|
2525 <ol> |
|
|
|
2526 <li>S3TC: <a href="https://dri.freedesktop.org/wiki/S3TC/">https://dri.freedesktop.org/wiki/S3TC/</a></li> |
|
|
|
2527 <li>DriConf: <a href="https://dri.freedesktop.org/wiki/DriConf">https://dri.freedesktop.org/wiki/DriConf</a></li> |
|
|
|
2528 </ol> |
|
|
|
2529 ]]></content> |
|
|
|
2530 </entry> |
|
|
|
2531 <entry> |
|
|
|
2532 <title type="text">Getting the USB-powerline bridge to work on Linux</title> |
|
|
|
2533 <link rel="alternate" type="text/html" href="https://www.codemadness.org/getting-the-usb-powerline-bridge-to-work-on-linux.html" /> |
|
|
|
2534 <id>https://www.codemadness.org/getting-the-usb-powerline-bridge-to-work-on-linux.html</id> |
|
|
|
2535 <updated>2019-12-06T00:00:00Z</updated> |
|
|
|
2536 <published>2009-04-13T00:00:00Z</published> |
|
|
|
2537 <author> |
|
|
|
2538 <name>hiltjo</name> |
|
|
|
2539 <uri>https://www.codemadness.org</uri> |
|
|
|
2540 </author> |
|
|
|
2541 <summary type="text">A guide to get a USB-powerline bridge with the Intellon 51x1 chipset working on Linux</summary> |
|
|
|
2542 <content type="html"><![CDATA[<h1>Getting the USB-powerline bridge to work on Linux</h1> |
|
|
|
2543 <p><strong>Last modification on </strong> <time>2019-12-06</time></p> |
|
|
|
2544 <p><strong>NOTE: this guide is obsolete, a working driver is now included in the Linux kernel tree (<a href="https://lkml.org/lkml/2009/4/18/121">since Linux 2.6.31</a>)</strong></p> |
|
|
|
2545 |
|
|
|
2546 <h2>Introduction</h2> |
|
|
|
2547 <p> |
|
|
|
2548 A USB to powerline bridge is a network device that instead of using an ordinary Ethernet cable (CAT5 for example) or wireless LAN it uses the powerlines as a network to communicate with similar devices. |
|
|
|
2549 A more comprehensive explanation of what it is and how it works you can find <a href="https://en.wikipedia.org/wiki/IEEE_1901">here</a>. |
|
|
|
2550 </p> |
|
|
|
2551 |
|
|
|
2552 <p>Known products that use the Intellon 51x1 chipset:</p> |
|
|
|
2553 <ul> |
|
|
|
2554 <li>MicroLink dLAN USB</li> |
|
|
|
2555 <li>"Digitus network"</li> |
|
|
|
2556 <li>Intellon USB Ethernet powerline adapter</li> |
|
|
|
2557 <li>Lots of other USB-powerline adapters...</li> |
|
|
|
2558 </ul> |
|
|
|
2559 |
|
|
|
2560 <p>To check if your device is supported:</p> |
|
|
|
2561 <pre><code>$ lsusb | grep -i 09e1 |
|
|
|
2562 Bus 001 Device 003: ID 09e1:5121 Intellon Corp.</code></pre> |
|
|
|
2563 <p>If the vendor (09e1) and product (5121) ID match then it's probably supported.</p> |
|
|
|
2564 |
|
|
|
2565 |
|
|
|
2566 <h2>Installation</h2> |
|
|
|
2567 <p>Get drivers from the official site<sup><a href="http://www.devolo.co.uk/consumer/downloads-44-microlink-dlan-usb.html?l=en">1</a></sup> or here<sup><a href="downloads/int51x1/dLAN-linux-package-v4.tar.gz">2</a></sup>. The drivers from the official site are more up-to-date.</p> |
|
|
|
2568 |
|
|
|
2569 <p>Extract them:</p> |
|
|
|
2570 <pre><code>$ tar -xzvf dLAN-linux-package-v4.tar.gz</code></pre> |
|
|
|
2571 |
|
|
|
2572 <p>Go to the extracted directory and compile them:</p> |
|
|
|
2573 <pre><code>$ ./configure |
|
|
|
2574 $ make</code></pre> |
|
|
|
2575 |
|
|
|
2576 <p>Depending on the errors you got you might need to download<sup><a href="downloads/int51x1/int51x1.patch">3</a></sup> and apply my patch:</p> |
|
|
|
2577 <pre><code>$ cd dLAN-linux-package-v4/ (or other path to the source code) |
|
|
|
2578 $ patch < int51x1.patch</code></pre> |
|
|
|
2579 |
|
|
|
2580 <p>Try again:</p> |
|
|
|
2581 <pre><code>$ ./configure |
|
|
|
2582 $ make</code></pre> |
|
|
|
2583 |
|
|
|
2584 <p>If that failed try:</p> |
|
|
|
2585 <pre><code>$ ./configure |
|
|
|
2586 $ KBUILD_NOPEDANTIC=1 make</code></pre> |
|
|
|
2587 |
|
|
|
2588 <p>If that went OK install the drivers (as root):</p> |
|
|
|
2589 <pre><code># make install</code></pre> |
|
|
|
2590 |
|
|
|
2591 <p>Check if the "devolo_usb" module is loaded:</p> |
|
|
|
2592 <pre><code>$ lsmod | grep -i devolo_usb</code></pre> |
|
|
|
2593 <p>If it shows up then it's loaded. Now check if the interface is added:</p> |
|
|
|
2594 <pre><code>$ ifconfig -a | grep -i dlanusb |
|
|
|
2595 dlanusb0 Link encap:Ethernet HWaddr 00:12:34:56:78:9A</code></pre> |
|
|
|
2596 |
|
|
|
2597 |
|
|
|
2598 <h2>Configuration</h2> |
|
|
|
2599 <p>It is assumed you use a static IP, otherwise you can just use your DHCP client to get an unused IP address from your DHCP server. Setting up the interface is done like this (change the IP address and netmask accordingly if it's different):</p> |
|
|
|
2600 <pre><code># ifconfig dlanusb0 192.168.2.12 netmask 255.255.255.0</code></pre> |
|
|
|
2601 |
|
|
|
2602 |
|
|
|
2603 <h2>Checking if the network works</h2> |
|
|
|
2604 <p>Try to ping an IP address on your network to test for a working connection:</p> |
|
|
|
2605 <pre><code>$ ping 192.168.2.1 |
|
|
|
2606 PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data. |
|
|
|
2607 64 bytes from 192.168.2.1: icmp_seq=1 ttl=30 time=2.49 ms |
|
|
|
2608 64 bytes from 192.168.2.1: icmp_seq=2 ttl=30 time=3.37 ms |
|
|
|
2609 64 bytes from 192.168.2.1: icmp_seq=3 ttl=30 time=2.80 ms |
|
|
|
2610 --- 192.168.2.1 ping statistics --- |
|
|
|
2611 3 packets transmitted, 3 received, 0% packet loss, time 2005ms |
|
|
|
2612 rtt min/avg/max/mdev = 2.497/2.891/3.374/0.368 ms</code></pre> |
|
|
|
2613 |
|
|
|
2614 <p> |
|
|
|
2615 You can now set up a network connection like you normally do with any Ethernet device. |
|
|
|
2616 The route can be added like this for example:</p> |
|
|
|
2617 <pre><code># route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.2.1 dlanusb0</code></pre> |
|
|
|
2618 |
|
|
|
2619 <p>Change the IP address of your local gateway accordingly. Also make sure your nameserver is set in /etc/resolv.conf, something like:</p> |
|
|
|
2620 <pre><code>nameserver 192.168.2.1</code></pre> |
|
|
|
2621 |
|
|
|
2622 <p>Test your internet connection by doing for example:</p> |
|
|
|
2623 <pre><code>$ ping codemadness.org |
|
|
|
2624 PING codemadness.org (64.13.232.151) 56(84) bytes of data. |
|
|
|
2625 64 bytes from acmkoieeei.gs02.gridserver.com (64.13.232.151): icmp_seq=1 ttl=52 time=156 ms |
|
|
|
2626 64 bytes from acmkoieeei.gs02.gridserver.com (64.13.232.151): icmp_seq=2 ttl=52 time=156 ms |
|
|
|
2627 64 bytes from acmkoieeei.gs02.gridserver.com (64.13.232.151): icmp_seq=3 ttl=52 time=155 ms |
|
|
|
2628 --- codemadness.org ping statistics --- |
|
|
|
2629 3 packets transmitted, 3 received, 0% packet loss, time 1999ms |
|
|
|
2630 rtt min/avg/max/mdev = 155.986/156.312/156.731/0.552 ms</code></pre> |
|
|
|
2631 |
|
|
|
2632 <p> |
|
|
|
2633 If this command failed you probably have not setup your DNS/gateway properly. |
|
|
|
2634 If it worked then good for you :) |
|
|
|
2635 </p> |
|
|
|
2636 |
|
|
|
2637 |
|
|
|
2638 <h2>References</h2> |
|
|
|
2639 <ol> |
|
|
|
2640 <li><a href="http://www.devolo.co.uk/consumer/downloads-44-microlink-dlan-usb.html?l=en">Devolo download page with drivers (USB version).</a></li> |
|
|
|
2641 <li><a href="downloads/int51x1/dLAN-linux-package-v4.tar.gz">dLAN-linux-package-v4.tar.gz</a></li> |
|
|
|
2642 <li><a href="downloads/int51x1/int51x1.patch">Patch for recent 2.6.x kernels</a></li> |
|
|
|
2643 <li><a href="downloads/int51x1/INT51X1_datasheet.pdf">INT51X1 datasheet</a></li> |
|
|
|
2644 </ol> |
|
|
|
2645 ]]></content> |
|
|
|
2646 </entry> |
|
|
|
2647 <entry> |
|
|
|
2648 <title type="text">Gothic 1 game guide</title> |
|
|
|
2649 <link rel="alternate" type="text/html" href="https://www.codemadness.org/gothic-1-guide.html" /> |
|
|
|
2650 <id>https://www.codemadness.org/gothic-1-guide.html</id> |
|
|
|
2651 <updated>2020-04-30T00:00:00Z</updated> |
|
|
|
2652 <published>2009-04-12T00:00:00Z</published> |
|
|
|
2653 <author> |
|
|
|
2654 <name>hiltjo</name> |
|
|
|
2655 <uri>https://www.codemadness.org</uri> |
|
|
|
2656 </author> |
|
|
|
2657 <summary type="text">Gothic 1 game guide with some useful tips</summary> |
|
|
|
2658 <content type="html"><![CDATA[<h1>Gothic 1 game guide</h1> |
|
|
|
2659 <p><strong>Last modification on </strong> <time>2020-04-30</time></p> |
|
|
|
2660 <p>Disclaimer: <em> |
|
|
|
2661 Some (including myself) may find some of these hints/exploits cheating. This |
|
|
|
2662 guide is just for educational and fun purposes. Some of these hints/tips apply |
|
|
|
2663 to Gothic 2 as well. I got the meat exploit from a guide somewhere on the |
|
|
|
2664 internet I can't recall where, anyway kudos to that person. The other exploits |
|
|
|
2665 I discovered myself. If you use some hints or exploits from these guide, |
|
|
|
2666 please add me to your "credits", I will appreciate it :) |
|
|
|
2667 </em></p> |
|
|
|
2668 |
|
|
|
2669 |
|
|
|
2670 <h2>Configuration</h2> |
|
|
|
2671 |
|
|
|
2672 |
|
|
|
2673 <h3>Widescreen resolution</h3> |
|
|
|
2674 <p> |
|
|
|
2675 Gothic supports widescreen resolutions with a small tweak, add the following |
|
|
|
2676 text string as a command-line argument: |
|
|
|
2677 </p> |
|
|
|
2678 |
|
|
|
2679 <pre><code>-zRes:1920,1200,32</code></pre> |
|
|
|
2680 |
|
|
|
2681 <p> |
|
|
|
2682 This also works for Gothic 2. Here 1920 is the width, 1200 the height and |
|
|
|
2683 32 the bits per pixel, change this to your preferred resolution. |
|
|
|
2684 </p> |
|
|
|
2685 |
|
|
|
2686 |
|
|
|
2687 <h3>Fix crash with Steam version</h3> |
|
|
|
2688 <p> |
|
|
|
2689 Disable steam overlay. If that doesn't work rename GameOverlayRenderer.dll in |
|
|
|
2690 your steam folder to _GameOverlayRenderer.dll. |
|
|
|
2691 </p> |
|
|
|
2692 |
|
|
|
2693 <p>I strongly recommend to buy the better version from <a |
|
|
|
2694 href="https://www.gog.com/game/gothic">GOG.com</a>. The GOG version has no DRM |
|
|
|
2695 and allows easier modding, it also allows playing in most published languages: |
|
|
|
2696 German, English, Polish, furthermore it has some original artwork and |
|
|
|
2697 soundtrack included.</p> |
|
|
|
2698 |
|
|
|
2699 <h3>Upgrade Steam version to stand-alone version and remove Steam DRM (Gothic 1 and 2)</h3> |
|
|
|
2700 <p>You can install the Gothic playerkit and patches to remove the Steam DRM.</p> |
|
|
|
2701 |
|
|
|
2702 <p><a href="https://www.worldofgothic.de/">WorldOfGothic</a> playerkit patches:</p> |
|
|
|
2703 |
|
|
|
2704 <ul> |
|
|
|
2705 <li>Gothic 1 (EN): <a href="http://www.worldofgothic.com/dl/?go=dlfile&fileid=28">http://www.worldofgothic.com/dl/?go=dlfile&fileid=28</a></li> |
|
|
|
2706 <li>Gothic 1 (DE): <a href="https://www.worldofgothic.de/dl/download_34.htm">https://www.worldofgothic.de/dl/download_34.htm</a></li> |
|
|
|
2707 <li>Gothic 2 (EN/DE): <a href="https://www.worldofgothic.de/dl/download_168.htm">https://www.worldofgothic.de/dl/download_168.htm</a></li> |
|
|
|
2708 </ul> |
|
|
|
2709 |
|
|
|
2710 |
|
|
|
2711 <h3>Play Gothic in a different language with English subtitles (works best with GOG version)</h3> |
|
|
|
2712 |
|
|
|
2713 <p>If you're like me and have played the English version many times, but would |
|
|
|
2714 like to hear the (original) voice audio or if you would like to play with |
|
|
|
2715 different audio than you're used to, then you can copy the speech.vdf file of |
|
|
|
2716 your preferred version to your game files. Optionally turn on subtitles. I've |
|
|
|
2717 used this to play the English version of Gothic with the original German voice |
|
|
|
2718 audio and English subtitles.</p> |
|
|
|
2719 |
|
|
|
2720 |
|
|
|
2721 <h2>Easy money/weapons/armour/other items</h2> |
|
|
|
2722 |
|
|
|
2723 |
|
|
|
2724 <h3>Steal from Huno</h3> |
|
|
|
2725 <p>At night attack Huno the smith in the Old Camp and steal all his steel. Then |
|
|
|
2726 make some weapons and sell them with a merchant. When you ask Huno about |
|
|
|
2727 blacksmith equipment it will respawn with 5 of each kind of steel. This is also |
|
|
|
2728 a fairly good starting weapon (requires 20 strength). Also his chest located |
|
|
|
2729 near the sharpening stone and fire contains some steel as well, lock-pick it. |
|
|
|
2730 The combination is: RRLRLL. The chest contains _at least_ 20 raw steel, forge |
|
|
|
2731 it to get 20 crude swords which you can sell for 50 ore each to a merchant. |
|
|
|
2732 This will generate some nice starting money (1000+ ore) :)</p> |
|
|
|
2733 |
|
|
|
2734 |
|
|
|
2735 <h3>Steal weapons from the castle in the Old camp</h3> |
|
|
|
2736 <p>This tip is useful for getting pretty good starting weapons.</p> |
|
|
|
2737 |
|
|
|
2738 <p>Before entering the castle itself drop your ore (Left control + down for me) |
|
|
|
2739 in front of it. This will ensure when you get caught (and you probably will ;)) |
|
|
|
2740 no ore will get stolen by the guards. Now use the "slip past guard" technique |
|
|
|
2741 described below and you should be able to get into Gomez his castle. Run to the |
|
|
|
2742 left where some weapons are stored. Now make sure you at least steal the best |
|
|
|
2743 weapon (battle sword) and steal as much as you can until you get whacked. I |
|
|
|
2744 usually stand in the corner since that's where the best weapons are (battle |
|
|
|
2745 sword, judgement sword, etc). You'll now have some nice starting weapon(s) and |
|
|
|
2746 the good thing is they require very little attributes (about 13 strength).</p> |
|
|
|
2747 |
|
|
|
2748 |
|
|
|
2749 <h3>Free scraper armour the new camp</h3> |
|
|
|
2750 <p>In the new camp go to the mine and talk to Swiney at the bottom of "The |
|
|
|
2751 Hollow". Ask who he is and then ask to join the scrapers. He will give you a |
|
|
|
2752 "Diggers dress" worth 250 ore. It has the following stats: + 10 against |
|
|
|
2753 weapons. + 5 against fire. This will also give you free entrance to the bar in |
|
|
|
2754 the new camp.</p> |
|
|
|
2755 |
|
|
|
2756 <h3>Unlimited water bottles in the new camp</h3> |
|
|
|
2757 <p>In the quest from Lefty you will be assigned to get water bottles from the |
|
|
|
2758 rice lord. He will give you infinite amounts of water bottles, in batches of |
|
|
|
2759 12.</p> |
|
|
|
2760 |
|
|
|
2761 |
|
|
|
2762 <h3>Armour amulet and increase HP potion</h3> |
|
|
|
2763 <p> |
|
|
|
2764 In the old camp in the main castle there are at least 3 chests with valuable items that don't require a key: |
|
|
|
2765 </p> |
|
|
|
2766 <ul> |
|
|
|
2767 <li>Middle right side (looking from the entrance), 1 chest: |
|
|
|
2768 <ul> |
|
|
|
2769 <li>lock combination: LLLLRLRL</li> |
|
|
|
2770 <li>loot: |
|
|
|
2771 <ul> |
|
|
|
2772 <li>+15 against weapons, +15 against arrows (amulet of stone skin) (worth: 1000 ore)</li> |
|
|
|
2773 </ul> |
|
|
|
2774 </li> |
|
|
|
2775 <li>additionally there are 2 locked doors at the right side in this room. In |
|
|
|
2776 the final room there are 3 floors with lots of chests.</li> |
|
|
|
2777 </ul> |
|
|
|
2778 </li> |
|
|
|
2779 <li>Left side, 1 chest: |
|
|
|
2780 <ul> |
|
|
|
2781 <li>lock combination: RLLLLLRR</li> |
|
|
|
2782 <li>loot: |
|
|
|
2783 <ul> |
|
|
|
2784 <li>+8 mana amulet (worth: 600 ore)</li> |
|
|
|
2785 <li>2 potions (+70 hp)</li> |
|
|
|
2786 <li>dreamcall (weed)</li> |
|
|
|
2787 <li>120 coins (worth: nothing)</li> |
|
|
|
2788 </ul> |
|
|
|
2789 </li> |
|
|
|
2790 </ul> |
|
|
|
2791 </li> |
|
|
|
2792 <li>Right side, 2 chests with: |
|
|
|
2793 <ul> |
|
|
|
2794 <li>lock combination: RLLLRLLR</li> |
|
|
|
2795 <li>loot: |
|
|
|
2796 <ul> |
|
|
|
2797 <li>armour amulets, +15 against weapons (worth: 600 ore)</li> |
|
|
|
2798 <li>maximum life potion, +10 maximum life (worth: 1000 ore)</li> |
|
|
|
2799 <li>speed potion (1 minute duration)</li> |
|
|
|
2800 <li>4 potions (+70 hp)</li> |
|
|
|
2801 </ul> |
|
|
|
2802 </li> |
|
|
|
2803 </ul> |
|
|
|
2804 </li> |
|
|
|
2805 </ul> |
|
|
|
2806 |
|
|
|
2807 |
|
|
|
2808 <h3>Swamp camp harvest twice</h3> |
|
|
|
2809 |
|
|
|
2810 <p>In the swamp-weed harvest quest you must get swamp-weed for a guru. After |
|
|
|
2811 this quest you can get the harvest again, but you can keep the harvest without |
|
|
|
2812 consequences.</p> |
|
|
|
2813 |
|
|
|
2814 <h2>Exploits</h2> |
|
|
|
2815 |
|
|
|
2816 |
|
|
|
2817 <h3>Slip past guards</h3> |
|
|
|
2818 |
|
|
|
2819 <p>This exploit is really simple, just draw your weapon before you're |
|
|
|
2820 "targeted" by the guard and run past them this bypasses the dialog sequence. |
|
|
|
2821 When you're just out of their range holster your weapon again, so the people |
|
|
|
2822 around won't get pissed off.</p> |
|
|
|
2823 |
|
|
|
2824 <p>Works really well on the guards in front of the Old camp's castle, Y'Berrion |
|
|
|
2825 templars and New camp mercenaries near the Water magicians, just to name a |
|
|
|
2826 few.</p> |
|
|
|
2827 |
|
|
|
2828 <h3>Meat duplication</h3> |
|
|
|
2829 <p>Go to a pan and focus / target it so it says "frying pan" or similar. Now |
|
|
|
2830 open your inventory and select the meat. Now cook the meat (for me Left Control |
|
|
|
2831 + Arrow up). The inventory should remain open. You'll now have twice as much |
|
|
|
2832 meat as you had before. Do this a few times and you'll have a lot of meat, easy |
|
|
|
2833 for trading with ore/other items as well.</p> |
|
|
|
2834 |
|
|
|
2835 |
|
|
|
2836 <h3>Fall from great heights</h3> |
|
|
|
2837 <p>When you fall or jump from where you usually get fall damage you can do the |
|
|
|
2838 following trick: slightly before the ground use left or right strafe. |
|
|
|
2839 This works because it resets the falling animation. There are also other ways |
|
|
|
2840 to achieve the same thing such as attacking with a weapon in the air. |
|
|
|
2841 </p> |
|
|
|
2842 |
|
|
|
2843 |
|
|
|
2844 <h2>Experience / level up tips</h2> |
|
|
|
2845 |
|
|
|
2846 |
|
|
|
2847 <h3>Test of faith (extra exp)</h3> |
|
|
|
2848 <p>You get an additional 750 exp (from Lares) when you forge the letter in the |
|
|
|
2849 new camp and then give it to Diego. You can still join both camps after this.</p> |
|
|
|
2850 |
|
|
|
2851 |
|
|
|
2852 <h3>Fighting skeleton mages and their skeletons</h3> |
|
|
|
2853 <p>An easy way to get more experience is to let the skeleton mages summon as |
|
|
|
2854 much skeletons as they can. After you have defeated all of them: kill the |
|
|
|
2855 skeleton mage.</p> |
|
|
|
2856 |
|
|
|
2857 |
|
|
|
2858 <h3>Permanent str/dex/mana/hp potions/items and teachers</h3> |
|
|
|
2859 <p>When you want to get the maximum power at the end of the game you should |
|
|
|
2860 save up the items that give you a permanent boost. Teachers of strength, |
|
|
|
2861 dexterity and mana won't train over 100 of each skill. However using potions |
|
|
|
2862 and quest rewards you can increase this over 100.</p> |
|
|
|
2863 |
|
|
|
2864 <p>You should also look out for the following:</p> |
|
|
|
2865 <ul> |
|
|
|
2866 <li>Learn to get extra force into your punch from Horatio (strength +5, this |
|
|
|
2867 can't be done after level 100 strength).</li> |
|
|
|
2868 <li>Smoke the strongest non-quest joint (+2 mana).</li> |
|
|
|
2869 </ul> |
|
|
|
2870 |
|
|
|
2871 |
|
|
|
2872 <h3>Permanent potions in Sleeper temple</h3> |
|
|
|
2873 <p>This one is really obvious, but I would like to point out the mummy's on |
|
|
|
2874 each side where Xardas is located have lots and I mean lots of permanent |
|
|
|
2875 potions. This will give you a nice boost before the end battle.</p> |
|
|
|
2876 |
|
|
|
2877 |
|
|
|
2878 <h3>Permanent potions as reward in quests</h3> |
|
|
|
2879 <p>Always pick the permanent potion as a reward for quests when you can, for |
|
|
|
2880 example the quest for delivering the message to the High Fire magicians (mana |
|
|
|
2881 potion) or the one for fetching the almanac for the sect camp. Don't forget to |
|
|
|
2882 pick up the potions from Riordian the water magician when you're doing the |
|
|
|
2883 focus stones quest, it contains a strength and dexterity potion (+3).</p> |
|
|
|
2884 |
|
|
|
2885 |
|
|
|
2886 <h3>In conclusion</h3> |
|
|
|
2887 <p>When you use the tips described above Gothic should be a really easy game |
|
|
|
2888 and you should be able to get at a high(er) level with lots of |
|
|
|
2889 mana/strength/hp.</p> |
|
|
|
2890 |
|
|
|
2891 <p>Have fun!</p> |
|
|
|
2892 ]]></content> |
|
|
|
2893 </entry> |
|
|
|
2894 </feed> |
|