initial commit

This commit is contained in:
Quentin W 2024-07-18 14:09:32 -04:00
commit 5b839e0543
174 changed files with 12261 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.DS_Store
.htpasswd
werc/etc/*

48
Dockerfile Normal file
View file

@ -0,0 +1,48 @@
FROM alpine:latest
#ENV PLAN9 /usr/lib/9base
ENV PLAN9 /usr/lib/plan9
ENV EDITOR /usr/bin/nvim
#RUN apk add 9base --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
#RUN apk add plan9port
RUN apk add --update --no-cache \
lighttpd \
lighttpd-mod_auth \
apache2-utils \
curl \
discount \
shadow \
imagemagick \
aspell \
aspell-en \
neovim \
git build-base linux-headers libucontext-dev libxt-dev libx11-dev fontconfig-dev libxext-dev perl \
&& rm -rf /var/cache/apk/*
RUN curl http://werc.cat-v.org/download/werc-1.5.0.tar.gz | tar xzf - && mkdir -p /var/www/ && mv ../werc-*/ /var/www/werc
RUN git clone https://github.com/9fans/plan9port /usr/lib/plan9
WORKDIR /usr/lib/plan9
RUN ./INSTALL
WORKDIR /
COPY etc/lighttpd/ /etc/lighttpd/
RUN sed 's/fltr_cache md2html\.awk/fltr_cache markdown/' /var/www/werc/etc/initrc > /var/www/werc/etc/initrc.local
COPY init.sh /usr/local/bin
RUN chmod +x /usr/local/bin/init.sh
RUN ln -s $PLAN9 /usr/local/plan9
RUN ln -s $PLAN9/bin/rc /bin/rc
RUN ln -s $PLAN9/bin/awk /bin/awk
#RUN cp /usr/bin/sha1sum $PLAN9/bin
ENV PATH="$PLAN9/bin:${PATH}"
EXPOSE 80
#RUN /var/www/werc/bin/contrib/fix-rc-scripts /var/www/werc/bin
RUN usermod -u 1000 lighttpd
RUN chown -R lighttpd:root /var/www
RUN chmod -R g+w /var/www/werc/sites
#RUN sed '1s|^.*$|#!/usr/lib/9base/bin/rc|' /var/www/werc/bin/werc.rc > /tmp/werc.rc.tmp && mv /tmp/werc.rc.tmp /var/www/werc/bin/werc.rc && chmod 775 /var/www/werc/bin/werc.rc
#RUN sed 's/formatter=(fltr_cache md2html\.awk)/formatter=(fltr_cache markdown)/' /var/www/werc/etc/initrc > /var/www/werc/etc/initrc.local
CMD ["init.sh"]

32
docker-compose.yml Normal file
View file

@ -0,0 +1,32 @@
services:
werc:
build:
dockerfile: Dockerfile
context: .
ports:
- 80:80
environment:
- HOSTNAME=thirdculture.top
volumes:
- werc:/var/www/werc
- lighttpd:/etc/lighttpd
tty: true
gossa:
image: pldubouilh/gossa
ports:
- 8001:8001
volumes:
- ./werc/sites/thirdculture.top/_files:/shared
volumes:
werc:
driver: local
driver_opts:
o: bind
type: none
device: "./werc"
lighttpd:
driver: local
driver_opts:
o: bind
type: none
device: "./etc/lighttpd"

View file

@ -0,0 +1,21 @@
$HTTP["host"] =~ "^files\.thirdculture\.top$" {
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/etc/lighttpd/.htpasswd"
auth.require = ( "" =>
(
"method" => "basic",
"realm" => "Password protected area",
"require" => "valid-user"
)
)
proxy.server = (
"" => (
(
"host" => "gossa",
"port" => 8001
)
)
)
}

View file

@ -0,0 +1,6 @@
$HTTP["host"] =~ "^ppl\.thirdculture\.top$" {
index-file.names = ( )
server.error-handler-404 = "/werc.rc"
alias.url += ( "/werc.rc" => "/var/www/werc/bin/werc.rc" )
cgi.assign += ( ".rc" => "")
}

View file

@ -0,0 +1,6 @@
$HTTP["host"] =~ "^thirdculture\.top$" {
index-file.names = ( )
server.error-handler-404 = "/werc.rc"
alias.url += ( "/werc.rc" => "/var/www/werc/bin/werc.rc" )
cgi.assign += ( ".rc" => "")
}

326
etc/lighttpd/lighttpd.conf Normal file
View file

@ -0,0 +1,326 @@
###############################################################################
# Default lighttpd.conf for Gentoo.
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $
###############################################################################
# {{{ variables
var.basedir = "/var/www/localhost"
var.logdir = "/var/log/lighttpd"
var.statedir = "/var/lib/lighttpd"
# }}}
# {{{ modules
# At the very least, mod_access and mod_accesslog should be enabled.
# All other modules should only be loaded if necessary.
# NOTE: the order of modules is important.
server.modules = (
"mod_rewrite",
# "mod_redirect",
"mod_alias",
"mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
"mod_auth",
# "mod_status",
# "mod_setenv",
"mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
# "mod_deflate",
# "mod_ssi",
# "mod_usertrack",
# "mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
# "mod_webdav",
"mod_accesslog"
)
# }}}
# {{{ includes
include "mime-types.conf"
# uncomment for cgi support
include "mod_cgi.conf"
# uncomment for php/fastcgi support
# include "mod_fastcgi.conf"
# uncomment for php/fastcgi fpm support
# include "mod_fastcgi_fpm.conf"
# }}}
# {{{ server settings
server.username = "lighttpd"
server.groupname = "lighttpd"
server.document-root = var.basedir + "/htdocs"
server.pid-file = "/run/lighttpd.pid"
server.errorlog = "/dev/pts/0"
#server.errorlog = var.logdir + "/error.log"
# log errors to syslog instead
# server.errorlog-use-syslog = "enable"
server.indexfiles = ("index.php", "index.html",
"index.htm", "default.htm")
# server.tag = "lighttpd"
server.follow-symlink = "enable"
# event handler (defaults to "poll")
# see performance.txt
#
# for >= linux-2.4
# server.event-handler = "linux-rtsig"
# for >= linux-2.6
# server.event-handler = "linux-sysepoll"
# for FreeBSD
# server.event-handler = "freebsd-kqueue"
# chroot to directory (defaults to no chroot)
# server.chroot = "/"
# bind to port (defaults to 80)
# server.port = 81
# bind to name (defaults to all interfaces)
# server.bind = "grisu.home.kneschke.de"
# error-handler for status 404
# server.error-handler-404 = "/error-handler.html"
# server.error-handler-404 = "/error-handler.php"
# Format: <errorfile-prefix><status-code>.html
# -> ..../status-404.html for 'File not found'
# server.errorfile-prefix = var.basedir + "/error/status-"
# FAM support for caching stat() calls
# requires that lighttpd be built with USE=fam
# server.stat-cache-engine = "fam"
# }}}
# {{{ mod_staticfile
# which extensions should not be handled via static-file transfer
# (extensions that are usually handled by mod_cgi, mod_fastcgi, etc).
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")
# }}}
# {{{ mod_accesslog
accesslog.filename = "/dev/pts/0"
#accesslog.filename = var.logdir + "/access.log"
# }}}
# {{{ mod_dirlisting
# enable directory listings
# dir-listing.activate = "enable"
#
# don't list hidden files/directories
# dir-listing.hide-dotfiles = "enable"
#
# use a different css for directory listings
# dir-listing.external-css = "/path/to/dir-listing.css"
#
# list of regular expressions. files that match any of the
# specified regular expressions will be excluded from directory
# listings.
# dir-listing.exclude = ("^\.", "~$")
# }}}
# {{{ mod_access
# see access.txt
url.access-deny = ("~", ".inc")
# }}}
# {{{ mod_userdir
# see userdir.txt
#
# userdir.path = "public_html"
# userdir.exclude-user = ("root")
# }}}
# {{{ mod_ssi
# see ssi.txt
#
# ssi.extension = (".shtml")
# }}}
# {{{ mod_ssl
# see ssl.txt
#
# ssl.engine = "enable"
# ssl.pemfile = "server.pem"
# }}}
# {{{ mod_status
# see status.txt
#
# status.status-url = "/server-status"
# status.config-url = "/server-config"
# }}}
# {{{ mod_simple_vhost
# see simple-vhost.txt
#
# If you want name-based virtual hosting add the next three settings and load
# mod_simple_vhost
#
# document-root =
# virtual-server-root + virtual-server-default-host + virtual-server-docroot
# or
# virtual-server-root + http-host + virtual-server-docroot
#
# simple-vhost.server-root = "/home/weigon/wwwroot/servers/"
# simple-vhost.default-host = "grisu.home.kneschke.de"
# simple-vhost.document-root = "/pages/"
# }}}
# {{{ mod_deflate
# see compress.txt
#
# deflate.cache-dir = var.statedir + "/cache/compress"
# deflate.mimetypes = ("text/plain", "text/html")
# }}}
# {{{ mod_proxy
# see proxy.txt
#
# proxy.server = ( ".php" =>
# ( "localhost" =>
# (
# "host" => "192.168.0.101",
# "port" => 80
# )
# )
# )
# }}}
# {{{ mod_auth
# see authentication.txt
#
# auth.backend = "plain"
# auth.backend.plain.userfile = "lighttpd.user"
# auth.backend.plain.groupfile = "lighttpd.group"
# auth.backend.ldap.hostname = "localhost"
# auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
# auth.backend.ldap.filter = "(uid=$)"
# auth.require = ( "/server-status" =>
# (
# "method" => "digest",
# "realm" => "download archiv",
# "require" => "user=jan"
# ),
# "/server-info" =>
# (
# "method" => "digest",
# "realm" => "download archiv",
# "require" => "valid-user"
# )
# )
# }}}
# {{{ mod_rewrite
# see rewrite.txt
#
# url.rewrite = (
# "^/$" => "/server-status"
# )
# }}}
# {{{ mod_redirect
# see redirect.txt
#
# url.redirect = (
# "^/wishlist/(.+)" => "http://www.123.org/$1"
# )
# }}}
# {{{ mod_evhost
# define a pattern for the host url finding
# %% => % sign
# %0 => domain name + tld
# %1 => tld
# %2 => domain name without tld
# %3 => subdomain 1 name
# %4 => subdomain 2 name
#
# evhost.path-pattern = "/home/storage/dev/www/%3/htdocs/"
# }}}
# {{{ mod_expire
# expire.url = (
# "/buggy/" => "access 2 hours",
# "/asdhas/" => "access plus 1 seconds 2 minutes"
# )
# }}}
# {{{ mod_rrdtool
# see rrdtool.txt
#
# rrdtool.binary = "/usr/bin/rrdtool"
# rrdtool.db-name = var.statedir + "/lighttpd.rrd"
# }}}
# {{{ mod_setenv
# see setenv.txt
#
# setenv.add-request-header = ( "TRAV_ENV" => "mysql://user@host/db" )
# setenv.add-response-header = ( "X-Secret-Message" => "42" )
# }}}
# {{{ mod_trigger_b4_dl
# see trigger_b4_dl.txt
#
# trigger-before-download.gdbm-filename = "/home/weigon/testbase/trigger.db"
# trigger-before-download.memcache-hosts = ( "127.0.0.1:11211" )
# trigger-before-download.trigger-url = "^/trigger/"
# trigger-before-download.download-url = "^/download/"
# trigger-before-download.deny-url = "http://127.0.0.1/index.html"
# trigger-before-download.trigger-timeout = 10
# }}}
# {{{ mod_cml
# see cml.txt
#
# don't forget to add index.cml to server.indexfiles
# cml.extension = ".cml"
# cml.memcache-hosts = ( "127.0.0.1:11211" )
# }}}
# {{{ mod_webdav
# see webdav.txt
#
# $HTTP["url"] =~ "^/dav($|/)" {
# webdav.activate = "enable"
# webdav.is-readonly = "enable"
# }
# }}}
# {{{ extra rules
#
# set Content-Encoding and reset Content-Type for browsers that
# support decompressing on-thy-fly (requires mod_setenv)
# $HTTP["url"] =~ "\.gz$" {
# setenv.add-response-header = ("Content-Encoding" => "x-gzip")
# mimetype.assign = (".gz" => "text/plain")
# }
# $HTTP["url"] =~ "\.bz2$" {
# setenv.add-response-header = ("Content-Encoding" => "x-bzip2")
# mimetype.assign = (".bz2" => "text/plain")
# }
#
# }}}
# {{{ debug
# debug.log-request-header = "enable"
# debug.log-response-header = "enable"
# debug.log-request-handling = "enable"
# debug.log-file-not-found = "enable"
# }}}
# vim: set ft=conf foldmethod=marker et :
include "/etc/lighttpd/conf.d/*.conf"

View file

@ -0,0 +1,79 @@
###############################################################################
# Default mime-types.conf for Gentoo.
# include'd from lighttpd.conf.
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mime-types.conf,v 1.4 2010/03/14 21:45:18 bangert Exp $
###############################################################################
# {{{ mime types
mimetype.assign = (
".svg" => "image/svg+xml",
".svgz" => "image/svg+xml",
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".spl" => "application/futuresplash",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".torrent" => "application/x-bittorrent",
".dvi" => "application/x-dvi",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".dmg" => "application/x-apple-diskimage",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".wax" => "audio/x-ms-wax",
".ogg" => "application/ogg",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".asc" => "text/plain",
".c" => "text/plain",
".h" => "text/plain",
".cc" => "text/plain",
".cpp" => "text/plain",
".hh" => "text/plain",
".hpp" => "text/plain",
".conf" => "text/plain",
".log" => "text/plain",
".text" => "text/plain",
".txt" => "text/plain",
".diff" => "text/plain",
".patch" => "text/plain",
".ebuild" => "text/plain",
".eclass" => "text/plain",
".rtf" => "application/rtf",
".bmp" => "image/bmp",
".tif" => "image/tiff",
".tiff" => "image/tiff",
".ico" => "image/x-icon",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".wmv" => "video/x-ms-wmv",
".bz2" => "application/x-bzip",
".tbz" => "application/x-bzip-compressed-tar",
".tar.bz2" => "application/x-bzip-compressed-tar"
)
# }}}
# vim: set ft=conf foldmethod=marker et :

33
etc/lighttpd/mod_cgi.conf Normal file
View file

@ -0,0 +1,33 @@
###############################################################################
# mod_cgi.conf
# include'd by lighttpd.conf.
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_cgi.conf,v 1.1 2005/08/27 12:36:13 ka0ttic Exp $
###############################################################################
#
# see cgi.txt for more information on using mod_cgi
#
server.modules += ("mod_cgi")
# NOTE: this requires mod_alias
alias.url = (
"/cgi-bin/" => var.basedir + "/cgi-bin/"
)
#
# Note that you'll also want to enable the
# cgi-bin alias via mod_alias (above).
#
$HTTP["url"] =~ "^/cgi-bin/" {
# disable directory listings
#dir-listing.activate = "disable"
# only allow cgi's in this directory
cgi.assign = (
".pl" => "/usr/bin/perl",
".cgi" => "/usr/bin/perl"
)
}
# vim: set ft=conf foldmethod=marker et :

View file

@ -0,0 +1,17 @@
###############################################################################
# mod_fastcgi.conf
# include'd by lighttpd.conf.
# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/mod_fastcgi.conf-1.4.13-r2,v 1.1 2007/04/01 23:22:00 robbat2 Exp $
###############################################################################
server.modules += ("mod_fastcgi")
fastcgi.server = ( ".php" =>
( "localhost" =>
(
"socket" => "/run/lighttpd/lighttpd-fastcgi-php-" + PID + ".socket",
"bin-path" => "/usr/bin/php-cgi"
)
)
)
# vim: set ft=conf foldmethod=marker et :

View file

@ -0,0 +1,16 @@
###############################################################################
# mod_fastcgi_fpm.conf
# include'd by lighttpd.conf.
###############################################################################
server.modules += ("mod_fastcgi")
fastcgi.server = ( ".php" =>
( "localhost" =>
(
"host" => "127.0.0.1",
"port" => "9000"
)
)
)
# vim: set ft=conf foldmethod=marker et :

24
init.sh Normal file
View file

@ -0,0 +1,24 @@
#!/bin/sh
if [ ! -d "/var/www/werc/sites/$HOSTNAME" ]; then
echo "Index directory for hostname $HOSTNAME does not exist. Creating..."
cp -r /var/www/werc/sites/werc.cat-v.org "/var/www/werc/sites/$HOSTNAME"
echo "# Hello World!" > "/var/www/werc/sites/$HOSTNAME/index.md"
fi
CONF_FILE="/etc/lighttpd/conf.d/$HOSTNAME.conf"
if [ ! -f "$CONF_FILE" ]; then
echo "Creating new configuration file: $CONF_FILE"
cat << EOF > "$CONF_FILE"
\$HTTP["host"] =~ "^$(echo "$HOSTNAME" | sed 's/\./\\./g')$" {
index-file.names = ( )
server.error-handler-404 = "/werc.rc"
alias.url += ( "/werc.rc" => "/var/www/werc/bin/werc.rc" )
cgi.assign += ( ".rc" => "" )
}
EOF
fi
echo "Running lighttpd"
chmod a+w /dev/pts/0
exec lighttpd -D -f /etc/lighttpd/lighttpd.conf

79
werc/README Normal file
View file

@ -0,0 +1,79 @@
werc - a minimalist document management system
----------------------------------------------
Werc is a content management system and web (anti-)framework designed to be simple to
use, simple to setup, simple to hack on, and not get in the way while allowing
users easy customization.
For more information see the official website: http://werc.cat-v.org/
Installation
------------
Requirements:
* An http server that can handle CGIs
* Plan 9 from User Space: http://swtch.com/plan9port,
Or 9base-tip: http://tools.suckless.org/9base,
Or frontbase: http://openbsd.stanleylieber.com/frontbase
Note: Werc by default expects the Plan 9 tools to be installed under
/bin/, if you have installed them elsewhere you will need to edit the
#! line in bin/werc.rc and customize the $plan9port variable in your
etc/initrc.local.
Instructions:
Untar werc at your desired location, configure httpd to use
/path-to-your-werc-installation/bin/werc.rc as a cgi-script, it is recommended
that you make werc.rc handle all non-static files (this can be done by setting
it up as your 404 handler) and setup your virtual hosts to handle static files
by setting the document root for the domain to
/path-to-werc-installation/sites/yourdomain.com/, and create a directory for
your web site under sites/ where you can start adding content right away.
If you will want to allow updates via the web interface (eg., for wiki or
comments apps) make sure all files under sites/ are writable by the user your
cgi will run as, usually www-data, for example by doing: chown -R :www-data
sites/; chmod -R g+w sites/
If your Plan 9 binaries are located somewhere else than the standard /bin/ you
will need to edit the first line of bin/werc.rc (Note that p9p in particular is
picky about where it is located, once you run ./INSTALL you should *not* move
it to a different directory without running ./INSTALL again.)
For general configuration options copy etc/initrc to etc/initrc.local and
customize it as needed. Site (and directory) specific options can be set in a
sites/example.com/_werc/config file inside the site's directory. To customize
templates and included files you can store your own version of the files in
lib/ under sites/example.com/_werc/lib.
The source tree for the werc website is included under sites/werc.cat-v.org as
an example, feel free to use it as a template for your own site.
For more details see the documentation section of the website:
http://werc.cat-v.org/docs/
Contact
-------
For comments, suggestions, bug reports or patches join the werc mailing list
at: http://werc.cat-v.org or the irc channel #cat-v in irc.freenode.org
If you have a public website that uses werc I would love to hear about it and
get feedback about you experience setting it up.
Thanks
------
Garbeam, Kris Maglione, sqweek, soul9, mycroftiv, maht, yiyus, cinap_lenrek,
khm and many others for their ideas, patches, testing and other contributions.
License
-------
Werc is in the public domain.

View file

@ -0,0 +1,6 @@
repo: 77501160f26f7411d00111255a38267f9973ec27
node: e422b2d51d185ecbbdb180a28fdd13cac672be03
branch: default
latesttag: null
latesttagdistance: 25
changessincelatesttag: 25

158
werc/apps/barf/README Executable file
View file

@ -0,0 +1,158 @@
BARF - emit HTML
DESCRIPTION
BARF utilizes rc(1) and command line tools to compile a structured
directory of files into a single page of HTML. Tagging and RSS 2.0
feeds have been implemented.
SETUP
To enable BARF, add:
conf_enable_barf
to _werc/config under the site root.
To configure BARF, copy or create the following files under the site
root (example files have been included in this distribution):
_werc/barf/config
A list of variables that control various site options:
barf_type=paste # blog, image, log, paste
posts_per_page=10
show_ascending=0
show_footer=0
show_header=0
show_sidebar=0
require_login=0 # if not logged in, redirect to /login
allow_anon=1 # allow posts without logging in
show_disqus=0 # include disqus comments template
# from _werc/barf/disqus
_werc/barf/footer
HTML or markdown that will appear as the foot of
the BARF content area.
_werc/barf/header
HTML or markdown that will appear at the head of
the BARF content area.
_werc/barf/sidebar
HTML or markdown that will appear on one side of
the BARF content area.
Finally, sample stylesheets are provided in the directory
pub/. Copy any of these to _werc/pub/style.css to try
them out.
POSTS
Posts are stored in the directory src/ relative to the
site root.
Directory names in src/ that do not match the regular
expression ^[0-9]*$ will not be included in the listing of
posts that are displayed in the browser. However, such
directories are still accessible when called directly via
an appropriately constructed URL.
A post's directory contains the following files and
directories (an example post's directory has been
included in this distribution):
body
date
img/
link
tags/
title
The img/ directory contains images uploaded to the
image board, including the original image and a
thumbnail version, resized to no greater than 500
pixels wide and 600 pixels tall.
The tags/ directory contains one empty file named
for each tag associated with the post.
The site root contains a file named tags that is compr-
ised of an index of the tags associated with each post.
This index is consulted when searching for a given tag in
the web browser.
UTILS
bin/gf
Parse Livejournal and Tumblr RSS feeds into
BARF posts. (Abandoned, may no longer work.)
bin/gk
Create a list of known tags in the site root in
a file named known_tags.
bin/gr
Parse Google Reader bundles into BARF posts.
bin/gt
Create an index of tags in the site root in a file
named tags.
For more information on these tools, read the source.
ADMIN
Any tool that can create, alter, or delete flat files
and directories is sufficient to administer a BARF.
Web-based login and administration utilizes werc's
built-in user authentication:
http://domain.com/login
After login, links to edit and delete will appear in
each post's meta data.
Web-based administration requires that the src/
directory and its sub-directories are writable by
the web server process.
REQUIREMENTS
Unix
Plan9port or 9base are required. Site type
image requires ImageMagick and curl. Site
type url also requires curl if the user employs
the option to download remote URLs. These
utilities may be swapped out for others by
altering the source.
SOURCE
http://plan9.stanleylieber.com/werc/apps/barf.tgz
https://code.9front.org/hg/barf
EXAMPLES
blog
http://read.stanleylieber.com
RSS feeds are converted by the utility rrss[0]
and stored as individual blog posts.
image
http://img.stanleylieber.com
Hybrid public/private image board. Requires
standard werc authentication to post, but all
posts are visible to the public.
paste
http://okturing.com
Public pastebin. No authentication required
to post.
url
http://url.stanleylieber.com
Private index of URL bookmarks, similar
in functionality to the old delicious.com.
(In fact, most of the index was imported
from delicious.)
SEE ALSO
[0] https://code.9front.org/hg/rrss
LICENSE
Public domain.
BUGS
On Plan 9, if the web server process is run as user
none (typically the case), directories used for entering
posts or uploading/downloading files from the browser
must be set world writable. This could prove problematic
on multiuser systems.

80
werc/apps/barf/app.rc Executable file
View file

@ -0,0 +1,80 @@
fn conf_enable_barf{
barf_base_uri=$conf_wd
barf_root=`{pwd}
conf_enable_app barf
}
fn barf_init{
p=`{echo $req_path | sed 's!^'^$barf_base_uri^'!!'}
barf_dir=`{basename -d $"p | sed 's!^\.$!!'}
barf_items=`{cat $barf_root/_werc/barf/items}
. ./apps/barf/lib/core
. ./apps/barf/barf/config
. $barf_root/_werc/barf/config
. ./apps/barf/lib/$barf_type
if(test -f $barf_root/_werc/barf/lib/$barf_type)
. $barf_root/_werc/barf/lib/$barf_type
if(~ $require_login 1 && ! ~ $req_path $barf_base_uri^login){
check_user
if(~ $#logged_user 0)
post_redirect /login
}
if(~ $REQUEST_METHOD GET && ~ $REQUEST_URI *'='*){
load_get_args
parse_get_args
}
if(~ $REQUEST_METHOD POST)
parse_post_args
if(~ $a_func add_post){
if(~ $allow_anon 1 || {check_user && ! ~ $#logged_user 0})
add_post
post_redirect /
}
if(~ $a_func edit_post delete_post dsrc){
if(check_user && ! ~ $#logged_user 0){
switch($a_func){
case edit_post
edit_post
case delete_post
delete_post
case dsrc
dsrc
}
}
}
get_start
get_stop
get_tags
if(~ $req_path $barf_base_uri){
extraHeaders=$"extraHeaders ^ \
'<link rel="alternate" type="application/rss+xml" title="RSS" href="'$base_url^$barf_base_uri'index.rss" />'
handler_body_main=(tpl_handler `{barf_template barf})
}
if not if(~ $req_path $barf_base_uri^index.rss){
obarf_type=$barf_type # disgusting hack. fix!
barf_type=rss
. ./apps/barf/lib/rss
barf_setup_feed_handlers barf.tpl 'text/xml; charset=utf-8'
}
if not if(~ $req_path $barf_base_uri^login){
barf_type=login
handler_body_main=(tpl_handler `{barf_template barf})
}
}
fn barf_setup_feed_handlers{
handler_body_main=NOT_USED_by_barf_feeds
res_tail=()
http_content_type=$2
headers=()
master_template=apps/barf/lib/$1
}
fn barf_template{
if(test -f $barf_root/$"barf_dir/_werc/barf/lib/$1.tpl)
echo -n $barf_root/$"barf_dir/_werc/barf/lib/$1.tpl
if not if(test -f $barf_root/_werc/barf/lib/$1.tpl)
echo -n $barf_root/_werc/barf/lib/$1.tpl
if not
get_lib_file barf/$1.tpl apps/barf/lib/$1.tpl
}

9
werc/apps/barf/barf/config Executable file
View file

@ -0,0 +1,9 @@
barf_type=blog # blog, image, log, paste, url
site_tmp=_tmp # used by hoc on plan 9
posts_per_page=10
show_ascending=0
show_footer=0
show_header=0
show_sidebar=0
require_login=0 # if not logged in, redirect to /login
allow_anon=1 # allow posts without logging in

1
werc/apps/barf/barf/footer Executable file
View file

@ -0,0 +1 @@
THIS IS THE FOOTER.

1
werc/apps/barf/barf/header Executable file
View file

@ -0,0 +1 @@
THIS IS THE HEADER.

1
werc/apps/barf/barf/sidebar Executable file
View file

@ -0,0 +1 @@
THIS IS THE SIDEBAR.

174
werc/apps/barf/bin/bsrc Executable file
View file

@ -0,0 +1,174 @@
#!/bin/rc
# Build static pages for $site.
rfork e
fn usage{
echo usage: $0 [ domain.com ] >[1=2]
exit usage
}
if(~ $#1 0)
usage
fn conf_enable_barf{ }
werc=/var/www/werc
site=$werc/sites/$1
barf_root=$site
. $site/_werc/config
. $site/_werc/barf/config
. $werc/apps/barf/lib/core
. $werc/apps/barf/lib/$barf_type
if(test -f $site/_werc/barf/lib/$barf_type)
. $site/_werc/barf/lib/$barf_type
if(~ $show_ascending 1)
sort=(sort -nu)
if not
sort=(sort -nru)
fn check_user{ }
fn display_html_footers{
echo '</body>
</html>'
}
fn display_html_headers{
echo '<html>
<head>
<title>'$"siteTitle'</title>
<link rel="stylesheet" href="/_werc/pub/style.css" type="text/css" media="screen" title="default">
<link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="'$"rss'">
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
'
}
fn display_prevnext{
if(~ $#nstart 1){
echo '
<div id="page_list">
<span>
'
if(test $start -lt $pstop && ! ~ $start $pstart)
echo '<a href="'$pstart^'-'^$pstop^'.html">prev</a> | '
echo '</span>
<span>
'
if(test $nstart -gt $bposts($#bposts))
echo '<a href="'$nstart^'-'^$nstop^'.html">next</a>'
echo '
</span>
</div>
'
}
}
fn get_post_list{
if(~ $#posts 0){
if(~ $id [0-9]*)
posts=$id
if not{
posts=`{
if(~ $tags all)
ls -p $site/src |
grep -e '^[0-9]*$' |
eval $sort |
sed -n $start^,^$stop^p
if not
grep -e '^.*\/'$tags'$' $site/tags |
awk -F '/' '{print $1;}' |
eval $sort |
sed -n $start^,^$stop^p
}
if(! ~ $posts [0-9]*)
posts=()
}
}
}
fn print{
display_html_headers
if(~ $show_header 1)
display_header
display_^$barf_type
if(~ $show_sidebar 1)
display_sidebar
if(~ $show_footer 1)
display_footer
display_html_footers
}
fn print_id{
echo '<span id="post_id"><a href="'$"a_id'.html">No.'$"a_id'</a></span>'
}
fn print_tags{
a_tags=`{ls -p $a_dir/tags}
a_tags=`{for(t in $a_tags) echo '<a href="/tag/'$t'">'$t'</a>, '}
a_tags=`{echo $a_tags | awk '{print substr($0, 1, length($0) -1)}'}
echo '<span id="post_tags">'$"a_tags'</span>'
}
fn print_title{
a_title=`{cat $a_dir/title}
if(! ~ $#a_title 0){
if(~ $barf_type log url)
echo '<a href="'`{cat $a_dir/link}'">'$"a_title'</a>'
if not
echo '<a href="'$"a_id'.html">'$"a_title'</a>'
}
}
cd $site
# individual posts
bposts=`{ls -p $site/src | grep -v private | grep -e '^[0-9]*$' | eval $sort}
for(b in $bposts){
id=$b posts=() print >$b.html
echo $"b^'.html' >[1=2]
}
# paginated posts
start=$bposts(1)
stop=`{echo $bposts(1)^-^$posts_per_page | bc}
pstart=$start
pstop=$stop
while(test $start -ge $bposts($#bposts)){
if(test $stop -lt $bposts($#bposts))
stop=$bposts($#bposts)
nstart=`{echo $stop^-^1 | bc}
nstop=`{echo $stop^-^$posts_per_page^-1 | bc}
pposts=`{
for(i in `{seq $stop $start | eval $sort})
if(test -d $site/src/$i)
echo $i
}
tags=all posts=$pposts print >$start^-^$stop.html
echo $"start^'-'^$"stop^'.html' >[1=2]
pstart=$start
pstop=$stop
start=`{echo $stop^-1 | bc}
stop=`{echo $start^-^$posts_per_page | bc}
}
cp `{ls [0-9]*-[0-9]*.html | sort -n | tail -1} index.html
if(test -x /boot/factotum)
chmod +t [0-9]*.html [0-9]*-[0-9]*.html index.html
# tags
for(b in `{awk -F '/' '{print $3;}' tags | sort -u}){
btags=$b
mkdir -p tag/$btags
bposts=`{grep -e '^.*\/'$btags'$' tags | awk -F '/' '{print $1;}' | eval $sort}
start=$bposts(1)
stop=$bposts($#bposts)
tags=all posts=$bposts print >tag/$btags/index.html
echo tag/$btags/index.html >[1=2]
if(test -x /boot/factotum)
chmod +t tag tag/$btags tag/$btags/index.html
}

31
werc/apps/barf/bin/dsrc Executable file
View file

@ -0,0 +1,31 @@
#!/bin/rc
# 2016-05-01T18:47:42-0400
# Delete posts $low through $high.
rfork e
dhost=ur.inri.net
fn usage {
echo usage: dsrc [ -r n ] [ -t n ] >[1=2]
exit usage
}
switch($1){
case -r
site=/usr/sl/www/werc/sites/read.stanleylieber.com
case -t
site=/usr/sl/www/werc/sites/tumblr.stanleylieber.com
case *
usage
}
if(! ~ $sysname ur){
rcpu -h $dhost -c dsrc $*
exit
}
low=`{ls -p $site/src | sort -n | sed 1q}
high=$2
cd $site/src && rm -rf `{seq $low $high}
{
for(i in `{seq $low $high})
echo ',x/^'$i'\/.*\n/d'
echo w
echo w
echo q
} | sam -d $site/tags >[2]/dev/null

426
werc/apps/barf/bin/gf Executable file
View file

@ -0,0 +1,426 @@
#!/bin/rc
# Parse RSS feeds from livejournal or tumblr into BARF blog posts
# for the specified site. If a post with a matching <link> already
# exists, no new post will be created for that <item>. Accordingly,
# the gf script may run slowly for sites with a large number of
# existing posts. Tags will be created from each <category>.
rfork en
switch($1){
case 1oct1993_lj
feed=http://feeds.feedburner.com/Sl/1oct1993
site=1oct1993.com
tags=(rss)
case architecture
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6e361b590b57934fb1e7c4e29339d619&_render=rss'
site=read.stanleylieber.com
tags=(architecture)
case comics
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6bc617a6b20aafd526affafc9a28a5d5&_render=rss'
site=read.stanleylieber.com
tags=(comics)
case fg_lj
feed=http://feeds.feedburner.com/Sl/flamesgif
site=flamesgif.com
tags=(rss livejournal)
case inri_lj
feed=http://feeds.feedburner.com/Sl/itrecords
site=inri.net
tags=(rss livejournal)
case mf_lj
feed=http://feeds.feedburner.com/Sl/massivefictions
site=massivefictions.com
tags=(rss livejournal)
case other_lj
feed=http://feeds.feedburner.com/SL/other
site=other.stanleylieber.com
tags=()
case read
#feed=http://feeds.feedburner.com/SL/g/friends
#feed='http://pipes.yahoo.com/pipes/pipe.run?_id=f5d60acfd41497310d74900270192600&_render=rss'
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=d1f7146306b019d96d768facf95eebd9&_render=rss'
site=test.stanleylieber.com
tags=()
case sl_lj
feed=http://feeds.feedburner.com/ImNotReallyStanleyLieber
site=stanleylieber.com
tags=(rss livejournal)
case sl_tumblr
feed=http://stanleylieber.tumblr.com/rss
site=stanleylieber.com
tags=(rss tumblr)
case ta_lj
feed=http://feeds.feedburner.com/Sl/text_adventure
site=textadventure.stanleylieber.com
tags=(rss livejournal)
case tech
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6dd49be6e34a6871db9bcfc74d4b36b1&_render=rss'
site=read.stanleylieber.com
tags=(tech)
case *
echo 'Usage: gf [ ... ]' >[1=2]
exit usage
}
file=/tmp/gf.$1
werc=/usr/sl/www/werc
if(test -f /boot/factotum)
cmd=hget
if not
cmd='curl -s'
fn get_feed{
$"cmd $feed >$file.work
{
echo '
,s/ //g
,s/\&quot;/\"/g
,s/\&#34;/\"/g
,s/\&amp;/\&/g
,s/\&#38;/\&/g
,s/\&#39;/''/g
,s/\&#44;/,/g
,s/\&#45;/-/g
,s/\&#46;/\./g
,s/\&#47;/\//g
,s/\&#58;/:/g
,s/\&#59;/;/g
,s/\&lt;/</g
,s/\&#60;/</g
,s/\&#61;/=/g
,s/\&gt;/>/g
,s/\&#62;/>/g
,s/\&#95;/_/g
,s/\|/\&#124;/g
,s/\n//g
,s/<\/item>/\n<\/item>\n/g
,s/^<item>/<item>\n/g
,s/^[ ]*<guid/<guid/g
,s/^<[\/i].*$//g
,s/^[ ]*\n[ ]*$//g
x/<description>.*<\/description>/ s/\n//g
w
q
'
echo
} | sam -d $file.work >[2]/dev/null >[1=2]
awk '/(^<item>|<guid|<link>|<pubDate>|<title>|<description>|<comments>|<category>|<\/item>)/ {print $0;}' $file.work >$file
}
fn get_tags{
switch($a_link){
case *1oct1993*
tags=($tags 1oct1993)
case *9front*
tags=($tags software plan9 9front)
case *amyearles* *pushedunder* *seaglass* *woolandwater*
tags=($tags amy_earles)
case *animenewsnetwork*
tags=($tags telescreen anime)
case *spikejapan*
tags=($tags japan comics manga telescreen anime)
case *ArchDaily* *archdaily*
tags=($tags archdaily architecture)
case *bldgblog*
tags=($tags bldgblog architecture)
case *kazuyosejima*
tags=($tags japan architecture)
case *Minimalissimo*
tags=($tags minimalissimo design architecture)
case *ArtFagCity* *artfagcity*
tags=($tags artfagcity art)
case *rhizome-fp*
tags=($tags rhizome-fp art)
case *rhizome*
tags=($tags rhizome art)
case *starwarsmodern*
tags=($tags starwarsmodern art)
case *tokyoartbeat*
tags=($tags tokyoartbeat japan art)
case *trendbeheer*
tags=($tags trendbeheer art)
case *ValentinaTanni*
tags=($tags valentinatanni art)
case *vvork*
tags=($tags vwork art)
case *auriea* *tale-of-tales* *taleoftales*
tags=($tags auriea)
case *basscomm* *closeoutwarrior* *crummysocks* *gamerrelocationproject* *protipoftheday* *PushButtonB* *pushbuttonb*
tags=($tags video_games basscomm)
case *benjaminmarra*
tags=($tags comics benjamin_marra)
case *boingboing*
tags=($tags boingboing)
case *bushinbooks* *henka*
tags=($tags budo)
case *alexaanddave* *CEREBUS* *Cerebus* *cerebus* *davesim* *gerhard*
tags=($tags comics cerebus gerhard)
case *coilhouse*
tags=($tags coilhouse)
case *arche-arc*
tags=($tags arche comics)
case *blaiselarmee*
tags=($tags blaise_larmee comics)
case *bleedingcool*
tags=($tags bleedingcool comics)
case *bobgreenberger*
tags=($tags bob_greengerger comics)
case *coldheatcomics*
tags=($tags coldheat comics)
case *comicbookresources*
tags=($tags cbr comics)
case *comicsbeat*
tags=($tags comicsbeat comics)
case *ComicsComics* *comicscomics*
tags=($tags comicscomics comics)
case *coveredblog*
tags=($tags coveredblog comics)
case *dcfifty-too*
tags=($tags dcfifty-too comics)
case *Destructoid* *destructoid*
tags=($tags destructoid video_games)
case *economist.com*
tags=($tags economist)
case *ferrandelgado*
tags=($tags ferran_delgado comics)
case *eddiecampbell*
tags=($tags eddie_campbell comics)
case *factualopinion*
tags=($tags factualopinion comics)
case *floating_world* *floatingworld*
tags=($tags floating_world comics)
case *frankmiller*
tags=($tags frank_miller comics)
case *humancolor*
tags=($tags humancolor comics)
case *jerkcity*
tags=($tags jerkcity comics)
case *newconstructionblog*
tags=($tags newconstruction manga comics)
case *ohdannyboy*
tags=($tags ohdannyboy comics)
case *pulphope*
tags=($tags pulphope comics)
case *pwbeat*
tags=($tags pwbeat comics)
case *reliablecomics*
tags=($tags reliablecomics comics)
case *reneefrench*
tags=($tags renee_french comics)
case *rickveitch*
tags=($tags rick_veitch comics)
case *smbc-comics*
tags=($tags smbc comics)
case *studygroup*
tags=($tags studygroup comics)
case *xkcd*
tags=($tags xkcd comics)
case *bowiesongs* *DavidBowie* *davidbowie*
tags=($tags music david_bowie)
case *designboom*
tags=($tags designboom design)
case *dezeen*
tags=($tags dezeen design)
case *infosthetics*
tags=($tags infosthetics design)
case *inhabitat*
tags=($tags inhabitat architecture design)
case *luigicolani*
tags=($tags luigicolani design)
case *mocoloco*
tags=($tags mocoloco design)
case *sydmead*
tags=($tags sydmead design)
case *dzima*
tags=($tags dzima)
case *bbcicecream*
tags=($tags bbcicecream fashion)
case *DamStyle *damstyle*
tags=($tags damstyle fashion)
case *facehunter*
tags=($tags facehunter fashion)
case *StilInBerlin*
tags=($tags germany fashion)
case *jstreets*
tags=($tags jstreets japan fashion)
case *stylefromtokyo*
tags=($tags stylefromtokyo japan fashion)
case *tokyofashion*
tags=($tags tokyofashion japan fashion)
case *flames.gif* *flamesgif*
tags=($tags flames.gif)
case *contemporary-home-computing*
tags=($tags software flames.gif)
case *kurzweil*
tags=($tags kurzweil future)
case *longnow*
tags=($tags longnow future)
case *OpenTheFuture*
tags=($tags openthefuture future)
case *golang* *blog.nella.org*
tags=($tags golang)
case *googlepluses*
tags=($tags google)
case *news.ycombinator.com*
tags=($tags hackernews hack)
case *seanbonner*
tags=($tags sean_bonner hack)
case *banriman*
tags=($tags banriman japan)
case *japansubculture*
tags=($tags japansubculture japan)
case *jeansnow*
tags=($tags jeansnow japan)
case *Kotaku* *kotaku*
tags=($tags kotaku video_games)
case *eforemario*
tags=($tags before_mario video_games)
case *nakakobooks*
tags=($tags books nakakobooks japan)
case *ozawamaria*
tags=($tags maria_ozawa japan)
case *shisaku.blogspot.com*
tags=($tags shisaku japan)
case *jimshooter*
tags=($tags comics jim_shooter)
case *LettersOfNote* *lettersofnote*
tags=($tags letters)
case *nasa*letters.rss*
tags=($tags nasa letters)
case *hellodamage* *manganews* *naokiurasawa* *samehat*
tags=($tags comics manga)
case *mangatraders*
tags=($tags p2p comics manga)
case *hortonheardawho*
tags=($tags hortonheardawho flickr nasa mars)
case *me-vs-gutenberg* *mevsgutenberg*
tags=($tags martin_sand)
case *marxy*
tags=($tags marxy)
case *etamodern*
tags=($tags metamodern)
case *aviationintel*
tags=($tags aviationintel mil)
case *aviationweek*
tags=($tags aviationweek mil)
case *codeonemagazine*
tags=($tags codeonemagazine mil)
case *geimint*
tags=($tags geimint mil)
case *momus* *mrstsk*
tags=($tags books music momus)
case *bjork* *toog*
tags=($tags music)
case *nasa.gov*
tags=($tags space nasa)
case *mongoliad*
tags=($tags neal_stephenson)
case *gaiman*
tags=($tags comics neil_gaiman)
case *nin.com* *feeds.nin.com*
tags=($tags music nin)
case *nix-os* *syssoftware*
tags=($tags plan9 nix)
case *bsdly* *OPENBSD* *OpenBSD* *openbsd* *scientist-home* *undeadly*
tags=($tags software openbsd)
case *godownmatthew* *mysticmilk* *petetoms*
tags=($tags pete_toms)
case *Pitchfork* *pitchfork*
tags=($tags music pitchfork)
case *9gridchan* *cat-v* *maht0x0r* *Plan9* *plan9*
tags=($tags software plan9)
case *FlauntTalks* *prince.org* *purpleinterviews* *wendyandlisa*
tags=($tags music prince)
case *commandcenter* *rob_pike*
tags=($tags golang plan9 rob_pike)
case *prometheus*
tags=($tags telescreen prometheus)
case *reddit.com*
tags=($tags reddit)
case *swtch.com*
tags=($tags golang plan9 rsc)
case *bunniestudios*
tags=($tags bunniestudios security)
case *jwz*
tags=($tags jwz security)
case *Krebs* *krebs*
tags=($tags krebs security)
case *scarybeastsecurity*
tags=($tags scarybeast security)
case *schneier*
tags=($tags bruce_schneier security)
case *chinchillakwak* *skwak*
tags=($tags skwak)
case *slashdot*
tags=($tags slashdot)
case *stanleylieber*
tags=($tags stanleylieber)
case *fastcompany*
tags=($tags fastcompany tech)
case *danharmon*
tags=($tags danharmon telescreen)
case *mindlessones*
tags=($tags mindlessones telescreen)
case *tcj.com*
tags=($tags comics tcj)
case *TEDblog* *ted.com*
tags=($tags ted)
case *ticom*
tags=($tags ticom security)
case *orrentfreak*
tags=($tags p2p torrentfreak)
case *ultra*culture*
tags=($tags ultraculture)
case *kleinletters*
tags=($tags comics todd_klein)
case *plaidstallions*
tags=($tags plaidstallions toys)
case *shojikawamori*
tags=($tags shojikawamori japan toys)
}
echo -n $tags
}
fn parse_posts{
ifs='
' {
posts=`{cat $file}
for(i in `{seq 1 $#posts | sort -nr}){
post=`{echo $posts($i) | sed 's/> </>\n</g' | grep -v -e '<comments>'}
if(! ~ $post ''){
a_title=`{echo $post | grep -e 'title>' | sed 's/^.*<title>//g; s/<\/title>.*$//g'}
a_date=`{echo $post | grep -e '<pubDate>' | sed 's/^.*<pubDate>//g; s/<\/pubDate>.*$//g'}
a_link=`{echo $post | grep -e '<link>' | sed 's/^.*<link>//g; s/<\/link>.*$//g; s/^.*http/http/g'}
a_tags=`{echo $post | grep -e '<category>' | sed 's/^.*<\/comments>//g; s/^.*<description>//g; s/^.*<\/description>//g; s/^.*<\/pubDate>//g; s/<category>/ /g; s/<\/category>//g; s/<dc.*$//g; s/^ //g; s/ $//g'}
a_tags=`{for(j in $a_tags){ echo $j | sed 's/^.*(<|>).*$//g'}}
a_body=`{echo $post | grep -e '<description>' | sed 's/^.*<description>//g; s/<\/description>.*$//g'}
a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $werc/sites/$site/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
if(! ~ $"a_link '' && ! ~ $"a_link `{cat $werc/sites/$site/src/*/link}){
mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
echo $"a_title >$werc/sites/$site/src/$a_id/title
echo $"a_date >$werc/sites/$site/src/$a_id/date
echo $"a_link >$werc/sites/$site/src/$a_id/link
echo $"a_body '</a></li></ul>' >$werc/sites/$site/src/$a_id/body
ifs=' ' {
for(j in `{get_tags}){
>$werc/sites/$site/src/$a_id/tags/$j
echo $a_id/tags/$j >>$werc/sites/$site/tags
}
}
}
if(test -f /boot/factotum && ~ $site *.stanleylieber.com)
for(i in `{f $werc/sites/$site/src/$a_id})
chmod +t $i
}
}
}
}
if(test -f /boot/factotum && test -f /rc/bin/hget)
webfs
get_feed
parse_posts

20
werc/apps/barf/bin/gk Executable file
View file

@ -0,0 +1,20 @@
#!/bin/rc
# Create an index of known_tags in $werc/sites/$site/known_tags
if(! ~ $#1 0)
base=$1
if not if(~ $#barf_root 1 && $#barf_base 1)
base=$barf_root/$"barf_base
if not
base=`{pwd}
if(test -f $base/_known_tags)
rm $base/_known_tags
for(i in `{cat $base/etc/tags}){
grep -e '^.*\/'$i'$' $base/tags |
awk -F '/' '{print $3;}' |
sort |
uniq -c |
awk '{print $2 " " $1;}' >>$base/_known_tags
}
if(test -f $base/_known_tags)
cp $base/_known_tags $base/known_tags

415
werc/apps/barf/bin/gr Executable file
View file

@ -0,0 +1,415 @@
#!/bin/rc
# Parse RSS feeds from Google Reader bundles into BULGE blog posts.
# If a post with a matching <link> already exists, no new post will
# be created for that <item>. Accordingly, the gr script may run
# slowly for sites with a large number of existing posts. Tags will
# be created from each <category>.
rfork en
switch($1){
case architecture
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6e361b590b57934fb1e7c4e29339d619&_render=rss'
site=read.stanleylieber.com
tags=(architecture)
case comics
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6bc617a6b20aafd526affafc9a28a5d5&_render=rss'
site=read.stanleylieber.com
tags=(comics)
case friends
feed='https://www.google.com/reader/bundle/user%2F08193524211692385241%2Fbundle%2Ffriends'
site=read.stanleylieber.com
tags=(friends)
case tech
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6dd49be6e34a6871db9bcfc74d4b36b1&_render=rss'
site=read.stanleylieber.com
tags=(tech)
case *
echo usage: `{basename $0} '[ ... ]' >[1=2]
exit usage
}
file=/tmp/gr.$1
werc=/usr/sl/www/werc
if(test -f /boot/factotum)
cmd=hget
if not
cmd='curl -s'
fn f{ du -a $* | sed 's/^.* //g' }
fn get_feed{
$"cmd $feed >$file.work
{
echo '
,s/\&quot;/\"/g
,s/\&#34;/\"/g
,s/\&amp;/\&/g
,s/\&#38;/\&/g
,s/\&#39;/\''/g
,s/\&#44;/,/g
,s/\&#45;/-/g
,s/\&#46;/\./g
,s/\&#47;/\//g
,s/\&#58;/:/g
,s/\&#59;/;/g
,s/\&lt;/</g
,s/\&#60;/</g
,s/\&#61;/=/g
,s/\&gt;/>/g
,s/\&#62;/>/g
,s/\&#95;/_/g
,s/\|/\&#124;/g
,/<div id="items">/d
/<div id="sidebar">/,d
,s/<h2 class="item-title">/\n<h2 class="item-title">/g
,s/<div class="item">.*$/HJDIVIDER/g
,s/\n//g
,s/HJDIVIDER/\n/g
1d
w
q
'
echo
} | sam -d $file.work >[2]/dev/null >[1=2]
}
fn get_tags{
switch($a_link){
case *1oct1993*
tags=($tags 1oct1993)
case *9front*
tags=($tags software plan9 9front)
case *amyearles* *pushedunder* *seaglass* *woolandwater*
tags=($tags amy_earles)
case *animenewsnetwork*
tags=($tags telescreen anime)
case *spikejapan*
tags=($tags japan comics manga telescreen anime)
case *ArchDaily* *archdaily*
tags=($tags archdaily architecture)
case *bldgblog*
tags=($tags bldgblog architecture)
case *kazuyosejima*
tags=($tags japan architecture)
case *Minimalissimo*
tags=($tags minimalissimo design architecture)
case *ArtFCity* *ArtFagCity* *artfagcity*
tags=($tags artfagcity art)
case *rhizome-fp*
tags=($tags rhizome-fp art)
case *rhizome*
tags=($tags rhizome art)
case *starwarsmodern*
tags=($tags starwarsmodern art)
case *tokyoartbeat*
tags=($tags tokyoartbeat japan art)
case *trendbeheer*
tags=($tags trendbeheer art)
case *ValentinaTanni*
tags=($tags valentinatanni art)
case *vvork*
tags=($tags vwork art)
case *auriea* *tale-of-tales* *taleoftales*
tags=($tags auriea)
case *basscomm* *closeoutwarrior* *crummysocks* *gamerrelocationproject* *protipoftheday* *PushButtonB* *pushbuttonb*
tags=($tags video_games basscomm)
case *benjaminmarra*
tags=($tags comics benjamin_marra)
case *boingboing*
tags=($tags boingboing)
case *bushinbooks* *henka*
tags=($tags budo)
case *alexaanddave* *CEREBUS* *Cerebus* *cerebus* *davesim* *gerhard*
tags=($tags comics cerebus gerhard)
case *coilhouse*
tags=($tags coilhouse)
case *arche-arc*
tags=($tags arche comics)
case *blaiselarmee*
tags=($tags blaise_larmee comics)
case *bleedingcool*
tags=($tags bleedingcool comics)
case *bobgreenberger*
tags=($tags bob_greengerger comics)
case *coldheatcomics*
tags=($tags coldheat comics)
case *comicbookresources*
tags=($tags cbr comics)
case *comicsbeat*
tags=($tags comicsbeat comics)
case *ComicsComics* *comicscomics*
tags=($tags comicscomics comics)
case *coveredblog*
tags=($tags coveredblog comics)
case *dcfifty-too*
tags=($tags dcfifty-too comics)
case *Destructoid* *destructoid*
tags=($tags destructoid video_games)
case *economist.com*
tags=($tags economist)
case *ferrandelgado*
tags=($tags ferran_delgado comics)
case *eddiecampbell*
tags=($tags eddie_campbell comics)
case *factualopinion*
tags=($tags factualopinion comics)
case *floating_world* *floatingworld*
tags=($tags floating_world comics)
case *frankmiller*
tags=($tags frank_miller comics)
case *humancolor*
tags=($tags humancolor comics)
case *jerkcity*
tags=($tags jerkcity comics)
case *newconstructionblog*
tags=($tags newconstruction manga comics)
case *ohdannyboy*
tags=($tags ohdannyboy comics)
case *pulphope*
tags=($tags pulphope comics)
case *pwbeat*
tags=($tags pwbeat comics)
case *reliablecomics*
tags=($tags reliablecomics comics)
case *reneefrench*
tags=($tags renee_french comics)
case *rickveitch*
tags=($tags rick_veitch comics)
case *smbc-comics*
tags=($tags smbc comics)
case *studygroup*
tags=($tags studygroup comics)
case *xkcd*
tags=($tags xkcd comics)
case *bowiesongs* *DavidBowie* *davidbowie*
tags=($tags music david_bowie)
case *designboom*
tags=($tags designboom design)
case *dezeen*
tags=($tags dezeen design)
case *infosthetics*
tags=($tags infosthetics design)
case *inhabitat*
tags=($tags inhabitat architecture design)
case *luigicolani*
tags=($tags luigicolani design)
case *mocoloco*
tags=($tags mocoloco design)
case *sydmead*
tags=($tags sydmead design)
case *dzima*
tags=($tags dzima)
case *bbcicecream*
tags=($tags bbcicecream fashion)
case *DamStyle *damstyle*
tags=($tags damstyle fashion)
case *facehunter*
tags=($tags facehunter fashion)
case *StilInBerlin*
tags=($tags germany fashion)
case *jstreets*
tags=($tags jstreets japan fashion)
case *Stilinberlin*
tags=($tags stilinberlin germany fashion)
case *stylefromtokyo*
tags=($tags stylefromtokyo japan fashion)
case *tokyofashion*
tags=($tags tokyofashion japan fashion)
case *flames.gif* *flamesgif*
tags=($tags flames.gif)
case *contemporary-home-computing*
tags=($tags software flames.gif)
case *kurzweil*
tags=($tags kurzweil future)
case *longnow*
tags=($tags longnow future)
case *OpenTheFuture*
tags=($tags openthefuture future)
case *golang* *blog.nella.org*
tags=($tags golang)
case *googlepluses*
tags=($tags google)
case *news.ycombinator.com*
tags=($tags hackernews hack)
case *seanbonner*
tags=($tags sean_bonner hack)
case *banriman*
tags=($tags banriman japan)
case *japansubculture*
tags=($tags japansubculture japan)
case *jeansnow*
tags=($tags jeansnow japan)
case *Kotaku* *kotaku*
tags=($tags kotaku video_games)
case *eforemario*
tags=($tags before_mario video_games)
case *nakakobooks*
tags=($tags books nakakobooks japan)
case *ozawamaria*
tags=($tags maria_ozawa japan)
case *ibuya246*
tags=($tags shibuya246 japan)
case *shisaku.blogspot.com*
tags=($tags shisaku japan)
case *jimshooter*
tags=($tags comics jim_shooter)
case *LettersOfNote* *lettersofnote*
tags=($tags letters)
case *nasa*letters.rss*
tags=($tags nasa letters)
case *hellodamage* *manganews* *naokiurasawa* *samehat*
tags=($tags comics manga)
case *mangatraders*
tags=($tags p2p comics manga)
case *hortonheardawho*
tags=($tags hortonheardawho flickr nasa mars)
case *me-vs-gutenberg* *mevsgutenberg*
tags=($tags martin_sand)
case *marxy*
tags=($tags marxy)
case *etamodern*
tags=($tags metamodern)
case *aviationintel*
tags=($tags aviationintel mil)
case *aviationweek*
tags=($tags aviationweek mil)
case *codeonemagazine*
tags=($tags codeonemagazine mil)
case *geimint*
tags=($tags geimint mil)
case *bjork*
tags=($tags bjork music)
case *momus* *mrstsk*
tags=($tags books momus music)
case *toog*
tags=($tags toog music)
case *nasa.gov*
tags=($tags space nasa)
case *mongoliad*
tags=($tags neal_stephenson)
case *gaiman*
tags=($tags comics neil_gaiman)
case *nin.com* *feeds.nin.com*
tags=($tags music nin)
case *nix-os* *syssoftware*
tags=($tags plan9 nix)
case *bsdly* *OPENBSD* *OpenBSD* *openbsd* *scientist-home* *undeadly*
tags=($tags software openbsd)
case *godownmatthew* *mysticmilk* *petetoms*
tags=($tags pete_toms)
case *Pitchfork* *pitchfork*
tags=($tags music pitchfork)
case *9gridchan* *cat-v* *maht0x0r* *Plan9* *plan9*
tags=($tags software plan9)
case *FlauntTalks* *prince.org* *purpleinterviews* *wendyandlisa*
tags=($tags music prince)
case *commandcenter* *rob_pike*
tags=($tags golang plan9 rob_pike)
case *prometheus*
tags=($tags telescreen prometheus)
case *reddit.com*
tags=($tags reddit)
case *swtch.com*
tags=($tags golang plan9 rsc)
case *bunniestudios*
tags=($tags bunniestudios security)
case *jwz*
tags=($tags jwz security)
case *Krebs* *krebs*
tags=($tags krebs security)
case *scarybeastsecurity*
tags=($tags scarybeast security)
case *schneier*
tags=($tags bruce_schneier security)
case *chinchillakwak* *skwak*
tags=($tags skwak)
case *slashdot*
tags=($tags slashdot)
case *stanleylieber*
tags=($tags stanleylieber)
case *fastcompany*
tags=($tags fastcompany tech)
case *danharmon*
tags=($tags danharmon telescreen)
case *mindlessones*
tags=($tags mindlessones telescreen)
case *tcj.com*
tags=($tags comics tcj)
case *TEDblog* *ted.com*
tags=($tags ted)
case *ticom*
tags=($tags ticom security)
case *orrentfreak*
tags=($tags p2p torrentfreak)
case *ultra*culture*
tags=($tags ultraculture)
case *kleinletters*
tags=($tags comics todd_klein)
case *kennercollector*
tags=($tags kennercollector toys)
case *plaidstallions*
tags=($tags plaidstallions toys)
case *shojikawamori*
tags=($tags shojikawamori japan toys)
case *ruinedcartridge*
tags=($tags basscomm video_games)
}
echo -n $tags
}
fn parse_posts{
ifs='
' {
for(post in `{sort -r $file.work}){
if(! ~ $post ''){
a_title=`{echo $post | sed 's/^.*<h2 class="item-title"><div class="">//g' | sed 's/<div class="item-info">.*$//g' | htmlfmt}
if(~ $#a_title 0)
a_title=`{echo $post | sed 's/^.*<div class="item-info">//g' | sed 's/<div class="item-annotations">.*$//g' | htmlfmt}
if(~ $#a_title 0)
a_title=fake
a_link=`{echo $post | sed 's/^.*<h2 class="item-title"><div class="">//g' | sed 's/<div class="item-info">.*$//g' | htmlfmt -a | sed 's/^.*\[//g' | sed 's/\].*$//g' | sed 's/ .*$//g'}
if(~ $#a_link 0 || ! ~ $"a_link http*)
a_link=`{echo $post | sed 's/^.*<h2 class="item-title"><div class="">//g' | sed 's/<div class="item-info">.*$//g' | sed 's/^.*<a href="//g' | sed 's/\".*$//g' | sed 's/^.*http/http/g' | sed 's/ .*$//g'}
if(~ $#a_link 0 || ! ~ $"a_link http*)
a_link=`{echo $post | sed 's/^.*<div class="item-info">//g' | sed 's/<div class="item-annotations">.*$//g' | htmlfmt -a | sed 's/^.*\[//g' | sed 's/\].*$//g' | sed 's/ .*$//g'}
if(~ $#a_link 0 || ! ~ $"a_link http*)
a_link=`{echo $post | sed 's/^.*<div class="item-info">//g' | sed 's/<div class="item-annotations">.*$//g' | sed 's/^.*<a href="//g' | sed 's/" class="f">.*$//g' | sed 's/\".*$//g' | sed 's/^.*http/http/g' | sed 's/ .*$//g'}
a_link=$a_link(1)
if(~ $#a_link 0 || ~ $"a_link '' || ! ~ $"a_link http*)
a_link=fake
if(! ~ $#a_link 1)
a_link=`{echo $a_link | awk '{print $1;}'}
a_date=`{date -n}
a_body=`{echo $post | sed 's/^.*<div class="item-body">//g' | sed 's/<div class="clear">.*$//g'}
if(~ $#a_body 0)
a_body=fake
a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $werc/sites/$site/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
if(! ~ $"a_link `{cat $werc/sites/$site/src/*/link}){
mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
echo $"a_title >$werc/sites/$site/src/$a_id/title
echo $"a_date >$werc/sites/$site/src/$a_id/date
echo $"a_link >$werc/sites/$site/src/$a_id/link
echo $"a_body '</a></li></ul>' >$werc/sites/$site/src/$a_id/body
ifs=' ' {
for(j in `{get_tags}){
>$werc/sites/$site/src/$a_id/tags/$j
echo $a_id/tags/$j >>$werc/sites/$site/tags
}
}
}
if(test -f /boot/factotum)
for(i in `{f $werc/sites/$site/src/$a_id})
chmod +t $i
}
}
}
}
if(test -f /boot/factotum && test -f /rc/bin/hget)
webfs
get_feed
parse_posts

23
werc/apps/barf/bin/gt Executable file
View file

@ -0,0 +1,23 @@
#!/bin/rc
# Create an index of tags in $werc/sites/$site/tags. BULGE
# greps this index when running a search on a given tag.
# This file is also maintained by the bin/g* commands, or
# when adding posts through the web interface.
if(! ~ $#1 0)
base=$1
if not if(~ $#barf_root 1 && $#barf_base 1)
base=$barf_root/$"barf_base
if not
base=`{pwd}
if(test -f $base/_tags)
rm $base/_tags
builtin cd $base/src
ls -p |
sort -n |
xargs du -a |
sed 's/^.* //g' |
grep -e '^[0-9]*\/tags' |
grep -v -e '^.*\/tags$' >>$base/_tags
if(test -s $base/_tags)
cp $base/_tags $base/tags

455
werc/apps/barf/bin/gy Executable file
View file

@ -0,0 +1,455 @@
#!/bin/rc
# Parse XML RSS feeds from Yahoo Pipes into BARF blog posts
# for the specified site. If a post with a matching _link_ already
# exists, no new post will be created for that item. Accordingly,
# the gy script may run slowly for sites with a large number of
# existing posts. Tags will be created according to the rules
# defined in the get_tags() function.
#
# Requires 20h's xmlpull and rssread.
rfork en
switch($1){
case read
feed='http://pipes.yahoo.com/pipes/pipe.run?_id=d1f7146306b019d96d768facf95eebd9&_render=rss'
site=read.stanleylieber.com
tags=()
case *
echo 'Usage: gy [ ... ]' >[1=2]
exit usage
}
file=/tmp/gy.$1
werc=/usr/sl/www/werc
if(test -f /boot/factotum)
cmd=hget
if not
cmd='curl -s'
fn cram{
ssam '
,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
,s/\n//g
,s/HJDIVIDERtitle:/\n&/g
'
}
fn scape{
ssam '
,s/ //g
,s/\&quot;/\"/g
,s/\&#34;/\"/g
,s/\&amp;/\&/g
,s/\&#38;/\&/g
,s/\&#39;/''/g
,s/\&#44;/,/g
,s/\&#45;/-/g
,s/\&#46;/\./g
,s/\&#47;/\//g
,s/\&#58;/:/g
,s/\&#59;/;/g
,s/\&lt;/</g
,s/\&#60;/</g
,s/\&#61;/=/g
,s/\&gt;/>/g
,s/\&#62;/>/g
,s/\&#95;/_/g
,s/\|/\&#124;/g
'
}
fn get_posts{
$"cmd $feed | rssread | cram | scape >$file
echo >>$file
}
fn get_tags{
switch($a_link){
case *1oct1993*
tags=($tags 1oct1993)
case *9front*
tags=($tags software plan9 9front)
case *organicmentalcore*
tags=($tags aleks)
case *amyearles* *etsy.com* *pushedunder* *seaglass* *woolandwater*
tags=($tags amy_earles)
case *animenewsnetwork*
tags=($tags telescreen anime)
case *spikejapan*
tags=($tags japan comics manga telescreen anime)
case *augmented.org*
tags=($tags augmented.org ar)
case *ArchDaily* *archdaily*
tags=($tags archdaily architecture)
case *bldgblog*
tags=($tags bldgblog architecture)
case *kazuyosejima*
tags=($tags japan architecture)
case *Minimalissimo*
tags=($tags minimalissimo design architecture)
case *ArtFagCity* *ArtFCity* *artfagcity*
tags=($tags artfagcity art)
case *rhizome-fp*
tags=($tags rhizome-fp art)
case *rhizome*
tags=($tags rhizome art)
case *starwarsmodern*
tags=($tags starwarsmodern art)
case *tokyoartbeat*
tags=($tags tokyoartbeat japan art)
case *trendbeheer*
tags=($tags trendbeheer art)
case *ValentinaTanni*
tags=($tags valentinatanni art)
case *vvork*
tags=($tags vwork art)
case *auriea* *tale-of-tales* *taleoftales*
tags=($tags auriea)
case *basscomm* *closeoutwarrior* *crummysocks* *gamerrelocationproject* *protipoftheday* *PushButtonB* *pushbuttonb*
tags=($tags video_games basscomm)
case *benjaminmarra*
tags=($tags comics benjamin_marra)
case *boingboing*
tags=($tags boingboing)
case *bushinbooks* *henka*
tags=($tags budo)
case *alexaanddave* *CEREBUS* *Cerebus* *cerebus* *davesim* *gerhard*
tags=($tags comics cerebus gerhard)
case *coilhouse*
tags=($tags coilhouse)
case *arche-arc*
tags=($tags arche comics)
case *bitolithic.com*
tags=($tags bitolithic comics)
case *blaiselarmee*
tags=($tags blaise_larmee comics)
case *bleedingcool*
tags=($tags bleedingcool comics)
case *bobgreenberger*
tags=($tags bob_greengerger comics)
case *coldheatcomics*
tags=($tags coldheat comics)
case *comicbookresources*
tags=($tags cbr comics)
case *comicsbeat*
tags=($tags comicsbeat comics)
case *ComicsComics* *comicscomics*
tags=($tags comicscomics comics)
case *coveredblog*
tags=($tags coveredblog comics)
case *dcfifty-too*
tags=($tags dcfifty-too comics)
case *Destructoid* *destructoid*
tags=($tags destructoid video_games)
case *economist.com*
tags=($tags economist)
case *brucesterling.tumblr.com*
tags=($tags bruce_sterling)
case *thecreatorsproject*
tags=($tags thecreatorsproject)
case *ferrandelgado*
tags=($tags ferran_delgado comics)
case *eddiecampbell*
tags=($tags eddie_campbell comics)
case *factualopinion*
tags=($tags factualopinion comics)
case *floating_world* *floatingworld*
tags=($tags floating_world comics)
case *frankmiller*
tags=($tags frank_miller comics)
case *humancolor*
tags=($tags humancolor comics)
case *jerkcity*
tags=($tags jerkcity comics)
case *maakies.com*
tags=($tags tony_millionaire maakies comics)
case *newconstructionblog*
tags=($tags newconstruction manga comics)
case *ohdannyboy*
tags=($tags ohdannyboy comics)
case *pulphope*
tags=($tags pulphope comics)
case *pwbeat*
tags=($tags pwbeat comics)
case *reliablecomics*
tags=($tags reliablecomics comics)
case *reneefrench*
tags=($tags renee_french comics)
case *rickveitch*
tags=($tags rick_veitch comics)
case *royalboiler*
tags=($tags royalboiler comics)
case *smbc-comics*
tags=($tags smbc comics)
case *studygroup*
tags=($tags studygroup comics)
case *xkcd*
tags=($tags xkcd comics)
case *bowiesongs* *DavidBowie* *davidbowie*
tags=($tags music david_bowie)
case *designboom*
tags=($tags designboom design)
case *dezeen*
tags=($tags dezeen design)
case *infosthetics*
tags=($tags infosthetics design)
case *inhabitat*
tags=($tags inhabitat architecture design)
case *luigicolani*
tags=($tags luigicolani design)
case *mocoloco*
tags=($tags mocoloco design)
case *sydmead*
tags=($tags sydmead design)
case *dzima*
tags=($tags dzima)
case *bbcicecream*
tags=($tags bbcicecream fashion)
case *DamStyle *damstyle*
tags=($tags damstyle fashion)
case *facehunter*
tags=($tags facehunter fashion)
case *StilInBerlin* *Stilinberlin*
tags=($tags germany fashion)
case *jstreets*
tags=($tags jstreets japan fashion)
case *stylefromtokyo*
tags=($tags stylefromtokyo japan fashion)
case *tokyofashion*
tags=($tags tokyofashion japan fashion)
case *flames.gif* *flamesgif*
tags=($tags flames.gif)
case *contemporary-home-computing*
tags=($tags software flames.gif)
case *acceler8or.com*
tags=($tags acceler8or future)
case *afrocyberpunk.wordpress.com*
tags=($tags afrocyberpunk future)
case *hyperallergic.com*
tags=($tags hyperallergic future)
case *kurzweil*
tags=($tags kurzweil future)
case *longnow*
tags=($tags longnow future)
case *OpenTheFuture*
tags=($tags openthefuture future)
case *theverge.com*
tags=($tags theverge future)
case *golang* *blog.nella.org*
tags=($tags golang)
case *googlepluses*
tags=($tags google)
case *news.ycombinator.com*
tags=($tags hackernews hack)
case *seanbonner*
tags=($tags sean_bonner hack)
case *banriman*
tags=($tags banriman japan)
case *japansubculture*
tags=($tags japansubculture japan)
case *jeansnow*
tags=($tags jeansnow japan)
case *Kotaku* *kotaku*
tags=($tags kotaku video_games)
case *eforemario*
tags=($tags before_mario video_games)
case *instagram* *web.stagram.com*
tags=($tags instagram)
case *nakakobooks*
tags=($tags books nakakobooks japan)
case *ozawamaria*
tags=($tags maria_ozawa japan)
case *Shibuya246*
tags=($tags shibuya246 japan)
case *shisaku.blogspot.com*
tags=($tags shisaku japan)
case *jimshooter*
tags=($tags comics jim_shooter)
case *LettersOfNote* *lettersofnote*
tags=($tags letters)
case *nasa*letters.rss*
tags=($tags nasa letters)
case *kore.livejournal.com*
tags=($tags kore livejournal)
case *real-funny-lady.livejournal.com*
tags=($tags rea_funny_lady livejournal)
case *vintage-ads.livejournal.com*
tags=($tags vintage_ads livejournal)
case *hellodamage*
tags=($tags comics hellodamage manga)
case *manganews*
tags=($tags comics manganews manga)
case *naokiurasawa*
tags=($tags comics naokiurasawa manga)
case *samehat*
tags=($tags comics samehat manga)
case *mangatraders*
tags=($tags p2p comics manga)
case *hortonheardawho*
tags=($tags hortonheardawho flickr nasa mars)
case *marstoday.com*
tags=($tags marstoday mars)
case *kielbryant*
tags=($tags kiel_bryant flickr)
case *flickr*paoru*
tags=($tags paoru flickr)
case *me-vs-gutenberg* *mevsgutenberg*
tags=($tags martin_sand)
case *marxy*
tags=($tags marxy)
case *etamodern*
tags=($tags metamodern)
case *aviationintel*
tags=($tags aviationintel mil)
case *aviationweek*
tags=($tags aviationweek mil)
case *codeonemagazine*
tags=($tags codeonemagazine mil)
case *geimint*
tags=($tags geimint mil)
case *momus* *mrstsk*
tags=($tags books music momus)
case *bjork*
tags=($tags bjork music)
case *c-h-r-i-s-c-a-r-t-e-r*
tags=($tags chris_carter music)
case *toog*
tags=($tags toog music)
case *nasa.gov*
tags=($tags space nasa)
case *mongoliad*
tags=($tags neal_stephenson)
case *gaiman*
tags=($tags comics neil_gaiman)
case *111567547782666546187*
tags=($tags daniel_rehn gplus)
case *114408853762245370512*
tags=($tags francesco_cardi gplus)
case *106673611724400311137*
tags=($tags mark_jondahl gplus)
case *113974084460235989118*
tags=($tags jose_nazario gplus)
case *102089697005520721324*
tags=($tags zaki_hasan gplus)
case *nin.com* *feeds.nin.com*
tags=($tags music nin.com nin)
case *ninofficialnews.tumblr.com*
tags=($tags music tumblr nin)
case *nix-os* *syssoftware*
tags=($tags plan9 nix)
case *bsdly* *OPENBSD* *OpenBSD* *openbsd* *scientist-home* *undeadly*
tags=($tags software openbsd)
case *godownmatthew* *mysticmilk* *petetoms*
tags=($tags pete_toms)
case *Pitchfork* *pitchfork*
tags=($tags music pitchfork)
case *9gridchan* *cat-v* *maht0x0r* *Plan9* *plan9*
tags=($tags software plan9)
case *FlauntTalks* *prince.org* *purpleinterviews* *wendyandlisa*
tags=($tags music prince)
case *101960720994009339267*
tags=($tags gplus rob_pike)
case *commandcenter* *rob_pike*
tags=($tags blogger rob_pike)
case *prometheus*
tags=($tags telescreen prometheus)
case *reddit.com*
tags=($tags reddit)
case *swtch.com*
tags=($tags golang plan9 rsc)
case *bunniestudios*
tags=($tags bunniestudios security)
case *jwz*
tags=($tags jwz security)
case *Krebs* *krebs*
tags=($tags krebs security)
case *scarybeastsecurity*
tags=($tags scarybeast security)
case *schneier*
tags=($tags bruce_schneier security)
case *chinchillakwak* *skwak*
tags=($tags skwak)
case *slashdot*
tags=($tags slashdot)
case *spaceref.com*
tags=($tags space spaceref)
case *StanleyLieber* *stanleylieber*
tags=($tags stanleylieber)
case *fastcompany*
tags=($tags fastcompany tech)
case *gizchina.com*
tags=($tags gizchina tech)
case *danharmon*
tags=($tags danharmon telescreen)
case *mindlessones*
tags=($tags mindlessones telescreen)
case *tcj.com*
tags=($tags comics tcj)
case *TEDBlog* *TEDblog* *ted.com*
tags=($tags ted)
case *ticom*
tags=($tags ticom security)
case *orrentfreak*
tags=($tags p2p torrentfreak)
case *ultra*culture*
tags=($tags ultraculture)
case *kleinletters*
tags=($tags comics todd_klein)
case *collectiondx.com*
tags=($tags collectiondx toys)
case *kennercollector.com*
tags=($tags kennercollector toys)
case *plaidstallions*
tags=($tags plaidstallions toys)
case *shojikawamori*
tags=($tags shojikawamori japan toys)
case *tumblr*
tags=($tags tumblr)
case *ruinedcartridge*
tags=($tags ruinedcartridge basscomm video_games)
}
echo -n $tags
}
fn parse_posts{
ifs='
' {
posts=`{cat $file}
for(i in `{seq 1 $#posts | sort -nr}){
post=$posts($i)
if(! ~ $post ''){
a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
a_date=`{date}
a_link=`{echo $post | sed 's/^.*HJDIVIDERlink: //g; s/HJDIVIDER.*$//g'}
a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $werc/sites/$site/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
echo $"a_title >$werc/sites/$site/src/$a_id/title
echo $"a_date >$werc/sites/$site/src/$a_id/date
echo $a_link(1) >$werc/sites/$site/src/$a_id/link
echo $a_link(1) | md5sum >>$werc/sites/$site/links
echo $"a_body '</a></li></ul>' >$werc/sites/$site/src/$a_id/body
ifs=' ' {
for(j in `{get_tags}){
>$werc/sites/$site/src/$a_id/tags/$j
echo $a_id/tags/$j >>$werc/sites/$site/tags
}
}
}
if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
}
}
}
}
if(test -f /boot/factotum && test -f /rc/bin/hget)
webfs
get_posts
parse_posts

119
werc/apps/barf/bin/gz Executable file
View file

@ -0,0 +1,119 @@
#!/bin/rc
# Parse XML RSS feeds into BARF blog posts for the specified site.
# If a post with a matching _link_ already exists, no new post will
# be created for that item. Tags will be created according to the rules
# defined in the get_tags() function.
#
# The file argument should point to a file containing one line per feed,
# with fields separated by the | character, in the following format:
#
# http://feeds.feedburner.com/ImNotReallyStanleyLieber|stanleylieber
#
# where the first field is the feed URL and each addition field is a tag.
#
# Requires 20h's xmlpull and rssread.
rfork en
switch($1){
case /*
feeds=$1
site=read.stanleylieber.com
tags=()
case *
echo 'Usage: gz file' >[1=2]
exit usage
}
file=/tmp/gz.$pid
werc=/usr/sl/www/werc
if(test -f /boot/factotum)
cmd=hget
if not
cmd='curl -s'
fn cram{
ssam '
,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
,s/\n//g
,s/HJDIVIDERtitle:/\n&/g
'
}
fn scape{
ssam '
,s/ //g
,s/\&quot;/\"/g
,s/\&#34;/\"/g
,s/\&amp;/\&/g
,s/\&#38;/\&/g
,s/\&#39;/''/g
,s/\&#44;/,/g
,s/\&#45;/-/g
,s/\&#46;/\./g
,s/\&#47;/\//g
,s/\&#58;/:/g
,s/\&#59;/;/g
,s/\&lt;/</g
,s/\&#60;/</g
,s/\&#61;/=/g
,s/\&gt;/>/g
,s/\&#62;/>/g
,s/\&#95;/_/g
,s/\|/\&#124;/g
'
}
fn get_posts{
$"cmd $"feed | rssread | cram | scape >$file
echo >>$file
}
fn parse_posts{
ifs='
' {
posts=`{cat $file}
for(i in `{seq 1 $#posts | sort -nr}){
post=$posts($i)
if(! ~ $post ''){
a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
a_date=`{date}
a_link=`{echo $post | sed 's/^.*HJDIVIDERlink: //g; s/HJDIVIDER.*$//g'}
a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $werc/sites/$site/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
echo $"a_title >$werc/sites/$site/src/$a_id/title
echo $"a_date >$werc/sites/$site/src/$a_id/date
echo $a_link(1) >$werc/sites/$site/src/$a_id/link
echo $a_link(1) | md5sum >>$werc/sites/$site/links
if(~ $a_link(1) *staticflickr.com*)
echo '<img src="'$"a_link'">' >$werc/sites/$site/src/$a_id/body
echo $"a_body '</a></li></ul>' >>$werc/sites/$site/src/$a_id/body
ifs=' ' {
for(j in $tags){
>$werc/sites/$site/src/$a_id/tags/$j
echo $a_id/tags/$j >>$werc/sites/$site/tags
}
}
}
if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
}
}
}
}
if(test -f /boot/factotum && test -f /rc/bin/hget)
webfs
for(i in `{grep -v -e '^#' $feeds}){
feed=`{echo $"i | sed 's/\|.*$//g'}
tags=`{echo $"i | sed 's/\|/ /g'}
tags=$tags(2-)
get_posts
parse_posts
}

119
werc/apps/barf/bin/gz.read Executable file
View file

@ -0,0 +1,119 @@
#!/bin/rc
# Parse XML RSS feeds into BARF blog posts for the specified site.
# If a post with a matching _link_ already exists, no new post will
# be created for that item. Tags will be created according to the rules
# defined in the get_tags() function.
#
# The file argument should point to a file containing one line per feed,
# with fields separated by the | character, in the following format:
#
# http://feeds.feedburner.com/ImNotReallyStanleyLieber|stanleylieber
#
# where the first field is the feed URL and each addition field is a tag.
#
# Requires 20h's xmlpull and rssread.
rfork en
switch($1){
case /*
feeds=$1
site=read.stanleylieber.com
tags=()
case *
echo 'Usage: gz file' >[1=2]
exit usage
}
file=/tmp/gz.$pid
werc=/usr/sl/www/werc
if(test -f /boot/factotum)
cmd=hget
if not
cmd='curl -s'
fn cram{
ssam '
,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
,s/\n//g
,s/HJDIVIDERtitle:/\n&/g
'
}
fn scape{
ssam '
,s/ //g
,s/\&quot;/\"/g
,s/\&#34;/\"/g
,s/\&amp;/\&/g
,s/\&#38;/\&/g
,s/\&#39;/''/g
,s/\&#44;/,/g
,s/\&#45;/-/g
,s/\&#46;/\./g
,s/\&#47;/\//g
,s/\&#58;/:/g
,s/\&#59;/;/g
,s/\&lt;/</g
,s/\&#60;/</g
,s/\&#61;/=/g
,s/\&gt;/>/g
,s/\&#62;/>/g
,s/\&#95;/_/g
,s/\|/\&#124;/g
'
}
fn get_posts{
$"cmd $"feed | rssread | cram | scape >$file
echo >>$file
}
fn parse_posts{
ifs='
' {
posts=`{cat $file}
for(i in `{seq 1 $#posts | sort -nr}){
post=$posts($i)
if(! ~ $post ''){
a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
a_date=`{date}
a_link=`{echo $post | sed 's/^.*HJDIVIDERlink: //g; s/HJDIVIDER.*$//g'}
a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $werc/sites/$site/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
echo $"a_title >$werc/sites/$site/src/$a_id/title
echo $"a_date >$werc/sites/$site/src/$a_id/date
echo $a_link(1) >$werc/sites/$site/src/$a_id/link
echo $a_link(1) | md5sum >>$werc/sites/$site/links
if(~ $a_link(1) *staticflickr.com*)
echo '<img src="'$"a_link'">' >$werc/sites/$site/src/$a_id/body
echo $"a_body '</a></li></ul>' >>$werc/sites/$site/src/$a_id/body
ifs=' ' {
for(j in $tags){
>$werc/sites/$site/src/$a_id/tags/$j
echo $a_id/tags/$j >>$werc/sites/$site/tags
}
}
}
if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
}
}
}
}
if(test -f /boot/factotum && test -f /rc/bin/hget)
webfs
for(i in `{grep -v -e '^#' $feeds}){
feed=`{echo $"i | sed 's/\|.*$//g'}
tags=`{echo $"i | sed 's/\|/ /g'}
tags=$tags(2-)
get_posts
parse_posts
}

119
werc/apps/barf/bin/gz.tumblr Executable file
View file

@ -0,0 +1,119 @@
#!/bin/rc
# Parse XML RSS feeds into BARF blog posts for the specified site.
# If a post with a matching _link_ already exists, no new post will
# be created for that item. Tags will be created according to the rules
# defined in the get_tags() function.
#
# The file argument should point to a file containing one line per feed,
# with fields separated by the | character, in the following format:
#
# http://feeds.feedburner.com/ImNotReallyStanleyLieber|stanleylieber
#
# where the first field is the feed URL and each addition field is a tag.
#
# Requires 20h's xmlpull and rssread.
rfork en
switch($1){
case /*
feeds=$1
site=tumblr.stanleylieber.com
tags=()
case *
echo 'Usage: gz file' >[1=2]
exit usage
}
file=/tmp/gz.$pid
werc=/usr/sl/www/werc
if(test -f /boot/factotum)
cmd=hget
if not
cmd='curl -s'
fn cram{
ssam '
,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
,s/\n//g
,s/HJDIVIDERtitle:/\n&/g
'
}
fn scape{
ssam '
,s/ //g
,s/\&quot;/\"/g
,s/\&#34;/\"/g
,s/\&amp;/\&/g
,s/\&#38;/\&/g
,s/\&#39;/''/g
,s/\&#44;/,/g
,s/\&#45;/-/g
,s/\&#46;/\./g
,s/\&#47;/\//g
,s/\&#58;/:/g
,s/\&#59;/;/g
,s/\&lt;/</g
,s/\&#60;/</g
,s/\&#61;/=/g
,s/\&gt;/>/g
,s/\&#62;/>/g
,s/\&#95;/_/g
,s/\|/\&#124;/g
'
}
fn get_posts{
$"cmd $"feed | rssread | cram | scape >$file
echo >>$file
}
fn parse_posts{
ifs='
' {
posts=`{cat $file}
for(i in `{seq 1 $#posts | sort -nr}){
post=$posts($i)
if(! ~ $post ''){
a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
a_date=`{date}
a_link=`{echo $post | sed 's/^.*HJDIVIDERlink: //g; s/HJDIVIDER.*$//g'}
a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $werc/sites/$site/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
echo $"a_title >$werc/sites/$site/src/$a_id/title
echo $"a_date >$werc/sites/$site/src/$a_id/date
echo $a_link(1) >$werc/sites/$site/src/$a_id/link
echo $a_link(1) | md5sum >>$werc/sites/$site/links
if(~ $a_link(1) *staticflickr.com*)
echo '<img src="'$"a_link'">' >$werc/sites/$site/src/$a_id/body
echo $"a_body '</a></li></ul>' >>$werc/sites/$site/src/$a_id/body
ifs=' ' {
for(j in $tags){
>$werc/sites/$site/src/$a_id/tags/$j
echo $a_id/tags/$j >>$werc/sites/$site/tags
}
}
}
if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
}
}
}
}
if(test -f /boot/factotum && test -f /rc/bin/hget)
webfs
for(i in `{grep -v -e '^#' $feeds}){
feed=`{echo $"i | sed 's/\|.*$//g'}
tags=`{echo $"i | sed 's/\|/ /g'}
tags=$tags(2-)
get_posts
parse_posts
}

3
werc/apps/barf/bin/rsrc Executable file
View file

@ -0,0 +1,3 @@
#!/bin/rc
# Remove static files.
rm -r [0-9]*.html [0-9]*-[0-9]*.html tag

4
werc/apps/barf/bin/srct Executable file
View file

@ -0,0 +1,4 @@
#!/bin/rc
# do not store these files in the worm
fn f{ du -a $* | sed 's/^.* //g' }
for(i in `{f $1}){ chmod +t $i }

14
werc/apps/barf/lib/barf.tpl Executable file
View file

@ -0,0 +1,14 @@
% if(~ $show_header 1 && ! ~ $barf_type login rss)
% display_header
% if(~ $a_func edit_form){
% if(check_user && ! ~ $#logged_user 0)
% edit_form
% if not
% display_^$barf_type
% }
% if not
% display_^$barf_type
% if(~ $show_sidebar 1 && ~ $#a_func 0 && ! ~ $barf_type login rss)
% display_sidebar
% if(~ $show_footer 1 && ~ $#a_func 0 && ! ~ $barf_type login rss)
% display_footer

43
werc/apps/barf/lib/blog Executable file
View file

@ -0,0 +1,43 @@
fn display_blog{
echo '<div id="center">
<div id="posts">'
get_post_list
for(i in `{seq 1 $#posts}){
a_id=$posts($i)
a_dir=$barf_root/$"barf_dir/src/$a_id
echo '<div id="post">
<div id="post_title">'
print_title
echo '</div>
<div id="post_meta">'
link=`{cat $a_dir/link}
echo '<span id="post_link">
<a href="'$"link'" target="_b">link</a>
</span>
| <span id="post_tags">'
print_tags
echo '</span>
| <span id="post_date">'
cat $a_dir/date
echo '</span>'
print_id
if(check_user && ! ~ $#logged_user 0){
echo ' | <span id="post_edit">'
print_edit
echo '</span>'
}
echo '</div>
<div id="post_body">'
cat $a_dir/body
if(~ $show_disqus 1 && ! ~ $#id 0)
cat $barf_root/_werc/barf/disqus
echo '</div>
</div>
<br>'
}
display_prevnext
echo '<br><br><br>
</div>
</div>
</div>'
}

414
werc/apps/barf/lib/core Executable file
View file

@ -0,0 +1,414 @@
fn delete_post{
a_dir=$barf_root/$"barf_dir/src/$a_id
if(test -d $a_dir){
rm -rf $a_dir &&
{echo ',x/^'$a_id'\/.*\n/d'; echo w; echo q} | sam -d $barf_root/$"barf_dir/tags >[2]/dev/null
}
post_redirect $base_url^$barf_base_uri
}
fn display_footer{
if(test -f $barf_root/$"barf_dir/_werc/barf/footer)
cat $barf_root/$"barf_dir/_werc/barf/footer
if not if(test -f $barf_root/_werc/barf/footer)
cat $barf_root/_werc/barf/footer
if not
cat apps/barf/barf/footer
}
fn display_header{
if(test -f $barf_root/$"barf_dir/_werc/barf/header)
cat $barf_root/$"barf_dir/_werc/barf/header
if not if(test -f $barf_root/_werc/barf/header)
cat $barf_root/_werc/barf/header
if not
cat apps/barf/barf/header
}
fn display_login{
echo '<div id="login">
<form method="post" action="/">
<input type="hidden" name="a_func" value="login">
username: <input type="text" name="user_name"><br>
password: <input type="password" name="user_password"><br>
<input name="s" type="submit" value="login">
</form>
</div>'
}
fn display_prevnext{
if(test $stop -gt `{echo 1+^$posts_per_page | bc}){
nprev=`{echo $start^-1-^$posts_per_page | bc}
prev='<span>
<a href="'$base_url^$barf_base_uri'?tags='$"tags'&start='$"nprev'">prev</a> |
</span>'
}
if(test $#posts -gt $posts_per_page){
nnext=`{echo $stop^+1 | bc}
next='<span>
<a href="'$base_url^$barf_base_uri'?tags='$"tags'&start='$"nnext'">next</a>
</span>'
}
echo '<div id="page_list">
'$"prev'
'$"next'
</div>'
}
fn display_sidebar{
if(test -f $barf_root/$"barf_dir/_werc/barf/sidebar)
cat $barf_root/$"barf_dir/_werc/barf/sidebar
if not if(test -f $barf_root/_werc/barf/sidebar)
cat $barf_root/_werc/barf/sidebar
if not
cat apps/barf/barf/sidebar
}
fn dsrc{
low=`{ls -p $barf_root/$"barf_dir/src | sort -n | sed 1q}
high=$a_id
if(~ $#low 1 && ~ $#high 1){
cd $barf_root/$"barf_dir/src && rm -rf `{seq $low $high} &&
{
for(i in `{seq $low $high})
echo ',x/^'$i'\/.*\n/d'
echo w
echo w
echo q
} | sam -d $barf_root/$"barf_dir/tags >[2]/dev/null
}
post_redirect $base_url^$barf_base_uri
}
fn edit_form{
if(~ $#a_id 0)
name=add
if not{
name=update
a_dir=$barf_root/$"barf_dir/src/$a_id
for(x in $barf_items){
if(~ $x img)
a_img=`{ls -p $a_dir/img | sed 1q}
if(~ $x tags)
a_tags=`{ls -p $a_dir/tags}
if not
$x=`{cat $a_dir/$x}
}
}
echo '<div id="list">
<form action="/" method="post" name="edit" id="button">
<input type="hidden" name="fake" value="fake">
<input type="text" name="url" style="display: none;">
<input type="hidden" name="a_func" value="edit_post">'
if(~ $name update)
echo '<input type="hidden" name="a_id" value="'$"a_id'">'
for(x in $barf_items){
if(~ $x body){
echo '<div id="edit_body">' \
'body:<br>' \
'<textarea name="a_body">'
if(~ $name update)
cat $a_dir/body
echo '</textarea></div>'
}
if not if(~ $x img){
echo '<div id="edit_img">' \
'image:<br>' \
'<input name="a_img" type="text" value="'$"a_img'" id="edit"> &nbsp;&nbsp;' \
'download: <input name="a_download" type="checkbox" value="1">' \
'</div>'
}
if not if(~ $x tags){
echo '<div id="edit_tags">' \
'tags: &nbsp;&nbsp;(space separated list of tags)<br>' \
'<input name="a_tags" type="text" value="'$"a_tags'" id="edit">' \
'</div>'
}
if not{
echo '<div id="edit_'$"x'">' \
$"x':<br>' \
'<input name="a_'$"x'" type="text" value="'$"$x'" id="edit">' \
'</div>'
}
}
echo '<div id="edit_submit">' \
'<input type="submit" name="'$name'" value="'$name'">' \
'</div>
</form>
</div>'
}
fn edit_post{
if(~ $#a_id 0){
a_id=`{echo `{ls -p $barf_root/$"barf_dir/src | sort -n | tail -1}^+1 | bc}
if(~ $#a_id 0)
a_id=1
while(test -d $barf_root/$"barf_dir/src/$a_id)
a_id=`{echo $a_id^+1 | bc}
}
a_dir=$barf_root/$"barf_dir^src/$a_id
mkdir -p $a_dir/img $a_dir/tags
rm -f $a_dir/tags/*
for(x in $barf_items){
if(~ $x date){
if(! ~ $#a_date 0)
echo $"a_date >$a_dir/date
if not
date >$a_dir/date
}
if not if(~ $x tags){
if(! ~ $#a_tags 0){
a_tags=`{echo $"a_tags | sed 's/[^A-Za-z0-9_\- ]//g'}
ifs=' '{a_tags=`{echo -n $a_tags}}
{
t=1
while(test $t -le $#a_tags){
>$a_dir/tags/$a_tags($t)
t=`{echo $t^+1 | bc}
}
}
for(i in $a_tags)
echo $a_id'/tags/'$i >>$barf_root/$"barf_dir/tags
}
}
if not if(! ~ $x img tags){
item='a_'$"x
if(! ~ $$item ''){
>$a_dir/$x
echo $$item >$a_dir/$x
}
}
}
if(~ $a_download 1){
switch($barf_type){
case image
rm -f $a_dir/img/*
img=$a_dir/img/^`{date -n}^.^`{echo $"a_img |
sed 's/^.*\.(gif|GIF)$/gif/g;
s/^.*\.(jpg|jpeg|JPG|JPEG)$/jpg/g;
s/^.*\.(png|PNG)$/png/g;
s/^.*\.(tif|TIF|tiff|TIFF)$/tif/g'
}
thumb=$a_dir/img/small.^`{basename $img | sed 's/\..*$//g'}^.png
if(test -f /boot/factotum){
@{
rfork n
if(test -f /rc/bin/hget)
webfs
hget $"a_img >$img
#magick/convert $img -resize 500x600 $thumb
switch($img){
case *.bmp
cmd=bmp
case *.gif
cmd=gif
case *.ico
cmd=ico
case *.jpg
cmd=jpg
case *.png
cmd=png
case *.tif
cmd=tif
case *.tga
cmd=tga
}
$cmd -9et <$img | resample -x 500 | topng >$thumb
}
}
if not{
curl -s -o $"a_img >$img
convert $img -resize 500x600 $thumb
}
case url
if(test -f /boot/factotum){
@{
rfork n
if(test -f /rc/bin/hget)
webfs
hget $"a_link | htmlfmt | fmt >$a_dir/body
}
}
if not
curl -s $"a_link | htmlfmt | fmt >$a_dir/body
}
}
if(! ~ $gp 1)
post_redirect $base_url^$barf_base_uri
}
fn get_post_list{
if(~ $id [0-9]*)
posts=$id
if not{
posts=`{
if(~ $show_ascending 1)
sort=(sort -n)
if not
sort=(sort -nr)
if(~ $tags all)
ls -p $barf_root/$"barf_dir/src |
grep -e '^[0-9]*$' |
eval $sort |
sed -n $start^,^$stop^p # awk 'NR=='$start',NR=='$stop' {print;}'
if not
grep -e '^.*\/'$tags'$' $barf_root/$"barf_dir/tags |
awk -F '/' '{print $1;}' |
eval $sort |
uniq |
sed -n $start^,^$stop^p
}
if(! ~ $posts [0-9]*)
posts=()
}
}
fn get_start{
if(~ $#start 0)
start=1
}
fn get_stop{
if(~ $#stop 0)
stop=`{echo $start^+^$posts_per_page | bc}
}
fn get_tags{
if(~ $#tags 0)
tags=all
}
fn load_get_args{
if(~ $REQUEST_METHOD GET && ~ $#get_args 0 && ~ $REQUEST_URI *'='*){
ifs='&' {
a=`{echo $"REQUEST_URI | sed 's/(^\/|#.*$)//g'}
for(pair in $a){
ifs='=' { pair=`{echo -n $pair} }
n='get_arg_'^`{echo $pair(1) | urldecode | tr -cd 'a-zA-Z0-9_'}
get_args=( $get_args $n )
ifs=() { $n=`{echo -n $pair(2) | urldecode | tr -d ' '} }
}
}
pair=()
}
}
fn parse_get_args{
if(! ~ $#get_arg_a_func 0)
a_func=$get_arg_a_func
if(! ~ $#get_arg_a_id 0)
a_id=$get_arg_a_id
if(! ~ $#get_arg_id 0)
id=$get_arg_id
if(! ~ $#get_arg_start 0)
start=$get_arg_start
if(! ~ $#get_arg_stop 0)
stop=$get_arg_stop
if(! ~ $#get_arg_reply 0)
reply=$get_arg_reply
if(! ~ $#get_arg_tags 0)
tags=$get_arg_tags
}
fn parse_post_args{
for(x in $barf_items){
a='a_'$"x
p='post_arg_'$"a
$a=$$p
}
if(! ~ $#post_arg_a_download 0)
a_download=$post_arg_a_download
if(! ~ $#post_arg_a_func 0)
a_func=$post_arg_a_func
if(! ~ $#post_arg_fake 0)
fake=$post_arg_fake
if(! ~ $#post_arg_a_id 0)
a_id=$post_arg_a_id
if(! ~ $#post_arg_url 0)
url=$post_arg_url
}
fn print_edit{
edit='<a href="'$base_url^$barf_base_uri'?a_func=edit_form&a_id='$"a_id'">edit</a>'
delete='<a href="'$base_url^$barf_base_uri'?a_func=delete_post&a_id='$"a_id'" onclick="return confirm(''are you sure you want to delete?'');">delete</a>'
dsrc='<a href="'$base_url^$barf_base_uri'?a_func=dsrc&a_id='$"a_id'" onclick="return confirm(''are you sure you want to dsrc?'');">dsrc</a>'
echo $"edit' | '$"delete' | '$"dsrc
}
fn print_id{
echo '<span id="post_id"><a href="/?id='$"a_id'">No.'$"a_id'</a></span>'
}
fn print_img{
a_img=`{ls -p $a_dir/img/[0-9]*}
a_thumb=`{ls -p $a_dir/img/small*}
if(! ~ $#a_img 0)
if(~ $#a_thumb 0)
a_thumb=$a_img
echo '<a href="'$base_url^$barf_base_uri'src/'$a_id'/img/'$a_img'" target="_b"><img src="'$base_url^$barf_base_uri'src/'$a_id'/img/'$a_thumb'" border="0"></a>'
}
fn print_tags{
a_tags=`{ls -p $a_dir/tags}
a_tags=`{for(t in $a_tags) echo '<a href="'$base_url^$barf_base_uri'?tags='$t'">'$t'</a>, '}
a_tags=`{echo $a_tags | awk '{print substr($0, 1, length($0) -1)}'}
echo '<span id="post_tags">'$"a_tags'</span>'
}
fn print_title{
a_title=`{cat $a_dir/title}
if(! ~ $#a_title 0){
if(~ $barf_type log url)
echo '<a href="'`{cat $a_dir/link}'">'$"a_title'</a>'
if not
echo '<a href="'$base_url^$barf_base_uri'?id='$"a_id'">'$"a_title'</a>'
}
}
fn redirect_bots{
if(! ~ $fake fake || ! ~ $url '')
post_redirect http://google.com
}
fn urldecode {
awk '
BEGIN {
hextab ["0"] = 0; hextab ["8"] = 8;
hextab ["1"] = 1; hextab ["9"] = 9;
hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
}
{
decoded = ""
i = 1
len = length ($0)
while ( i <= len ) {
c = substr ($0, i, 1)
if ( c == "%" ) {
if ( i+2 <= len ) {
c1 = substr ($0, i+1, 1)
c2 = substr ($0, i+2, 1)
if ( hextab [c1] == "" || hextab [c2] == "" ) {
print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
} else {
code = 0 + hextab [c1] * 16 + hextab [c2] + 0
c = sprintf ("%c", code)
i = i + 2
}
} else {
print "WARNING: invalid % encoding: " substr ($0, i, len - i)
}
} else if ( c == "+" ) {
c = " "
}
decoded = decoded c
++i
}
printf "%s", decoded
}
'
}

View file

@ -0,0 +1 @@
% run_handler $handler_body_main

68
werc/apps/barf/lib/image Executable file
View file

@ -0,0 +1,68 @@
fn add_post{
redirect_bots
a_download=1
edit_post
}
fn display_image{
echo '<div id="center">'
if(~ $allow_anon 1 || {check_user && ! ~ $#logged_user 0}){
echo '<div id="upload">
<form method="post" action="/">
<input type="hidden" name="fake" value="fake">
<input type="text" name="url" style="display: none;">
<input type="hidden" name="a_func" value="add_post">
<div id="upload_heading">/'$tags'/</div>
<table id="upload_table">
<tr><td id="upload_label">Image</td><td><input type="text" name="a_img" id="upload_input"></td></tr>
<tr><td id="upload_label">Link</td><td><input type="text" name="a_link" id="upload_input"></td></tr>
<tr><td id="upload_label">Tags</td><td><input type="text" name="a_tags" id="upload_tags">
<input type="submit" name="submit" value="add" id="upload_submit"></td></tr>
</table>
</form>
<table align="center">
<tr>
<td>
<p>
<li id="upload_meta">Supported file types are: GIF, JPG, PNG</li>
<li id="upload_meta">Images greater than 500x600 pixels will be thumbnailed.</li>
</td>
</tr>
</table>
</div>'
}
echo '<div id="center_body">'
get_post_list
for(i in `{seq 1 $#posts}){
a_id=$posts($i)
a_dir=$barf_root/$"barf_dir/src/$a_id
echo '<div id="post">
<div id="post_meta">
<span id="post_link">'
link=`{cat $a_dir/link}
echo '<a href="'$"link'">link</a>
</span> |
<span id="post_tags">'
print_tags
echo '</span> |
<span id="post_date">'
cat $a_dir/date
echo '</span>'
if(check_user && ! ~ $#logged_user 0){
echo '| <span id="post_edit">'
print_edit
echo '</span>'
}
echo '</div>
<div id="post_img">'
print_img
echo '</div>
</div>
<br><br>'
}
display_prevnext
echo '<br><br><br><br>
</div>
</div>
</div>'
}

55
werc/apps/barf/lib/log Executable file
View file

@ -0,0 +1,55 @@
fn display_log{
if(~ $#logged_user 0)
a='<a href="'$base_url^$barf_base_uri'login">login</a>'
if not
a='<a href="'$base_url^$barf_base_uri'?a_func=edit_form">add</a>'
echo '<div>
<span id="add">'$"a'</span>
<span id="search">
<form method="get" action="/">
<input type="text" name="tags" size="28">
<input type="submit" value="search">
</form>
</span>
</div>
</div>
<div id="list">
<table id="post_table">
<tbody>
<tr id="blank">
<th style="display: none;">&nbsp;</th>
<th style="display: none;">&nbsp;</th>
<th style="display: none;">&nbsp;</th>'
if(check_user && ! ~ $#logged_user 0)
echo '<th style="display: none;">&nbsp;</th>'
echo '</tr>'
get_post_list
for(i in `{seq 1 $#posts}){
a_id=$posts($i)
a_dir=$barf_root/$"barf_dir/src/$a_id
echo '<tr>'
for(j in $barf_items){
echo '<td id="post_'$"j'">'
if(~ $j img)
print_img
if not if(~ $j tags)
print_tags
if not if(~ $j title)
print_title
if not
cat $a_dir/$j
echo '</td>'
}
if(check_user && ! ~ $#logged_user 0){
echo '<td id="post_edit">'
print_edit
echo '</td>'
}
echo '</tr>'
}
echo '</tbody>
</table>'
display_prevnext
echo '<br><br><br><br>
</div>'
}

50
werc/apps/barf/lib/paste Executable file
View file

@ -0,0 +1,50 @@
fn add_post{
redirect_bots
a_date=`{date}
edit_post
}
fn display_paste{
echo '<div id="center">'
if(~ $allow_anon 1 || {check_user && ! ~ $#logged_user 0}){
echo '<div id="paste">
<p>
<form method="post" action="/">
<input type="hidden" name="fake" value="fake">
<input type="text" name="url" style="display: none;">
<input type="hidden" name="a_func" value="add_post">
<textarea name="a_body" id="paste_box"></textarea><br>
<input type="submit" name="submit" value="submit" id="paste_submit">
</form>
</div>'
}
echo '<p>
<div id="posts">'
get_post_list
for(i in `{seq 1 $#posts}){
a_id=$posts($i)
a_dir=$barf_root/$"barf_dir/src/$a_id
echo '<div id="post">
<div id="post_meta">'
date=`{cat $a_dir/date}
echo '<span id="post_date">
<a href="/src/'$"a_id'/body" target="_b">'$"date'</a>
</span>'
if(check_user && ! ~ $#logged_user 0){
echo ' | <span id="post_edit">'
print_edit
echo '</span>'
}
echo '</div>
<div id="post_body">'
txt_handler $barf_root/$"barf_dir/src/$a_id/body
echo '</div>
</div>
<br>'
}
display_prevnext
echo '<br><br><br><br>
</div>
</div>
</div>'
}

56
werc/apps/barf/lib/rss Executable file
View file

@ -0,0 +1,56 @@
fn display_rss{
echo '<?xml version="1.0" encoding="UTF-8"?>'
echo '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">'
echo '<channel>'
echo '<atom:link href="'$base_url^$req_path'" rel="self" type="application/rss+xml" />'
echo '<title><![CDATA['$"siteTitle']]></title>'
echo '<link>'$base_url^$barf_base_uri'</link>'
echo '<description><![CDATA['$"blogDesc']]></description>'
echo '<generator><![CDATA[barf]]></generator>'
echo '<lastBuildDate>'
ndate -m `{date `{mtime $barf_root/$"barf_dir/src | awk '{print $1}'}} # rfc2822 last time channel content changed.
echo -n '</lastBuildDate>'
echo '<language>en-us</language>'
date=`{ndate -m} # rfc2822 publication date for content in the channel.
get_post_list
for(i in `{seq 1 $#posts}){
a_id=$posts($i)
a_dir=$barf_root/$"barf_dir/src/$a_id
echo '<item>'
echo '<guid isPermaLink="true">'$base_url^$barf_base_uri'?id='$"a_id'</guid>'
echo '<pubDate>'$"date'</pubDate>'
title=`{cat $a_dir/title}
if(~ $title '')
ntitle=($siteTitle $"a_id)
if not
ntitle=$title
echo '<title>'$"ntitle'</title>'
echo '<link>'$base_url^$barf_base_uri'?id='$"a_id'</link>'
echo '<description><![CDATA['
if(~ $obarf_type image){
if(! ~ $#a_link 0)
link=$"a_link
if not
link=$base_url^$barf_base_uri'?id='$"a_id
echo '<p>source: <a href="'$"link'">link</a></p>'
}
a_tags=`{ls -p $a_dir/tags}
if(! ~ $#a_tags 0){
echo '<p>tags: '
print_tags
echo '</p>'
echo '<p>'
}
# begin ugly if statements
if(~ $obarf_type paste)
echo '<pre>'
if(! ~ $obarf_type image)
cat $a_dir/body
if(~ $obarf_type paste)
echo '</pre>'
if(~ $obarf_type image)
print_img
echo '</p>]]></description></item>'
}
echo '</channel></rss>'
}

52
werc/apps/barf/lib/url Executable file
View file

@ -0,0 +1,52 @@
fn display_url{
if(~ $#logged_user 0)
a='<a href="'$base_url^$barf_base_uri'login">login</a>'
if not
a='<a href="'$base_url^$barf_base_uri'?a_func=edit_form">add</a>'
echo '<div>
<span id="add">'$"a'</span>
<span id="search">
<form method="get" action="/">
<input type="text" name="tags" size="28">
<input type="submit" value="search">
</form>
</span>
</div>
</div>
<div id="list">
<table id="post_table">
<tbody>
<tr id="blank">
<th style="display: none;">&nbsp;</th>
<th style="display: none;">&nbsp;</th>
<th style="display: none;">&nbsp;</th>'
if(check_user && ! ~ $#logged_user 0)
echo '<th style="display: none;">&nbsp;</th>'
echo '</tr>'
get_post_list
for(i in `{seq 1 $#posts}){
a_id=$posts($i)
a_dir=$barf_root/$"barf_dir/src/$a_id
echo '<tr>
<td id="post_title">'
print_title
echo '</td>
<td id="post_tags">'
print_tags
echo '</td>
<td id="post_date">'
cat $a_dir/date
echo '</td>'
if(check_user && ! ~ $#logged_user 0){
echo '<td id="post_edit">'
print_edit
echo '</td>'
}
echo '</tr>'
}
echo '</tbody>
</table>'
display_prevnext
echo '<br><br><br><br>
</div>'
}

10
werc/apps/barf/mkfile Executable file
View file

@ -0,0 +1,10 @@
WERC=/usr/sl/www/werc
PLAN9=$WERC/sites/plan9.stanleylieber.com
web:V:
src=`{basename `{pwd}}
rm -rf $PLAN9/werc/apps/$src
cd $WERC/apps
tar zcvf $PLAN9/werc/apps/$src.tgz $src
cd $PLAN9/werc/apps
tar zxvf $src.tgz

344
werc/apps/barf/pub/1995.css Executable file
View file

@ -0,0 +1,344 @@
/* 1995 */
body {
color: black;
background-color: silver;
font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif;
font-size: 84%; /* Enables font size scaling in MSIE */
margin: 0;
padding: 0;
}
/* # Header # */
.superHeader {
color: black;
background-color: silver;
height: 1.6em;
}
.superHeader img { vertical-align: bottom; }
.superHeader a {
color: blue;
background-color: transparent;
font-size: 91%;
margin: 0;
padding: 0 0.5ex 0 0.25ex;
text-decoration: underline; }
}
a { text-decoration: underline; }
a:hover { text-decoration: underline; }
.superHeader div {
position: absolute;
top: 0.40ex;
}
.superHeader .left { left: 0.4em; }
.superHeader .right { right: 0.4em; }
.midHeader {
color: black;
background-color: silver;
border: solid 0 black;
border-width: 1px 0;
}
.headerTitle {
color: black;
font-size: 233%;
font-weight: normal;
margin: 0 0 0 4mm;
padding: 0.25ex 0;
}
#headerSubTitle {
font-size: 50%;
font-style: italic;
margin-left: 1em;
}
.headerTitle a { color: black; }
.headerTitle a:hover { text-decoration: none; }
.subHeader {
display: none;
color: white;
background-color: rgb(0,51,153);
margin: 0;
padding: 1ex 1ex 1ex 1.5mm;
}
.subHeader a {
color: white;
background-color: transparent;
font-weight: bold;
margin: 0;
padding: 0 0.75ex 0 0.5ex;
}
.superHeader .highlight, .subHeader .highlight {
color: rgb(253,160,91);
background-color: transparent;
}
/* # Side # */
#side-bar {
width: 16em;
float: left;
clear: left;
border-right: 1px solid black;
}
#side-bar div {
border-bottom: 1px solid black;
}
.sideBarTitle {
font-weight: bold;
margin: 0 0 0.5em 2mm;
padding: 1em 0 0 0;
}
#side-bar ul {
list-style-type: none;
list-style-position: outside;
margin: 0;
padding: 0 0 0.3em 0;
}
li ul {
padding-left: 0.6em !important;
}
#side-bar li {
margin: 0;
padding: 0.1ex 0; /* Circumvents a rendering bug (?) in MSIE 6.0 XXX should move to iehacks.css, this causes an ugly gap */
}
#side-bar a {
color: black;
background-color: transparent;
margin: 0;
padding: 0.25em 1ex 0.25em 2mm;
display: block;
text-transform: capitalize;
font-weight: bold!important;
font-size: 102%;
border-left: blue solid 0.2em;
}
.thisPage, .thisPage a {
color: black!important;
background-color: white;
padding-left: 5mm;
}
#side-bar a:hover {
color: white;
background-color: blue;
border-left: black solid 0.2em;
text-decoration: none;
}
.sideBarText {
line-height: 1.5em;
margin: 0 0 1em 0;
padding: 0 1.5ex 0 2.5mm;
display: block;
}
#side-bar .sideBarText a {
margin: 0;
padding: 0;
display: inline;
}
#side-bar .sideBarText a:hover {
color: black;
background-color: transparent;
text-decoration: none;
}
/* # Main Copy # */
#main-copy {
max-width: 70em;
color: black;
background-color: transparent;
text-align: justify;
line-height: 1.5em;
margin: 0em 0 0 16em;
padding: 0.5mm 5mm 5mm 5mm;
border-left: 1px solid black;
}
#bodyText {
margin: 0 0 0 15.5em;
padding: 2mm 5mm 2mm 5mm;
}
#main-copy p {
margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */
padding: 0;
}
#main-copy a {
color: blue;
background-color: transparent;
text-decoration: underline;
}
#main-copy a:hover {
color: blue;
background-color: transparent;
text-decoration: underline;
}
#main-copy h1, #main-copy h2 {
color: black;
background-color: transparent;
font-size: 145.5%;
font-weight: bold;
margin: 2em 0 0 0;
padding: 0.5ex 0 0.5ex 0.6ex;
border-bottom: 2px solid black;
}
#main-copy h2 {
font-size: 115.5%;
border-bottom: 1px solid black;
}
#main-copy .topOfPage {
color: black;
background-color: transparent;
font-size: 91%;
font-weight: bold;
text-decoration: none;
margin: 3ex 1ex 0 0;
padding: 0;
float: right;
}
dl {
margin: 1em 1ex 2em 1ex;
padding: 0;
}
dt {
font-weight: bold;
margin: 0 0 0 0;
padding: 0;
}
dd {
margin: 0 0 2em 2em;
padding: 0;
}
/* # Footer # */
#footer {
color: black;
background-color: silver;
padding: 1em;
clear: both;
border-color: black;
border-width: 1px 0;
}
#footer .left {
text-align: left;
line-height: 1.55em;
float: left;
clear: left;
}
#footer .right {
text-align: right;
line-height: 1.45em;
}
#footer a {
color: blue;
background-color: transparent;
}
/* GENERAL */
table {
background-color: transparent;
padding: 0px;
border: 0px;
border-collapse: collapse;
}
td {
padding: 10px;
border-width: 1px;
border-style: solid;
border-collapse: collapse;
border-color: #000000;
background: silver;
}
tr {
border-width: 1px;
border-style: solid;
border-collapse: collapse;
border-color: #000000;
}
hr {
border-width: 0px 0px 0.1em 0px;
border-color: black;
}
acronym, .titleTip {
border-bottom: 1px solid black;
cursor: help;
margin: 0;
padding: 0 0 0.4px 0;
}
pre {
margin-left: 2em;
font-size: 1.2em;
}
blockquote {
border-left: 1px solid blue;
font-style: italic;
}
.smallCaps {
font-size: 110%;
font-variant: small-caps;
}
.doNotDisplay { display: none; }
.notify_errors,
.notify_notes,
.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid black; }
.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; }
.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
.notify_errors a { color: #8a1f11; }
.notify_notes a { color: #514721; }
.notify_success a { color: #264409; }
/* # Page/Handler specific # */
h1.dir-list-head, ul.dir-list {
text-transform: capitalize;
font-weight: bold;
}
ul.sitemap-list a {
text-transform: capitalize;
}

63
werc/apps/barf/pub/1oct1993.css Executable file
View file

@ -0,0 +1,63 @@
/* 1oct1993 */
body {
color: #FFFFFF;
background-color: #000000;
font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
font-size: 84%; /* Enables font size scaling in MSIE */
margin: 0;
padding: 0;
}
a { text-decoration: none; color: #00ADEF; }
a:hover { color: #00ADEF; text-decoration: none; }
li:hover { color: #00ADEF; text-decoration: none; }
li a { color: #00ADEF }
li a:hover { color: #00ADEF; text-decoration: none; }
li ul { padding-left: 0.6em !important; }
h1 { font-size: 10pt; font-weight: normal; }
h2 { font-size: 9pt; font-weight: normal; }
input , textarea, select, option { background-color: #00ADEF; border: none; }
table { border: none; }
tr { background-color: transparent; }
th {
background-color: transparent;
border: none;
text-align: center;
}
td {
background-color: transparent;
border: none;
}
hr {
border-width: 0px 0px 0.1em 0px;
border-color: transparent;
}
pre, code, blockquote {
font-family: Courier, 'Lucida Console','Courier New', Serif;
margin-left: 2em;
font-size: 1.2em;
}
blockquote {
border-left: none;
font-style: none;
background-color: #00ADEF;
}
#header { flex-basis: 100%; }
#header tr { background-color: transparent; }
#center {
width: 500px;
margin-left: auto;
margin-right: auto;
}
#center h1 { font-size 9pt; }
#footer {
font-size: 8pt;
background-color: #000000;
color: #00ADEF;
margin-left: auto;
margin-right: auto;
}
#footer a { color: #00ADEF; text-decoration: none; }
#footer a:hover { color: #00ADEF; text-decoration: none; }
#footer table { font-size: 8pt; }
#footer tr { background-color: transparent; }

View file

@ -0,0 +1,77 @@
/* flamesgif.com */
body {
color: black;
background-color: silver;
font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
font-size: 84%; /* Enables font size scaling in MSIE */
margin: 0;
padding: 0;
}
a { text-decoration: none; color: blue; }
a:hover { color: purple;}
blockquote {
border-left: none;
font-style: none;
background-color: silver;
}
li:hover { color: purple }
li a { color: blue }
li a:hover { color: purple; }
h1 { font-size: 10pt; }
h2, h3, h1, h4 { color : blue; }
hr {
border-width: 0px 0px 0.1em 0px;
border-color: transparent;
}
input , textarea, select, option { background-color: blue; border: none; }
pre, code, blockquote {
font-family: Courier, 'Lucida Console','Courier New', Serif;
margin-left: 2em;
font-size: 1.2em;
}
table { border: none; }
th {
background-color: transparent;
border: none;
text-align: center;
}
td {
background-color: transparent;
border: none;
}
ul { list-style: none; padding-left: 0px; margin: 0px }
#center {
width: 600px;
margin-left: auto;
margin-right: auto;
}
#center h1 { font-size 9pt; }
#footer {
font-size: 8pt;
background-color: silver;
color: blue;
margin-left: auto;
margin-right: auto;
}
#footer a { color: blue; text-decoration: none; }
#footer a:hover { color: purple; text-decoration: none; }
#footer table { font-size: 8pt; }
#right {
float: right;
position: absolute;
top: 210px;
right: 1px;
width: 25%;
height: 100%;
list-style: none;
}
#sidebar {
position: relative;
z-index: 100;
width: 95%;
top: 10px;
right: 10px;
left: 10px;
margin: 2px;
background: silver;
}

53
werc/apps/barf/pub/img.css Executable file
View file

@ -0,0 +1,53 @@
/* img.stanleylieber.com */
body { display: flex; flex-wrap: wrap; font-family: sans; }
header { flex-basis: 99%; flex-shrink: 0; padding-left: 1em; padding-bottom: 1em; }
article { flex-basis: 99%; padding: 0; }
footer { flex-basis: 99%; flex-shrink: 0; }
header nav { display: flex; justify-content: space-between; }
footer { display: flex; justify-content: space-between; }
body { margin:0; padding: 0; font-size: 10pt; font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; background-color: #000000; color: #FFFFFF; }
a { text-decoration: none; color: #FFFFFF; background-color: #000000; font-weight: bold; }
a:hover { text-decoration: none; background-color: #FFFFFF; color: #000000; }
/* header and top bar */
header h3 { padding-bottom: 2px; }
header a img { vertical-align: bottom; padding-top: 1em; }
/* main copy */
article { padding-left: 1em; padding-right: 1em; }
article nav { padding-bottom: 2px; }
article div { padding-top: 2px; padding-bottom: 2px; }
article h1, article h2, article h3, article h4, article h5, article h6, article h7, article h8 {
font-weight: bold; margin: 0; padding-bottom: 2px;
}
article a img { vertical-align: bottom; }
article img { max-width: 100%!important; }
article iframe { max-width: 100%!important; }
article video { max-width: 100%!important; }
article fieldset { color: #FFFFFF; border-color: #FFFFFF; }
article legend { color: #FFFFFF; border-color: #FFFFFF; }
/* footer */
footer > nav { margin-left: auto; padding: 1em; }
/* fixed-width fonts */
pre, code { white-space: pre-wrap!important; }
pre, code, blockquote {
max-width: 100%!important;
font-family: Courier, 'Lucida Console','Courier New', Serif;
}
/* input */
input, textarea, select, option {
font-family: Sans-Serif;
font-size: 100%;
padding: 2px;
border-top: solid 1px #FFFFFF;
border-bottom: solid 1px #FFFFFF;
border-left: solid 1px #FFFFFF;
border-right: solid 1px #FFFFFF;
background-color: #000000;
color: #FFFFFF;
margin: 2px;
}

417
werc/apps/barf/pub/inri.css Executable file
View file

@ -0,0 +1,417 @@
/* inri.net */
body {
font-family :'Lucida Sans Unicode','Lucida Sans', 'Trebuchet MS', 'Lucida Grande', 'Bitstream Sans Vera', Verdana, Arial, Tahoma, Helvetica, Sans-Serif;
font-style : normal;
padding: 2px 2em;
line-height: 1.5em;
font-size: 70%;
background: #FFF;
color: #111;
}
/* # Header # */
.superHeader {
color: white;
background-color: gray;
height: 1.6em;
}
.superHeader img { vertical-align: bottom; }
.superHeader a {
color: white;
background-color: transparent;
font-size: 91%;
margin: 0;
padding: 0 0.5ex 0 0.25ex;
}
a { text-decoration: none; }
a:hover { text-decoration: underline; }
.superHeader div {
position: absolute;
top: 0.40ex;
}
.superHeader .left { left: 0.4em; }
.superHeader .right { right: 0.4em; }
.midHeader {
color: gray;
background-color: gray;
background-color: #ff6d06;
border: solid 0 black;
border-width: 2px 0;
}
.headerTitle {
color: black;
font-size: 233%;
font-weight: normal;
margin: 0 0 0 4mm;
padding: 0.25ex 0;
}
#headerSubTitle {
font-size: 50%;
font-style: italic;
margin-left: 1em;
}
.headerTitle a { color: black; }
.headerTitle a:hover { text-decoration: none; }
.subHeader {
display: none;
color: white;
background-color: gray;
margin: 0;
padding: 1ex 1ex 1ex 1.5mm;
}
.subHeader a {
color: white;
background-color: transparent;
font-weight: bold;
margin: 0;
padding: 0 0.75ex 0 0.5ex;
}
.superHeader .highlight, .subHeader .highlight {
color: gray;
background-color: transparent;
}
/* # Side # */
#side-bar {
width: 16em;
float: left;
clear: left;
border-right: 1px solid white;
}
#side-bar div {
border-bottom: 1px solid white;
}
.sideBarTitle {
font-weight: bold;
margin: 0 0 0.5em 2mm;
padding: 1em 0 0 0;
}
#side-bar ul {
list-style-type: none;
list-style-position: outside;
margin: 0;
padding: 0 0 0.3em 0;
}
li ul {
padding-left: 0.6em !important;
}
#side-bar li {
margin: 0;
padding: 0.1ex 0; /* Circumvents a rendering bug (?) in MSIE 6.0 XXX should move to iehacks.css, this causes an ugly gap */
}
#side-bar a {
color: gray;
background-color: transparent;
margin: 0;
padding: 0.25em 1ex 0.25em 2mm;
display: block;
text-transform: capitalize;
font-weight: bold!important;
font-size: 102%;
border-left: white solid 0.2em;
}
.thisPage, .thisPage a {
color: black!important;
background-color: white;
padding-left: 5mm;
}
#side-bar a:hover {
color: black;
background-color: gray;
border-left: gray solid 0.2em;
text-decoration: none;
}
.sideBarText {
line-height: 1.5em;
margin: 0 0 1em 0;
padding: 0 1.5ex 0 2.5mm;
display: block;
}
#side-bar .sideBarText a {
margin: 0;
padding: 0;
display: inline;
}
#side-bar .sideBarText a:hover {
color: gray;
background-color: transparent;
text-decoration: none;
}
/* # Main Copy # */
#main-copy {
max-width: 70em;
color: black;
background-color: transparent;
text-align: justify;
line-height: 1.5em;
margin: 0em 0 0 16em;
padding: 0.5mm 5mm 5mm 5mm;
border-left: 1px solid white;
}
#bodyText {
margin: 0 0 0 15.5em;
padding: 2mm 5mm 2mm 5mm;
}
#main-copy p {
margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */
padding: 0;
}
#main-copy a {
color: gray;
background-color: transparent;
}
#main-copy a:hover {
color: gray;
}
#main-copy h1, #main-copy h2 {
color: gray;
background-color: transparent;
font-size: 145.5%;
font-weight: bold;
margin: 2em 0 0 0;
padding: 0.5ex 0 0.5ex 0.6ex;
border-bottom: 2px solid gray;
}
#main-copy h2 {
font-size: 115.5%;
border-bottom: 1px solid gray;
}
#main-copy .topOfPage {
color: gray;
background-color: transparent;
font-size: 91%;
font-weight: bold;
text-decoration: none;
margin: 3ex 1ex 0 0;
padding: 0;
float: right;
}
#post {
position: relative;
left: 23%;
width: 76%;
padding-top: 25px;
padding-bottom: 25px;
}
#post tr { background-color: transparent; }
#center {
position: absolute;
top: 210px;
left: 1%;
width: 65%;
height: 100%;
}
#center h1 { font-size 8pt; font-family :'Lucida Sans Unicode','Lucida Sans', 'Trebuchet MS', 'Lucida Grande', 'Bitstream Sans Vera', Verdana, Arial, Tahoma, Helvetica, Sans-Serif; }
a { text-decoration: none; color: #000000; }
a:hover { color: #111;}
li:hover { color: #111 }
li a { color: #000000 }
li a:hover { color: #111; }
ul { list-style: none; padding-left: 0px; margin: 0px }
h1 { font-size: 8pt; font-weight: normal; }
h2 { font-size : 140%; }
h3 { font-size: 120%; }
h4 { font-size: 100%; }
h2, h3, h1, h4 {
font-family: Georgia,'Trebuchet MS', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Verdana, Arial, Tahoma, Helvetica, Sans-Serif;
color : #000000;
margin: 0px 0px;
padding: 2px 0px;
clear: both;
}
input , textarea, select, option { background-color: #eee; border: none; }
dl {
margin: 1em 1ex 2em 1ex;
padding: 0;
}
dt {
font-weight: bold;
margin: 0 0 0 0;
padding: 0;
}
dd {
margin: 0 0 2em 2em;
padding: 0;
}
#right {
float: right;
position: absolute;
top: 210px;
right: 1px;
width: 34%;
height: 100%;
list-style: none;
}
/* sidebar */
#sidebar {
position: relative;
z-index: 100;
width: 95%;
top: 10px;
right: 10px;
left: 10px;
margin: 2px;
background: #FFFFFF;
}
#sidebar h2 {
margin: 5px 0px 0px;
padding: 4px 0px;
font-size:100%;
}
#sidebar li { font-size: 8.5pt; }
#sidebar ul { margin: 2px; }
/*searchform*/
#searchform label { font-weight:bold; }
#searchform input { width: 20%; }
#searchform input.submit { width: 16%; }
#top {
float: top;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
height: 10%;
width: 100%
overflow: auto;
}
/* # Footer # */
#footer {
font-size: 8pt;
background-color: white;
color: black;
}
#footer a { color: gray; text-decoration: none; }
#footer a:hover { color: #111; text-decoration: none; }
#footer table { font-size: 8pt; }
#footer .left {
text-align: left;
line-height: 1.55em;
float: left;
clear: left;
}
#footer .right {
text-align: right;
line-height: 1.45em;
}
/* GENERAL */
table {
background-color: transparent;
border: none;
}
tr {
background-color: transparent;
border: none;
}
th {
background-color: transparent;
border: none;
text-align: center;
}
td {
background-color: transparent;
border: none;
}
hr {
border-width: 0px 0px 0.1em 0px;
border-color: transparent;
}
acronym, .titleTip {
border-bottom: 1px solid #ddd;
cursor: help;
margin: 0;
padding: 0 0 0.4px 0;
}
pre {
margin-left: 2em;
font-size: 1.2em;
}
blockquote {
border-left: none;
font-style: none;
background-color: silver;
}
.smallCaps {
font-size: 110%;
font-variant: small-caps;
}
.doNotDisplay { display: none; }
.notify_errors,
.notify_notes,
.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; }
.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; }
.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
.notify_errors a { color: #8a1f11; }
.notify_notes a { color: #514721; }
.notify_success a { color: #264409; }
/* # Page/Handler specific # */
h1.dir-list-head, ul.dir-list {
text-transform: capitalize;
font-weight: bold;
}
ul.sitemap-list a {
text-transform: capitalize;
}

View file

@ -0,0 +1,62 @@
/* mf */
body {
color: #a6a6a6;
background-color: #626060;
font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
font-size: 84%; /* Enables font size scaling in MSIE */
margin: 0;
padding: 0;
}
a { text-decoration: none; color: #a6a6a6; }
a:hover { background-color: #a6a6a6; color: #626060; text-decoration: none; }
a img { display: block; border: 0 none; }
li:hover { background-color: #a6a6a6; color: #626060; text-decoration: none; }
li a { color: #a6a6a6 }
li a:hover { background-color: #a6a6a6; color: #626060; text-decoration: none; }
li ul { padding-left: 0.6em !important; }
h1 { font-size: 10pt; font-weight: normal; }
h2 { font-size: 9pt; font-weight: normal; }
input , textarea, select, option { background-color: #a6a6a6; border: none; }
table { border: none; background-color: transparent; }
th {
background-color: transparent;
border: none;
text-align: center;
}
tr:nth-child(odd) { background-color: transparent; }
td {
background-color: transparent;
border: none;
}
hr {
border-width: 0px 0px 0.1em 0px;
border-color: transparent;
}
pre, code, blockquote {
font-family: Courier, 'Lucida Console','Courier New', Serif;
margin-left: 2em;
font-size: 1.2em;
}
blockquote {
border-left: none;
font-style: none;
background-color: #a6a6a6;
}
#header {
margin-left: auto;
margin-right: auto;
}
#center {
width: 500px;
margin-left: auto;
margin-right: auto;
}
#center h1 { font-size 9pt; }
#footer {
font-size: 8pt;
background-color: #626060;
color: #a6a6a6;
}
#footer a { color: #a6a6a6; text-decoration: none; }
#footer a:hover { color: #626060; text-decoration: none; }
#footer table { font-size: 8pt; }

58
werc/apps/barf/pub/okturing.css Executable file
View file

@ -0,0 +1,58 @@
/* okturing.com */
body { display: flex; flex-wrap: wrap; font-family: sans; }
header { flex-basis: 100%; flex-shrink: 0; }
article { flex-basis: 100%; padding: 1em; }
footer { flex-basis: 100%; flex-shrink: 0; }
header nav { display: flex; justify-content: space-between; }
nav a, header a { text-decoration: none ; color: inherit; }
header h1 span { margin-left: 1em; font-size: 50%; font-style: italic; }
body > nav { flex-basis: content; padding-right: 1vw; min-width: 16em; }
nav ul { display: flex; flex-direction: column; list-style-type: none; list-style-position: outside; padding-left: 0; }
nav li ul { padding-left: 0.6em }
footer { display: flex; justify-content: space-between; }
/* cut here to leave vanity behind */
body { margin:0; padding: 0; font-size: 84%; font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif; background-color: #FFFFFF; color: #000000; }
a:hover { text-decoration: none; background-color: #FFFFFF; color: #000000; }
/* header and top bar */
header nav { background-color: #FFFFFF; color: #000000; padding: 0em; border-bottom: 2px solid #FFFFFF; font-size: 91%; }
header h1 { background-color: #FFFFFF; color: #000000; margin: 0; border-bottom: 2px solid #FFFFFF; font-weight: normal; padding: 0.25ex; font-size: 233%; }
/* sidebar */
body > nav { border-right: 1px solid #FFFFFF; padding: 0; }
body > nav > div { border-bottom: 1px solid #FFFFFF; }
body > nav > div a { background-color: #00ff00; color: #000000; display: block; text-transform: capitalize; font-weight: bold; padding: 0.25em 1ex 0.25em 2mm; font-size: 102%}
body > nav > div a:hover { color: #FFFFFF; background-color: #000000 border-left: #FFFFFF solid 0.2em; text-decoration: none; }
body > nav > div p { font-weight: bold; margin: 0 0 0.5em 2mm; padding: 1em 0 0 0; }
/* main copy */
article { padding: 1em; }
article h1, article h2 { color: #000000; font-weight: bold; margin: 2em 0 0 0; border-bottom: 2px solid #FFFFFF; }
article h3, article h4, article h5 { #000000; font-weight: bold; margin: 2em 0 0 0; }
article h6, article h7, article h8 { color: #000000; font-weight: bold; margin: 2em 0 0 0; }
article a { background-color: #FFFFFF; color: #000000; text-decoration: none; }
article a:hover { text-decoration: none; background-color: #000000; color: #FFFFFF; }
article a img { display: block; border: 0 none; }
/* footer */
footer { color: #000000; background-color: #FFFFFF; }
footer a { background-color: #FFFFFF; color: #000000; }
footer div { padding: 1em; }
input, textarea, select, option {
font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
font-size:100%;
padding: 2px;
background : #eee;
color : #111;
border: 1px solid #fff;
margin: 2px;
}
pre, code, blockquote {
white-space: pre-wrap;
padding-left: 2em;
font-family: Courier, 'Lucida Console','Courier New', Serif;
}

345
werc/apps/barf/pub/osx.css Executable file
View file

@ -0,0 +1,345 @@
/* osx.stanleylieber.com */
body {
font-family :Helvetica, Verdana, Arial, Sans-Serif;
font-style : normal;
padding: 2px 2em;
line-height: 1.5em;
font-size: 70%;
background: #FFF;
color: #111;
}
/* font styles */
a { text-decoration: none; color: #000000; }
a:hover { background: #7600FC; color: #fff; }
li:hover { color: #000000; }
li a { color: #000000; }
li a:hover { background: #7600FC; color: #fff; }
ul { list-style: none; padding-left: 0px; margin: 0px }
p {
font-size : 100%;
font-style : normal;
padding: 0px;
}
h2 {
font-size : 140%;
}
h3 {
font-size: 120%;
}
h4 {
font-size: 100%;
}
h2, h3, h1, h4 {
font-family: Helvetica, Verdana, Arial, Sans-Serif;
color : #000000;
margin: 0px 0px;
padding: 2px 0px;
clear: both;
}
/* end font styles */
hr {
border: 1px solid #fff;
}
blockquote, code {
background : #eee;
padding: 6px;
border-left: 3px solid #eee;
}
code, pre {
font-family: Courier, 'Lucida Console','Courier New', Sans-Serif;
}
#admin_banner {
position: relative;
text-align: center;
}
#admin_body {
position: relative;
top: 100px;
left: 10px;
width: 90%;
}
#admin_frames {
height: 100%;
float: top;
/* for ie */
margin: 0;
overflow: auto;
/* end for ie */
}
#admin_index_body {
position: relative;
top: 100px;
margin-left: auto;
margin-right: auto;
}
#admin_menu {
position: relative;
left: 10px;
width: 90%;
text-align: left;
}
#admin_table {
margin-left: auto;
margin-right: auto;
width: 90%;
border-collapse: collapse;
border-color: #111;
font-family: sans-serif;
font-size: 9pt;
}
#admin_table td {
vertical-align: middle;
text-align: center;
}
#admin_table th {
background: #111;
color: gray;
}
#bottom {
float: bottom;
position: absolute;
bottom: 10px;
}
#button input.submit {
background: #111;
color: gray;
border-top: solid 1px #111;
border-bottom: solid 1px #111;
border-left: solid 1px #111;
border-right: solid 1px #111;
width: 15%;
}
#center {
position: absolute;
top: 155px;
left: 1%;
width: 65%;
height: 100%;
}
#divider {
background: #111;
height: 1px;
}
/*forms*/
input , textarea, select, option {
font-family : Helvetica, Verdana, Arial, Sans-Serif;
font-size:100%;
padding: 2px;
background : #eee;
color : #111;
border: 1px solid #fff;
margin: 2px;
}
fieldset, legend {
background:transparent;
color : #111;
border: none;
padding: 5px;
}
label, legend {
font-weight:normal;
}
#header {
float: top;
position: absolute;
top: 0px;
left: 17%;
height: 100%;
font-size: 24pt;
background: #7600FC;
height: 50px;
}
#header a {
background: #7600FC;
color: #fff;
}
#left {
float: left;
position: absolute;
top: 0px;
left: 10%;
width: 15%;
height: 100%;
list-style: none;
overflow: auto;
}
#meta {
font-size: 8pt;
}
#page_frames {
width: 100%;
float: left;
/* for ie */
margin: 0;
overflow: auto;
/* end for ie */
}
#page_category {
position: relative;
text-align: center;
}
#page_list {
text-align: right;
font-size: 9pt;
}
#page_login {
position: relative;
text-align: right;
font-size: 8pt;
}
#page_upload {
background: #111; color: #444; font-weight: bold
}
#post {
position: relative;
left: 13%;
width: 86%;
padding-bottom: 100px;
}
#post_body {
position: relative;
top: 10px;
bottom: 10px;
left: 10px;;
}
#post_date {
font-size: 8pt;
}
#post_meta {
margin-left: 2px;
color: #111;
font-size: 8pt;
}
#post_tags {
font-size: 8pt;
}
#post_thumb {
margin-top: 5px;
margin-bottom: 5px;
}
#post_title {
border: 1px;
line-height: 1.5em;
}
#post_title a {
background: red;
color: #fff;
}
#post_title a:hover {
background: #7600FC;
color: #fff;
}
#post_title h2 {
font-weight: 100;
}
#registration_body {
left: 10px;
text-align: left;
}
#right {
float: right;
position: absolute;
top: 150px;
right: 1%;
width: 33%;
height: 100%;
list-style: none;
}
#rss {
margin-left: auto;
margin-right: auto;
text-align: center;
font-size: 8pt;
}
/* sidebar */
#sidebar {
position: relative;
z-index: 100;
width: 90%;
top: 10px;
right: 10px;
left: 10px;
margin: 2px;
background: #FFFFFF;
}
#sidebar h2 {
margin: 5px 0px 0px;
padding: 4px 0px;
font-size:100%;
}
#sidebar ul {
margin: 2px;
}
/*searchform*/
#searchform label {
font-weight:bold;
}
#searchform input#s {
width: 40%;
}
#searchform input.submit {
width: 16%;
}
#top {
float: top;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
height: 10%;
width: 100%
overflow: auto;
}
.warning {
color: #111;
font-weight: bold;
}

67
werc/apps/barf/pub/other.css Executable file
View file

@ -0,0 +1,67 @@
/* other */
body {
color: blue;
background-color: white;
font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
font-size: 84%; /* Enables font size scaling in MSIE */
margin: 0;
padding: 0;
}
a { text-decoration: none; color: blue; }
a:hover { color: purple; background-color: white; text-decoration: none; }
li:hover { color: purple; background-color: white; text-decoration: none; }
li a { color: blue; }
li a:hover { color: purple; background-color: white; text-decoration: none; }
h1 { font-size: 10pt; font-weight: normal; }
h2 { font-size: 9pt; font-weight: normal; }
input , textarea, select, option { background-color: #eee; border: none; }
li ul {
padding-left: 0.6em !important;
}
table { border: none; background-color: transparent; }
th {
background-color: transparent;
border: none;
text-align: center;
}
tr:nth-child(odd) { background-color: transparent; }
td {
background-color: transparent;
border: none;
}
hr {
border-width: 0px 0px 0.1em 0px;
border-color: transparent;
}
pre, code, blockquote {
Courier, 'Lucida Console','Courier New', Serif;
margin-left: 2em;
font-size: 1.2em;
}
blockquote {
border-left: none;
font-style: none;
background-color: #eee;
}
#center {
width: 500px;
margin-left: auto;
margin-right: auto;
line-height: 0;
}
/* #center p {
line-height: 1;
-webkit-margin-before: 0px;
-webkit-margin-after: 0px;
} */
#footer {
font-size: 8pt;
background-color: white;
color: blue;
margin-left: auto;
margin-right: auto;
}
#footer a { color: blue; text-decoration: none; }
#footer a:hover { color: purple; background-color: white; text-decoration: none; }
#footer table { font-size: 8pt; }
#text { line-height: 1; }

29
werc/apps/barf/pub/read.css Executable file
View file

@ -0,0 +1,29 @@
/* black */
header { flex-basis: 99%; flex-shrink: 0; padding-left: 1em; padding-bottom: 1em; }
header h3 { padding-bottom: 2px; }
header a img { vertical-align: bottom; padding-top: 1em; }
body { font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; background-color: #000000; color: #FFFFFF; }
a { text-decoration: none; color: #FFFFFF; background-color: #000000; font-weight: bold; }
a:hover { text-decoration: none; background-color: #FFFFFF; color: #000000; }
/* footer */
footer > nav { margin-left: auto; padding: 1em; }
/* fixed-width fonts */
pre, code { white-space: pre-wrap!important; }
pre, code, blockquote {
max-width: 100%!important;
font-family: Courier, 'Lucida Console','Courier New', Serif;
}
/* input */
input, textarea, select, option {
font-family: Sans-Serif;
font-size: 100%;
padding: 2px;
border-top: solid 1px #FFFFFF;
border-bottom: solid 1px #FFFFFF;
border-left: solid 1px #FFFFFF;
border-right: solid 1px #FFFFFF;
background-color: #000000;
color: #FFFFFF;
margin: 2px;
}

View file

@ -0,0 +1,64 @@
/* nothing */
body {
display: flex;
flex-wrap: wrap;
color: black;
background-color: white;
font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
font-size: 84%; /* Enables font size scaling in MSIE */
margin: 0;
padding: 0;
}
header, article, footer { flex-basis: 100%; }
a { text-decoration: none; color: gray; }
a:hover { color: #111; text-decoration: none; }
a img { display: block; border: 0 none; }
li:hover { color: #111; text-decoration: none; }
li a { color: gray }
li a:hover { color: #111; text-decoration: none; }
li ul { padding-left: 0.6em !important; }
h1 { font-size: 10pt; font-weight: normal; }
h2 { font-size: 9pt; font-weight: normal; }
input , textarea, select, option { background-color: gray; border: none; }
table { border: none; background-color: transparent; }
th {
background-color: transparent;
border: none;
text-align: center;
}
tr:nth-child(odd) { background-color: transparent; }
td {
background-color: transparent;
border: none;
}
hr {
border-width: 0px 0px 0.1em 0px;
border-color: transparent;
}
pre, code, blockquote {
font-family: Courier, 'Lucida Console','Courier New', Serif;
margin-left: 2em;
font-size: 1.2em;
}
blockquote {
border-left: none;
font-style: none;
background-color: gray;
}
#center {
width: 500px;
margin-left: auto;
margin-right: auto;
}
#center h1 { font-size 9pt; }
#footer {
font-size: 8pt;
background-color: white;
color: gray;
margin-left: auto;
margin-right: auto;
}
#footer a { color: gray; text-decoration: none; }
#footer a:hover { color: #111; text-decoration: none; }
#footer table { font-size: 8pt; }

195
werc/apps/barf/pub/url.css Executable file
View file

@ -0,0 +1,195 @@
/* url.stanleylieber.com */
body {
font-family: Vera, Helvetica, Verdana, Arial, Sans-Serif;
font-style: normal;
padding: 2px 2em;
line-height: 1.5em;
font-size: 70%;
background: #FFFFFF;
color: #000000;
}
a { text-decoration: none; color: #000000; }
a:hover { background: #EEEEEE;}
li:hover { background: #EEEEEE; }
li a:hover { background: #EEEEEE; }
ul { list-style: none; }
p {
font-size : 100%;
font-style : normal;
padding: 0px;
}
h2 { font-size : 140%; }
h3 { font-size: 120%; }
h4 { font-size: 100%; }
h2, h3, h1, h4 {
margin: 0px 0px;
padding: 2px 0px;
clear: both;
}
hr { border: 1px solid #fff; }
input {
background-color: #EEEEEE;
}
code, pre { font-family: Courier, 'Lucida Console','Courier New', Sans-Serif; }
blockquote, code {
background : #eee;
padding: 6px;
border-left: 3px solid #eee;
}
td {
padding: 10px;
border-width: 1px;
border-style: solid;
border-collapse: collapse;
border-color: #000000;
background: #FFFFFF;
}
textarea {
height: 300px;
background-color: #EEEEEE;
}
tr {
border-width: 1px;
border-style: solid;
border-collapse: collapse;
border-color: #000000;
}
#add {
position: relative;
top: 65px;
left: 9%;
font-size: 10pt;
}
#blank {
border-width: 1px;
border-style: solid;
border-collapse: collapse;
border-color: #FFFFFF;
}
#bottom {
float: bottom;
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
width: 100%;
}
#center {
position: relative;
margin-left: auto;
margin-right: auto;
top: 130px;
width: 90%;
height: 100%;
}
#edit {
width: 750px;
font-size: 10pt;
}
#footer {
position: relative;
margin-left: auto;
margin-right: auto;
bottom: 100px;
}
#header {
position: relative;
margin-left: auto;
margin-right: auto;
top: 40px;
width: 83%;
}
#logo { font-size: 40pt; color: #DDDDDD; }
#logo a { font-size: 40pt; color: #CCCCCC; }
#logo a:hover { background: #EEEEEE;}
#list {
position: relative;
margin-left: auto;
margin-right: auto;
top: 90px;
width: 90%;
height: 100%;
}
#meta { font-size: 8pt; }
#page_list {
margin: 20px;
text-align: right;
font-size: 9pt;
}
#post {
position: relative;
padding: 20px;
}
#post_meta { text-align: center; }
#post_date {
width: 200px;
text-align: center;
font-size: 8pt;
}
#post_edit {
width: 100px;
text-align: center;
font-size: 8pt;
}
#post_table {
position: relative;
margin-left: auto;
margin-right: auto;
padding: 0px;
width: 100%;
border-collapse: collapse;
}
#post_tags {
text-align: left;
font-size: 8pt;
}
#post_title {
text-align: left;
font-size: 10pt;
}
#search {
position: absolute;
top: 90px;
right: 9%;
font-size: 10pt;
}
#top {
float: top;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
height: 100px;
width: 100%;
}

View file

@ -0,0 +1 @@
Trust, but verify.

View file

@ -0,0 +1 @@
Thu Aug 25 18:35:52 CDT 2011

View file

@ -0,0 +1 @@
http://plan9.stanleylieber.com/9front

View file

View file

View file

View file

@ -0,0 +1 @@
This is a BULGE demo post.

3
werc/apps/barf/tags Executable file
View file

@ -0,0 +1,3 @@
1/tags/theory
1/tags/random
1/tags/demo

148
werc/apps/blagh/app.rc Normal file
View file

@ -0,0 +1,148 @@
fn conf_enable_blog {
blagh_uri=$conf_wd
blagh_dirs=$*
if(~ $#blagh_dirs 0)
blagh_dirs=( . )
conf_enable_app blagh
if(~ $"conf_blog_editors '')
conf_blog_editors=blog-editors
if(~ $"conf_blog_only_pull '')
conf_blog_only_pull=0
if(~ $"conf_max_posts_per_page '')
conf_max_posts_per_page=32
}
fn blagh_init {
if(~ $#blagh_dirs 0 && ~ $req_path */[bB]log/*) {
blagh_uri=`{echo $req_path | sed 's,(/[bB]log/).*,\1,'}
blagh_dirs=( . )
}
# Should not match sub-dirs!
if(! ~ $#blagh_dirs 0) {
# && test -d / `{echo '-a -d '^$blagh_root^$blagh_dirs}
blagh_url=$base_url^$blagh_uri
blagh_root=$sitedir^$blagh_uri
if(check_user $conf_blog_editors && ! ~ $"conf_blog_only_pull '1') {
editor_mode=on
if(~ $"post_arg_date '')
post_date=`{/bin/date -I|sed 's,-,/,g'}
if not
post_date=$post_arg_date
ll_add handlers_bar_left echo '<a href="'$blagh_uri'new_post">Make a new post</a>'
}
if(~ $req_path $blagh_uri) {
handler_body_main=blagh_body
u=$blagh_uri'index'
extraHeaders=$"extraHeaders ^ \
'<link rel="alternate" type="application/atom+xml" title="ATOM" href="'$"u'.atom" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="'$"u'.rss" />
<link rel="alternate" type="application/json" title="JSON" href="'$"blagh_uri'feed.json" />'
}
if not if(~ $req_path $blagh_uri^index.atom)
blagh_setup_feed_handlers atom.tpl 'application/atom+xml'
if not if(~ $req_path $blagh_uri^index.rss)
blagh_setup_feed_handlers rss20.tpl 'text/xml; charset=utf-8'
if not if(~ $req_path $blagh_uri^feed.json)
blagh_setup_feed_handlers jsonfeed.tpl 'application/json; charset=utf-8'
if not if(~ $req_path $blagh_uri^new_post && ! ~ $#editor_mode 0) {
handler_body_main=( tpl_handler `{get_lib_file blagh/new_post.tpl apps/blagh/new_post.tpl} )
if(~ $REQUEST_METHOD POST) {
if(mkbpost $"post_arg_body $"post_date $"post_arg_title $post_arg_id)
post_redirect $blagh_uri
if not
notify_errors=$status
}
}
}
}
fn blagh_setup_feed_handlers {
handler_body_main=NOT_USED_by_blagh_feeds
res_tail=()
http_content_type=$2
headers=()
master_template=apps/blagh/$1 # Should we allow tempalte override?
}
fn blagh_body {
echo '<div class="bfeed">'
if (! ~ $"blogTitle '')
echo '<h1>'$"blogTitle'</h1>'
# Direct links to feeds are disabled because they are not very useful, add clutter and might waste pagerank.
# An user can add this on their own using handlers_body_head anyway.
#echo '<div style="text-align:right">(<a href="index.rss">RSS Feed</a>|<a href="index.atom">Atom Feed</a>)</div>'
# XXX Not sure why this fixes issues with blog setup, probably bug in fltr_cache!
for(p in `{get_post_list $blagh_root^$blagh_dirs}) {
l=`{echo -n $p|sed 's!'$sitedir^'/?(.*)([0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9])(/[^/]+/)!\2 /\1\2\3!'}
sed '1s!.*![&]('^$l(2)^') ('^$l(1)^')!' < $p/index.md |
sed 's!\([0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]\)!<div class="date">&</div>!'
echo # Needed extra \n so markdown doesn't mess up the formatting, probably can be done in sed.
} | $formatter
# XXX BUG! Markdown [references] break because multiple markdown documents are merged. Should format each blog post independently.
# TODO: use fltr_cache directly, that can fix the previous bug plus provide a perf boost by caching title generation.
echo '</div>'
}
fn get_post_list {
# /./->/|/ done to sort -t| and order by date
# Note: $paths in blagh_dirs should not contain '/./' or '|'
ls -F $*^/./[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]/ >[2]/dev/null | sed -n '/'^$forbidden_uri_chars^'/d; s,/\./,/|/,; /\/$/p' | sort -r '-t|' +1 | sed -e 's,/+\|/+,/,' -e $conf_max_posts_per_page^'q'
}
fn mkbpost {
bptext=$1
bpdate=$2
bptitle=$3
bpid=$4
_status=()
if(~ $"bptext '')
_status=($_status 'You need to provide a post body.')
if(! ~ $"bpdate [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9])
_status=($_status 'Invalid date: '''^$"bpdate^'''') # XXX Should make semantic check.
if(~ $#_status 0) {
umask 002 # Let group write
if(! ~ $"bpid '')
bpid=`{echo -n '-'^$bpid | sed 's/'$forbidden_uri_chars'+/_/g; 1q'}
ddir=$blagh_root^$bpdate^'/'
n=`{ls $ddir >[2]/dev/null |wc -l}
mkdir -p $ddir/$"n^$"bpid/
{
if(! ~ $"bptitle '') {
echo $bptitle
echo '-------------------------------------'
}
# TODO: Enable metadata
#echo '* Posted:' `{date}
#if(! ~ $#logged_user 0)
# echo '* Author: '$logged_user
echo
echo $bptext
}> $ddir/$"n^$"bpid/index.md
# Experimental support for http://pubsubhubbub.googlecode.com/
if(! ~ $"conf_blog_pubsubdub_hub '') {
ifs='' { p=`{echo $req_url|sed 's/new_post$/index.atom/'|url_encode } }
dprint hget -p 'hub.mode=publish&hub.url='^$"p $conf_blog_pubsubdub_hub
hget -d -h -p 'hub.mode=publish&hub.url='^$"p $conf_blog_pubsubdub_hub >[1=2] &
}
}
status=$_status
}
fn strip_title_from_md_file {
sed '1N; /^.*\n===*$/N; /.*\n===*\n$/d'
}

58
werc/apps/blagh/atom.tpl Normal file
View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
%{
# See for more info:http://www.tbray.org/ongoing/When/200x/2005/07/27/Atomic-RSS
fn statpost {
f = $1
post_uri=$base_url^`{cleanname `{echo $f | sed -e 's!^'$sitedir'!!'}}^'/'
title=`{read $f/index.md}
by=`{ls -m $f | sed 's/^\[//g; s/].*$//g' >[2]/dev/null}
ifs=() { summary=`{cat $f/index.md | strip_title_from_md_file | ifs=$difs {$formatter} } }
}
# rfc3339 date when feed was last updated.
fupdated = `{ndate -a `{date `{mtime `{ls $blagh_root$blagh_dirs/[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]/[0-9] | tail -1} | awk '{print $1}'}}}
%}
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:thr="http://purl.org/syndication/thread/1.0">
% if(! ~ $"conf_blog_pubsubdub_hub '') {
% echo '<link rel="hub" href="'$conf_blog_pubsubdub_hub'" />'
% }
<link rel="self" href="%($base_url^$req_path%)"/>
<id>%($base_url^$req_path%)</id>
<icon><![CDATA[/favicon.ico]]></icon>
<title><![CDATA[%($siteTitle%)]]></title>
<subtitle><![CDATA[%($siteSubTitle%)]]></subtitle>
<updated>%($fupdated%)</updated>
<link href="."/>
% for(f in `{get_post_list $blagh_root$blagh_dirs}) {
% statpost $f
<entry>
% # Maybe we should be smarter, see: http://diveintomark.org/archives/2004/05/28/howto-atom-id, example: <id>tag:intertwingly.net,2004:2899</id>
<id>%($post_uri%)</id>
<link href="%($post_uri%)"/>
<title><![CDATA[%($title%)]]></title>
% # <link rel="replies" href="2899.atom" thr:count="0"/>
<author><name><![CDATA[%($by%)]]></name></author>
<content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">
<![CDATA[%($summary%)]]>
</div></content>
% # rfc3339 date when entry was last updated.
% eupdated=`{ndate -a `{date `{mtime $f | awk '{print $1}'}}}
<updated>%($eupdated%)</updated>
</entry>
% }
</feed>
% exit

20
werc/apps/blagh/convert.rc Executable file
View file

@ -0,0 +1,20 @@
#!/usr/bin/env rc
path=($PLAN9/bin/ $path)
for(p in *.md) {
echo
echo '========================='
echo p $p
pp=`{echo $p | sed 's/^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])[\-_](.*).md$/\1 \2 \3 \4/' }
echo pp $pp
d=$pp(1)^'/'^$pp(2)^'/'^$pp(3)^'/'^$pp(4)^'/'
mkdir -p $d
echo $pp(4) | sed -e 's/^[0-9]_//; s/_/ /g;' > $d/index.md
echo '=================================' >> $d/index.md
echo >> $d/index.md
cat $p >> $d/index.md
}

View file

@ -0,0 +1,35 @@
{
"version": "https://jsonfeed.org/version/1",
"title": "%($siteTitle%)",
"home_page_url": "%($"base_url%)",
"feed_url": "%($"base_url^$"req_path%)",
"items": [
%{
fn statpost {
f = $1
post_uri=$base_url^`{cleanname `{echo $f | sed -e 's!^'$sitedir'!!'}}^'/'
title=`{read $f/index.md}
#ifs=() { summary=`{cat $f/index.md | crop_text 1024 ... | $formatter } }
ifs=() { summary=`{cat $f/index.md | strip_title_from_md_file | ifs=$difs {$formatter| sed 's/"/\\"/g' | tr -d '\012' } } }
}
%}
% #for(f in `{get_post_list $blagh_root$blagh_dirs}) {
%
% postlist=`{get_post_list $blagh_root$blagh_dirs}
% postcount=0
% for(f in $postlist) {
% statpost $f
{
"id": "%($post_uri%)",
"url": "%($post_uri%)",
"title": "%($title%)",
"content_html": "%($summary%)"
}
% postcount = `{echo $postcount 1+p | dc}
% if (! ~ $#postlist $postcount) { echo , }
% }
]
}
% exit

View file

@ -0,0 +1,11 @@
<div>
% notices_handler
<form method="POST"><fieldset>
<legend>Submit a new blog post</legend>
<textarea cols="94" rows=16" name="body">%($"post_arg_body%)</textarea><br />
<label>Title: <input size="64" type="text" name="title" value="%($"post_arg_title%)" /></label>
<label>Id: <input size="8" type="text" name="id" value="%($"post_arg_id%)" /></label>
<label>Date: <input size="10" maxlength="10" type="text" name="date" value="%($"post_date%)" /></label>
<input type="submit" value="Post" />
</fieldset></form>
</div>

43
werc/apps/blagh/rss20.tpl Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
%{
fn statpost {
f = $1
post_uri = `{echo $f | sed 's,^'$sitedir',,'}
title=`{read $f/index.md}
post_uri=$base_url^`{cleanname `{echo $f | sed -e 's!^'$sitedir'!!'}}^'/'
by=`{ls -m $f | sed 's/^\[//g; s/].*$//g' >[2]/dev/null}
ifs=() {summary=`{ cat $f/index.md |strip_title_from_md_file| ifs=$difs {$formatter | escape_html} }}
}
%}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="%($base_url^$req_path%)" rel="self" type="application/rss+xml" />
<title><![CDATA[%($siteTitle%)]]></title>
<link>%($base_url^$req_path%)</link>
<description><![CDATA[%($blogDesc%)]]></description>
<language>en-us</language>
<generator><![CDATA[Tom Duff's rc, and Kris Maglione's clever hackery]]></generator>
%{
# <webMaster>uriel99+rss@gmail.com (Uriel)</webMaster>
# rfc2822 last time channel content changed.
lbd=`{ndate -m `{date `{mtime `{ls $blagh_root$blagh_dirs/[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]/[0-9] | tail -1} | awk '{print $1}'}}}
echo '<lastBuildDate>'$"lbd'</lastBuildDate>'
# rfc2822 publication date for content in the channel.
pubdate=`{ndate -m}
for(f in `{get_post_list $blagh_root$blagh_dirs}){
statpost $f
%}
<item>
<title><![CDATA[%($title%)]]></title>
<author><![CDATA[%($by%)@noreply.cat-v.org (%($by%))]]></author>
<link>%($post_uri%)</link>
<guid isPermaLink="true">%($post_uri%)</guid>
<pubDate>%($pubdate%)</pubDate>
<description> %($summary%) </description>
</item>
% }
</channel>
</rss>

103
werc/apps/bridge/app.rc Executable file
View file

@ -0,0 +1,103 @@
comment_file_types=(md html)
fn conf_enable_comments {
if(~ $1 -n) {
allow_new_user_comments=yes
shift
}
if not if(~ $1 -a) {
bridge_anon_comments=yes
}
enable_comments=yes
groups_allowed_comments=$*
conf_enable_app bridge
}
fn bridge_init {
if(~ $#enable_comments 1 && ! ~ `{ls $local_path.$comment_file_types >[2]/dev/null|wc -l} 0) {
comments_dir=$sitedir$req_path'_werc/comments'
if(~ $REQUEST_METHOD GET && test -d $comments_dir)
ll_add handlers_body_foot template apps/bridge/comments_list.tpl
if(check_user $groups_allowed_comments || {~ $#logged_user 0 && ~ 1 $#allow_new_user_comments $#bridge_anon_comments}) {
if(~ $#post_arg_bridge_post 1) {
ll_add handlers_body_foot template apps/bridge/foot.tpl
if(mk_new_comment $comments_dir)
post_redirect $base_url^$req_path
if not
saved_comment_text=$post_arg_comment_text
}
if not if(~ $REQUEST_METHOD GET)
ll_add handlers_body_foot template apps/bridge/foot.tpl
}
if not if(~ $REQUEST_METHOD GET)
ll_add handlers_body_foot echo '<hr><p>To post a comment you need to <a href="/_users/login">login</a> first.</p>'
}
}
fn validate_new_user {
usr=$1; pass=$2; pass2=$3
_status=()
if(~ $"usr '' || ! echo $usr |sed 1q|grep -s '^'$allowed_user_chars'+$')
_status='Requested user name is invalid, must match: '^$allowed_user_chars^'+'
if not if(test -d etc/users/$usr)
_status='Sorry, user name '''^$usr^''' already taken, please pick a different one.'
if(~ $"pass '' || ! ~ $"pass $"pass2)
_status=($_status 'Provided passwords don''t match.')
status=$_status
}
fn mk_new_comment {
_status=()
dir=$1
if(~ $"post_arg_comment_text '')
_status='Provide a comment!'
if not if(~ $#logged_user 0) {
if(! ~ $#allow_new_user_comments 0) {
if(validate_new_user $"post_arg_comment_user $post_arg_comment_passwd $post_arg_comment_passwd2) {
u=$post_arg_comment_user':'$post_arg_comment_passwd
dir=$comments_dir^'_pending'
# XXX: This doesn't work because we then do a redirect.
notify_notes='Saved comment and registration info, they will be enabled when approved by an admin.'
}
if not
_status=$status
}
if not if(! ~ $#bridge_anon_comments 0) {
if(~ $"post_arg_ima_robot 'not')
u='Glenda' # Anonymous
if not
_status='You are a robot!'
}
if not
_status='You need to log in to comment.'
}
if not if(check_user $groups_allowed_comments)
u=$logged_user
if not
_status='You are not a member of a group allowed to comment.'
if(~ $#_status 0) {
umask 002
dir=$dir'/'`{date -n} # FIXME Obvious race
mkdir -m 775 -p $dir &&
echo $u > $dir/user &&
echo $current_date_time > $dir/posted &&
echo $post_arg_comment_text > $dir/body
_s=$status
if(! ~ $"_s '') {
dprint 'ERROR XXX: Could not create comment: ' $_s
_status='Could not post comment due internal error, sorry.'
}
}
notify_errors=$_status
status=$_status
}

View file

@ -0,0 +1,13 @@
<hr>
<h2>Comments</h2>
% for(c in `{ls $comments_dir/}) {
% if(test -s $c/body) {
<div class="comment">
<h5>By: <i>%(`{cat $c/user}%)</i></b> (%(`{cat $c/posted}%))
</h5>
% cat $c/body | escape_html | sed 's,$,<br>,'
<hr></div>
% }
% }

37
werc/apps/bridge/foot.tpl Executable file
View file

@ -0,0 +1,37 @@
<hr>
% notices_handler
<form action="" method="post">
<textarea name="comment_text" id="comment_text" cols="80" rows="16">%($"saved_comment_text%)</textarea>
<br>
<input type="submit" name="bridge_post" value="Post a comment">
% if(~ $#logged_user 0) {
% if(~ $#allow_new_user_comments 1) {
<label>New user name:
<input type="text" name="comment_user" value="%($"post_arg_comment_user%)">
</label>
<label>Password:
<input type="password" name="comment_passwd" value="">
</label>
<label>Repeat password:
<input type="password" name="comment_passwd2" value="">
</label>
<div style="font-size: 70%">
Enter your desired user name/password and after your comment has been reviewed by an admin it will be posted and your account will be enabled. If you are already registered please <a href="/_users/login">login</a> before posting.
</div>
% }
% if not if(~ $#bridge_anon_comments 1) {
<label>Is <a href="http://glenda.cat-v.org">Glenda a cute bunny</a>?
<select name='ima_robot'>
<option value="yes">No</option>
<option value="not">Yes</option>
<option value="foobar">I hate bunnies!</option>
<option value="robot">I'm a robot!</option>
</select>
</label>
% }
% }
</form>

40
werc/apps/dirdir/app.rc Executable file
View file

@ -0,0 +1,40 @@
fn conf_enable_wiki {
enable_wiki=yes
wiki_editors_groups=$*
conf_enable_app dirdir
}
fn dirdir_init {
if(! ~ $#enable_wiki 0 && check_user $wiki_editors_groups) {
lp=$local_path
# werc.rc doesn't append /index when $local_path doesn't exist
# maybe it should, but for now we can fix it up here.
if(~ $lp */)
lp=$lp^'index'
dirdir_file=$lp.md
dirdir_dir=$dirdir_file^'_werc/dirdir/'
if(~ 1 $#post_arg_dirdir_edit $#post_arg_dirdir_preview)
handler_body_main=(tpl_handler `{get_lib_file dirdir/edit.tpl apps/dirdir/edit.tpl})
if not if(! ~ '' $"post_arg_dirdir_save $"post_arg_edit_text)
save_page
if not if(~ $"handler_body_main '' || {~ $REQUEST_METHOD GET && test -f $local_path.md})
ll_add handlers_bar_left tpl_handler apps/dirdir/sidebar_controls.tpl
}
}
fn save_page {
dirdir_verdir=$dirdir_dir/^`{date -n}^/
mkdir -p $dirdir_verdir
umask 002
# XXX Use a tmp file and mv(1) to ensure updates are atomic?
echo $logged_user > $dirdir_verdir/author
echo $post_arg_edit_text > $dirdir_verdir/data
echo $post_arg_edit_text > $dirdir_file
post_redirect $base_url^$req_path
#notify_notes='Saved <a href="'$"req_path'">'$"req_path'</a>!'
}

25
werc/apps/dirdir/edit.tpl Executable file
View file

@ -0,0 +1,25 @@
<div>
<h1>Editing: <a href="%($req_path%)">%($req_path%)</a></h1>
<br>
<form action="" method="POST">
<textarea name="edit_text" id="edit_text" cols="80" rows="43">%{
# FIXME Extra trailing new lines get added to the content somehow, should avoid it.
if(~ $#post_arg_edit_text 0 && test -f $dirdir_file)
cat $dirdir_file | escape_html
if not
echo -n $post_arg_edit_text | escape_html
%}</textarea>
<br>
<input type="submit" name="dirdir_save" value="Save">
<input type="submit" name="dirdir_preview" value="Preview">
<small>DirDir documents are written using <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a>.</small>
</form>
</div>
% if(! ~ $"post_arg_dirdir_preview '') {
<h2>Preview:</h2>
<div id="preview">
% echo $post_arg_edit_text | $formatter
</div>
% }

View file

@ -0,0 +1,3 @@
<form action="" method="POST">
<input type="submit" name="dirdir_edit" value="Edit page" />
</form>

View file

@ -0,0 +1,20 @@
The default path for site search is /_search/. Assuming you want to keep
that default, you could enable site search like so:
mkdir -p /www/werc/sites/MYSITE/_search/_werc/
echo 'conf_enable_duckduckgo' > /www/werc/sites/MYSITE/_search/_werc/config
mkdir -p /www/werc/sites/MYSITE/_werc/lib/
cp /www/werc/apps/duckduckgo/footer.inc.sample /www/werc/sites/MYSITE/_werc/lib/footer.inc
Searches will POST to /_search/ and from there get redirected to Duck Duck
Go with a site:$SERVER_NAME prefix. To have the search path URL be some-
thing different, you'll have to edit line 23 of app.rc to point to the new
path.
TODO:
* Make it automatically work no matter which directory the app is enabled in.
* OR make the search path a configuration option.
* Provide a template for non-footer deployment
* Enable the search path itself to serve a search form to GET requests

30
werc/apps/duckduckgo/app.rc Executable file
View file

@ -0,0 +1,30 @@
fn conf_enable_duckduckgo {
enable_duckduckgo=yes
conf_enable_app duckduckgo
pageTitle='Site Search'
}
fn duckduckgo_init {
get_post_args q
if (! ~ $#q 0) {
redirect_string = 'https://duckduckgo.com/?q=site:'$SERVER_NAME^'+'^$"q
http_redirect $redirect_string '302 Found'
}
if not {
handler_body_main='duckduckgo_body'
}
}
fn duckduckgo_body {
echo '
<h1>Site search</h1>
<h2>using DuckDuckGo</h2>
<form action="/_search/" method="POST">
<label for="searchtext">Site search:</label>
<input type="text" id="searchtext" name="q" placeholder="Search text...">
<input type="submit" value="Search">
</form>'
}

View file

@ -0,0 +1,3 @@
<div><a href="http://werc.cat-v.org">Powered by werc</a></div>
<div><form action="/_search/" method="POST"><label for="searchtext">Site search:</label> <input type="text" id="searchtext" name="q" placeholder="Enter search text..."><input type="submit" display="Search"></form></div>

10
werc/apps/hello/app.rc Executable file
View file

@ -0,0 +1,10 @@
fn hello_init {
if(~ $req_path /hello) {
handler_body_main='hello_body'
pageTitle='Hi title!'
}
}
fn hello_body {
echo 'Hello world!'
}

45
werc/apps/paste/app.rc Executable file
View file

@ -0,0 +1,45 @@
fn conf_enable_wercpaste {
paste_url=$conf_wd
if (~ $#paste_dir 0) { paste_dir=`{pwd} }
conf_enable_app wercpaste
}
fn wercpaste_init {
if (~ $REQUEST_METHOD POST && ~ $post_arg_url url && ~ $req_path $paste_url ) { # incoming paste
now=`{ date -n }
cksum=`{ echo $"post_arg_paste | sum | awk '{ print $1 }' }
if (~ $cksum '1715a8eb' ) { # empty paste; discard
post_redirect $base_url^$paste_url
}
if not { # save and redirect
# TODO: stop using echo
# env var size limit is 16kb, this thing dies with larger input.
echo $"post_arg_paste > $paste_dir^/^$now^.^$cksum
# uncomment the following line to redirect to the pasted file
#post_redirect $base_url^$paste_url^$now^.^$cksum
# uncomment the following line instead to just return the url
echo 'Content-type: text/plain'; echo ''; exec echo $base_url^$paste_url^$now^.^$cksum
}
}
if not { # show a paste if there is one
if (test -r $werc_root/$local_path && ~ $QUERY_STRING raw ) {
echo 'Content-type: text/plain'; echo ''; exec cat $werc_root/$local_path
}
}
# drop a textbox
if (~ $REQUEST_METHOD GET ) { handler_body_main='begforpaste' }
}
fn begforpaste {
echo '<article class="pastebox">
<h3 style="text-align: center">pasted data is not publically indexed</h3>
<form action="'$paste_url'" method="post" style="margin:2em">
<textarea name="paste" cols="120" rows="20" required style="display: block; margin: 0 auto 0 auto" ></textarea><br>
<input type="submit" name="submit" value="SUBMIT" style="display: block; margin: 0 auto 0 auto" ><br><br>
<span style="display: none"><input type="text" name="url" value="url" > (do not change) </span>
</form>
</article>
'
}

89
werc/apps/wman/app.rc Executable file
View file

@ -0,0 +1,89 @@
fn conf_enable_wman {
wman_tmac=an
wman_base_uri=$conf_wd
wman_man_path=$*
if(~ $#wman_man_path 0)
wman_man_path=$wman_base_uri
conf_enable_app wman
}
wman_junk_filter='/(\/(INDEX|\.cvsignore|_.*)|\.9p|\.html)$/d; s!/man([0-9]+/[^/]+)$!/\1!; '
fn wman_ls_pages {
ls $* \
| sed $dirfilter^$wman_junk_filter^' s/\.([0-9]|9p)$//; s!/0intro$!/intro!' \
| sort -u
}
fn wman_init {
ifs=$ifs^'/' { p=`{echo $req_path | sed 's!^'^$wman_base_uri^'!!'} }
wman_cat=$p(1)
wman_page=$p(2)
if(~ $#wman_unix_mode 1) {
wman_cp='man'
wman_pe=.^$"wman_cat
}
if(! ~ $"wman_cat '') {
wman_cat_path=$wman_man_path^/^$"wman_cp^$p(1)
if(! ~ $"wman_page '') {
wman_page_file=$wman_page^$"wman_pe
# Hack to handle 0intro files.
if(~ $wman_page intro && test -f $wman_cat_path^/0^$"wman_page_file)
wman_page_file=0^$"wman_page_file
wman_page_file=$wman_cat_path^/^$"wman_page_file
x=`{echo $"req_path|sed 's%.*/([^/]+)/'$"wman_cat'/'^$"wman_page^'%\1%; s%_% %g'}
pageTitle=$wman_page' page from Section '$wman_cat' of the '^$"x' manual'
}
}
wman_cat_list=`{ls -F $wman_man_path/*/ \
| sed -e $wman_junk_filter -e 's!.*/([^/]+)/[^/]+$!\1!; /[0-9]+/!d' \
| sort -un}
synth_paths=($wman_base_uri$wman_cat_list'/')
if(~ $req_path $wman_base_uri && ~ $"handler_body_main '')
handler_body_main=(tpl_handler apps/wman/section_list.tpl)
if not if(~ $req_path $wman_base_uri^*) {
#^*/[a-z0-9]*[a-z]* $wman_base_uri^*/*[a-z]*[a-z0-9] $wman_base_uri^*/[a-z])
if(echo $req_path | grep -s '^'^$wman_base_uri^'/*[0-9]+/[0-9a-z\-\+\.]+$')
if(test -f $wman_page_file) # Check for 404
handler_body_main=(tpl_handler apps/wman/man_page.tpl)
if not if(~ $req_path $wman_base_uri^*/)
handler_body_main=(tpl_handler apps/wman/page_list.tpl)
if not if(~ $p(2) [A-Z]* [0-9][A-Z]*) # Correct badly capitalized links
perm_redirect $wman_base_uri^$p(1)^/^`{echo $p(2) |tr 'A-Z' 'a-z'}
}
# Search
ll_add handlers_body_head tpl_handler apps/wman/search.tpl
if(! ~ $"post_arg_wman_search '') {
s=`{echo $post_arg_wman_search | sed 's/[^a-zA-Z0-9\-\.]+//g; s/\.+/./g; 1q'}
ifs='' { wman_search_results=`{wman_ls_pages $wman_man_path/*/*^$"s^*} }
if(! ~ $"post_arg_go '' && ~ `{echo -n $wman_search_results|wc -l} 1)
post_redirect $wman_base_uri^`{echo $wman_search_results|awk -F/ '{print $(NF-1)"/"$NF}'}
}
}
fn wman_get_section_desc {
cat $wman_man_path/^$"wman_cp^$1/0intro* >[2]/dev/null| sed '1,2d; s!intro \\- [Ii]ntroduction to !!; 3q;'
}
fn wman_page_gen {
#troff -manhtml $1| troff2html -t 'Plan 9 from User Space'
troff -N -m$wman_tmac $1 | wman_out_filter
}
fn wman_out_filter {
wman_default_out_filter
}
fn wman_default_out_filter {
# col -x syntax is the same for UNIX and Plan 9.
escape_html \
| sed 's!([\.\-a-zA-Z0-9]+)\(('^`{echo $wman_cat_list|tr ' ' '|'}^')\)!<a href="../\2/\1">&</a>!g' \
| awk '/^$/ {if(n != 1) print; n=1; next} /./ {n=0; print}' \
| col -x
}

3
werc/apps/wman/man_page.tpl Executable file
View file

@ -0,0 +1,3 @@
<pre>
% wman_page_gen $wman_page_file
</pre>

11
werc/apps/wman/page_list.tpl Executable file
View file

@ -0,0 +1,11 @@
% d=`{wman_get_section_desc $wman_cat}
<h1>Manual pages - Section %($wman_cat%): %($"d%)</h1>
<ul style="float:left">
%{
wman_ls_pages $wman_cat_path \
| awk -F/ '{ print "<li><a href=\""$(NF)"\">"$(NF)"</a></li>" }
NR%20 == 0 { print "</ul><ul style=\"float: left\">" }'
%}
</ul>

20
werc/apps/wman/search.tpl Executable file
View file

@ -0,0 +1,20 @@
<form action="" method="POST">
<fieldset>
<input type="text" name="wman_search" value="%($"s%)" />
<input type="submit" name="go" value="Feel Lucky" />
<input type="submit" value="Search" />
% if(! ~ $"post_arg_wman_search '') {
% if(~ $"wman_search_results '') {
No matches found for <i>'%($post_arg_wman_search%)'</i>.
% }
% if not {
<ul>
% echo $wman_search_results|awk -F/ '$(NF-1) ~ "^[0-9]+$" {printf "<li><a href=\"'$wman_base_uri'%s/%s\" />%s(%s)</a></li>", $(NF-1),$NF, $NF, $(NF-1)}'
</ul>
% }
% }
</fieldset>
</form>

11
werc/apps/wman/section_list.tpl Executable file
View file

@ -0,0 +1,11 @@
<h1>Manual Sections</h1>
<ul style="text-transform: capitalize;">
% for(c in $wman_cat_list) {
<li><a href="%($c%)/"><b>Section: %($c%)</b></a>
% wman_get_section_desc $c
% if(~ $status '' '|')
% echo '(<a href="'$c'/intro">intro</a>)'
</li>
% }
</ul>

45
werc/apps/xibit/README Normal file
View file

@ -0,0 +1,45 @@
Xibit (tibix) - the image gallery generator for werc
Xibit can:
- generate thumbnails from almost any picture format
- generate preview images with captions
- display them (rather brokenly for now)
Dependencies:
- Plan9port
- Imagemagick
- werc
To make it work:
1, clone the git repo at git://home.9souldier.org/xibit into $werc_root/apps
2, pick a directory to serve the gallery from
3, create an _werc and _werc/xibit directory in there, the xibit directory needs to be writable by the webserver to generate the thumbnails (at one point i'll probably make a cronjob, and then this will be optional)
4, create an _werc/config file (readable by the webserver), that contains the options for xibit
5, add xibit to the enabled_apps in initrc.local (or the local per-directory config file)
That should get you going.
to use captions just create a directory in GALLERY/_werc/xibit called captions, make it readable by the weberver and add the captions as files, using the following naming convention:
image.imageextension.md
the caption handler accepts markdown formatting
to enable comments add the comments handler (bridge) to the enabled apps, it'll (should) automatically work with xibit
Config options:
- fmts:
file extensions recognised
ex. fmts=(jpg gif png svg)
- thumbsize:
size of thumbnails to generate, accepts
ex. thumbsize='140x'
- previewsize:
size of the previews to generate
ex. previewsize='x460'
check_user:
Enforce authentication
This has been ripped out of the xibit code, if you want to enable perms enforcing, you should add the following to your config:
if ( ! check_user) { #if fyou want to enforce per-group permissions, do "if( ! check_user $group) {"
enabled_apps=() #maybe you want to leave some apps on, i just do this on a per-directory besis
handler_body_main=(echo '<a href="/_users/login">please log in</a>')
}

5
werc/apps/xibit/TODO Normal file
View file

@ -0,0 +1,5 @@
features:
- details list index - filenames with creation, etc..
- if format is image format but not one recognised by browsers, convert it to png for preview and thumbnail viewing
nice css @ http://www.area17.com/03_work/nove/photography/ and http://www.sergiojuncos.com/usa2008/large-2.html and http://jmcpherson.org/photoblog/index.php

91
werc/apps/xibit/app.rc Executable file
View file

@ -0,0 +1,91 @@
#xibit is an app that generates image galeries for werc.
#the license the mit license, see the license file in the distribution's root directory
#until the time i change my mind
#comments and suggestions can come to http://redmine.9souldier.org/projects/xibit0/issues/new or johnny@9souldier.org
fn conf_enable_xibit {
xibit_uri=$conf_wd
conf_enable_app xibit
}
fn xibit_init {
xibit_root=$sitedir$"xibit_uri
#SOMEONE PLEASE FIXME if(! ~ $#xibit_uri 0 && test '( -d '^$"xibit_root^'/_werc/xibit ) -a ( -w '^$"xibit_root^'/_werc/xibit )' && convert -help > /dev/null) {
if(! ~ $#xibit_uri 0 && test -d $"xibit_root/_werc/xibit && test -w $"xibit_root/_werc/xibit && which convert > /dev/null) {
xibitdir=$xibit_root^/_werc/xibit
xibit_uri_file=`{echo $req_path |sed 's,^.*/([^/]+)$,\1,g'}
mkdir -p $"xibitdir/previews
mkdir -p $"xibitdir/thumbs
extraHeaders=($extraHeaders '<style>' `{cat apps/xibit/xibit.css} '</style>')
if( ~ $"req_path */index */)
handler_body_main=xibit_thumb_handler
if not {
xibit_img=`{echo $req_path |sed 's,^.*/([^/]+)(\.[^\.]+)?$,\1,g'}
for(pic in $xibit_img.^$fmts){
if(test -f $xibit_root/^$pic)
handler_body_main=xibit_img_handler
}
if ( ~ $#handler_body_main 0 )
status='xibit cant to anything here'
}
}
}
fn xibit_thumb_handler {
cd $xibit_root
xibitdir=_werc/xibit
rm $"xibitdir/dirstat.md5.tmp > /dev/null >[2] /dev/null
if( ! ~ `{ls -l |md5sum |tee $xibitdir/dirstat.md5.tmp} `{cat $xibitdir/dirstat.md5}) {
mv $xibitdir/dirstat.md5.tmp $xibitdir/dirstat.md5
for(pic in `{ls *.^$fmts >[2] /dev/null}) {
if( ! test -f $"xibitdir/thumbs/^$"pic )
convert $pic -resize $thumbsize $xibitdir/thumbs/^$pic
if( ! test -f $"xibitdir/previews/^$"pic )
convert $pic -resize $previewsize $xibitdir/previews/^$pic
xibit_pics=($xibit_pics $pic)
}
}
if not
for(pic in `{ls *.^$fmts >[2] /dev/null})
xibit_pics=($xibit_pics $pic)
rm $xibitdir/dirstat.md5.tmp > /dev/null >[2] /dev/null
cd $werc_root
if( ! ~ $req_path */details )
template apps/xibit/thumbs.tpl
if not
template apps/xibit/details.tpl
}
fn xibit_img_handler {
cd $xibit_root
for(file in $xibit_uri_file.^$fmts) {
if( test -f $file) {
xibit_img=`{echo $file |sed 's,^.*/([^/]+),\1,g'}
xibit_preview=_werc/xibit/previews/^$xibit_img
if (test -r _werc/xibit/captions/^$xibit_img^.md)
xibit_caption_file=$xibitdir^/captions/^$xibit_img^.md
xibit_nextpic=`{next_pic $xibit_img}
xibit_prevpic=`{prev_pic $xibit_img}
dprint $xibit_nextpic $xibit_prevpic
cd $werc_root
}
}
cd $werc_root
xibit_thumb_handler
}
fn prev_pic {
findre='/^'^$1^'$/!h; /^'^$1^'$/!d; /^'^$1^'$/g;'
if( ! ls -F |sed 1q |grep -s $1 )
ls -F |grep -v '_werc' | sed 's,\*$,,g; /\$/d; s,'',,g' | sed $"findre^'; s,\.[^\.]+$,,'
}
fn next_pic {
findre='/^'^$1^'$/!d; /^'^$1^'/n; p'
if( ! ls -F |tail -1 |grep -s $1 )
ls -F |grep -v '_werc' | sed 's,\*$,,g; /\/$/d; s,'',,g' | sed -n $"findre |sed 's,\.[^\.]+$,,'
}

View file

@ -0,0 +1,14 @@
<div class="images-details">
<ul>
% for (pic in $xibit_pics) {
<li>
<a href="
% echo $pic |sed 's,(.*)\..+$,\1,g'
" class="thumb" >
<img src="%( $xibit_thumbsdir^/^$pic %)" class="thumb"/>
</a>
% identify $xibit_urlroot/^$pic |awk '{print $4}'
</li>
% }
</ul>
</div>

21
werc/apps/xibit/image.tpl Normal file
View file

@ -0,0 +1,21 @@
<div id="main-img">
% if ( ! ~ $#xibit_prevpic 0) {
<a href="%($xibit_prevpic%)#main-img">Previous</a>
% }
% if ( ! ~ $#xibit_nextpic 0 && ! ~ $#xibit_prevpic 0 ) {
/
% }
% if ( ! ~ $#xibit_nextpic 0) {
<a href="%($xibit_nextpic%)#main-img">Next</a>
% }
<div class="main-img" id="mainpic">
<a href="%($xibit_img%)">
<img src="%($xibit_preview%)" />
</a>
</div>
% if ( ! ~ $#xibit_caption_file 0) {
<div class="caption">
% md_handler $xibit_caption_file
</div>
% }
</div>

19
werc/apps/xibit/license Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2009 John Soros
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -0,0 +1,11 @@
% for (pic in $xibit_pics){
% picnoext=`{echo $pic |sed 's,(.*)\..+$,\1,g'}
% if(! ~ $pic $xibit_img) {
<a href="%($picnoext%)#main-img" class="thumb" >
<img src="%( _werc/xibit/thumbs/^$pic %)" class="thumb"/>
</a>
% }
% if not {
% template apps/xibit/image.tpl
% }
% }

17
werc/apps/xibit/xibit.css Normal file
View file

@ -0,0 +1,17 @@
.thumbs-index {
float: right;
clear: none;
white-space: nowrap;
}
.thumb {
clear: none;
width: auto;
height: auto;
padding: 5px;
border: 2px;
display: inline;
}
#main-img {
text-align: center;
clear: none;
}

33
werc/bin/aux/addwuser.rc Executable file
View file

@ -0,0 +1,33 @@
#!/bin/rc
if(! ~ $#werc_root 0)
cd $werc_root
fn usage {
if(! ~ $#* 0)
echo $0: $* >[1=2]
echo 'Usage:' $0 'user_name user_password [groups ...]' >[1=2]
exit usage
}
if(! test -d etc/users/)
usage 'Run for root of werc installation or set $werc_root'
user_name=$1
shift
user_pass=$1
shift
user_groups=$*
if(~ $"user_name '' || ~ $"user_pass '')
usage
mkdir etc/users/$user_name
echo $user_pass > etc/users/$user_name/password
if(! ~ $#user_groups 0)
for(g in $user_groups) {
mkdir -p etc/users/$g
echo $user_name >> etc/users/$g/members
}

64
werc/bin/aux/bpst.rc Executable file
View file

@ -0,0 +1,64 @@
#!/bin/rc
path=( $PLAN9/bin $path )
base=.
if(~ $#user 0)
user=`{whoami}
file=(); title=();
bloguser=$user
while(! ~ $#* 0) {
switch($1) {
case -u
base=/gsoc/www/people/$user/blog/
case -b
shift
base=$1
case -f
shift
file=$1
}
shift
}
if(~ $"EDITOR '')
EDITOR=vi
if(~ $#file 0 || ! test -f $file) {
file=/tmp/blogtmp.$pid
rm $file >[2]/dev/null
touch $file
}
$EDITOR $file
aspell -c $file
rm $file.bak >[2]/dev/null
fn mkbpost {
umask 002 # Let group write
bptext=$1
if(! ~ $#2 0)
bpid=`{echo -n '-'^$"bpid | sed 's/'$forbidden_uri_chars'+/_/g; 1q'}
d=`{/bin/date +%F|sed 's,-,/,g'}
ddir=$blagh_root^$d^'/'
n=`{ls $ddir >[2]/dev/null |wc -l}
mkdir -p $ddir/$"n^$"bpid/
{
# TODO: Enable metadata
#echo '* Posted:' `{date}
#if(! ~ $#logged_user 0)
# echo '* Author: '$logged_user
cat $bptext
}> $ddir/$"n^$"bpid/index.md
}
forbidden_uri_chars='[^a-zA-Z0-9_+\-\/\.]'
blagh_root=$base
if(test -s $file)
mkbpost $file
if not
echo Empty file!

14
werc/bin/aux/gensitemaptxt.rc Executable file
View file

@ -0,0 +1,14 @@
#!/bin/rc
# DEPRECATED: sitemap.tpl now generates and updates a sitemap.txt when requested, and is also more smart than this simplistic script.
for(d in sites/*/) {
echo $d
9 du -a $d | awk '/\.(md|html)$/ { print $2 }; {}' | 9 sed -e 's/\.(md|html)$//' -e 's,/index$,/,' -e 's,^sites/,http://,' > $d/sitemap.txt
if(! test -f $d/robots.txt) {
echo generating missing robots.txt for $d
echo $d|sed 's,sites/,Sitemap: http://,; s/$/sitemap.txt/;' > $d/robots.txt
cat $d/robots.txt
}
}

16
werc/bin/aux/runtsts.rc Executable file
View file

@ -0,0 +1,16 @@
#!/bin/rc
tstdom='http://test.cat-v.org'
cd sites/tst.cat-v.org
tstfiles=`{du -a |awk '/\.tst$/ { print $2 }; {} ' | sed 's/^\.//; s/\.tst$//'}
for(f in $tstfiles) {
ifs='
' { tsts=`{cat ./$f.tst} }
for(t in $tsts) {
echo tst $t
}
}

236
werc/bin/cgilib.rc Executable file
View file

@ -0,0 +1,236 @@
# Useful CGI stuff
fn dprint { echo $* >[1=2] }
fn dprintv { { for(v in $*) { echo -n $v^'#'^$#$v^'=' $$v '; ' }; echo } >[1=2] }
fn echo {if(! ~ $1 -n || ! ~ $2 '') /bin/echo $*}
fn escape_html { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' $* }
fn http_redirect {
if(~ $1 http://* https://*)
t=$1
if not if(~ $1 /*)
t=$"base_url^$1
if not
t=$"base_url^$"req_path^$1
exec /bin/echo 'Status: '^$2^'
Location: '^$t^'
'
exit
}
fn perm_redirect { http_redirect $1 '301 Moved Permanantly' }
fn post_redirect { http_redirect $1 '303 See Other' }
# Note: should check if content type is application/x-www-form-urlencoded?
# Should compare with http://www.shelldorado.com/scripts/cmds/urlgetopt.txt
fn load_post_args {
if(~ $REQUEST_METHOD POST && ~ $#post_args 0) {
ifs='&
' for(pair in `{cat}) {
ifs='=' { pair=`{echo -n $pair} }
n='post_arg_'^`{echo $pair(1)|nurldecode|tr -cd 'a-zA-Z0-9_'}
post_args=( $post_args $n )
ifs=() { $n=`{echo -n $pair(2)|nurldecode|tr -d ' '} }
}
pair=()
}
if not
status='No POST or post args already loaded'
}
# Status is () if at least one arg is found. DEPRECATED: access vars directly.
fn get_post_args {
load_post_args
_status='No post arg matches'
for(n in $*) {
v=post_arg_$n
if(! ~ $#$v 0) {
$n=$$v
_status=()
}
}
status=$_status
}
# This seems slightly improve performance, but might depend on httpd buffering behavior.
fn awk_buffer {
awk '{
buf = buf $0"\n"
if(length(buf) > 1400) {
printf "%s", buf
buf = ""
}
}
END { printf "%s", buf }'
}
fn nurldecode { urlencode -d || url_decode} # GROSS
fn url_decode {
awk '
BEGIN {
hextab ["0"] = 0; hextab ["8"] = 8;
hextab ["1"] = 1; hextab ["9"] = 9;
hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
}
{
decoded = ""
i = 1
len = length ($0)
while ( i <= len ) {
c = substr ($0, i, 1)
if ( c == "%" ) {
if ( i+2 <= len ) {
c1 = substr ($0, i+1, 1)
c2 = substr ($0, i+2, 1)
if ( hextab [c1] == "" || hextab [c2] == "" ) {
print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
} else {
code = 0 + hextab [c1] * 16 + hextab [c2] + 0
c = sprintf ("%c", code)
i = i + 2
}
} else {
print "WARNING: invalid % encoding: " substr ($0, i, len - i)
}
} else if ( c == "+" ) {
c = " "
}
decoded = decoded c
++i
}
printf "%s", decoded
}
'
}
fn nurlencode { urlencode || url_encode } # GROSS
fn url_encode {
awk '
BEGIN {
# We assume an awk implementation that is just plain dumb.
# We will convert an character to its ASCII value with the
# table ord[], and produce two-digit hexadecimal output
# without the printf("%02X") feature.
EOL = "%0A" # "end of line" string (encoded)
split ("1 2 3 4 5 6 7 8 9 A B C D E F", hextab, " ")
hextab [0] = 0
for ( i=1; i<=255; ++i ) ord [ sprintf ("%c", i) "" ] = i + 0
if ("'^$"EncodeEOL^'" == "yes") EncodeEOL = 1; else EncodeEOL = 0
}
{
encoded = ""
for ( i=1; i<=length ($0); ++i ) {
c = substr ($0, i, 1)
if ( c ~ /[a-zA-Z0-9.-]/ ) {
encoded = encoded c # safe character
} else if ( c == " " ) {
encoded = encoded "+" # special handling
} else {
# unsafe character, encode it as a two-digit hex-number
lo = ord [c] % 16
hi = int (ord [c] / 16);
encoded = encoded "%" hextab [hi] hextab [lo]
}
}
if ( EncodeEOL ) {
printf ("%s", encoded EOL)
} else {
print encoded
}
}
END {
#if ( EncodeEOL ) print ""
}
' $*
}
# Cookies
fn set_cookie {
# TODO: should check input values more carefully
name=$1
val=$2
extraHttpHeaders=( $extraHttpHeaders 'Set-cookie: '^$"name^'='^$"val^'; path=/;' )
}
fn get_cookie {
ifs=';' { co=`{echo $HTTP_COOKIE} }
# XXX: we might be adding a trailing new line?
# The ' ?' is needed to deal with '; ' inter-cookie delimiter
{ for(c in $co) echo $c } | sed -n 's/^ ?'$1'=//p'
}
fn static_file {
echo -n 'Content-Type: '
select_mime $1
echo
exec cat $1
}
fn select_mime {
m='text/plain'
if(~ $1 *.css)
m='text/css'
if not if(~ $1 *.ico)
m='image/x-icon'
if not if(~ $1 *.png)
m='image/png'
if not if(~ $1 *.jpg *.jpeg)
m='image/jpeg'
if not if(~ $1 *.gif)
m='image/gif'
if not if(~ $1 *.pdf)
m='application/pdf'
echo $m
}
##############################################
# Generic rc programming helpers
# Manage nested lists
fn ll_add {
_l=$1^_^$#$1
$_l=$*(2-)
$1=( $$1 $_l )
}
# Add to the head: dangerous if you shrink list by hand!
fn ll_addh {
_l=$1^_^$#$1
$_l=$*(2-)
$1=( $_l $$1 )
}
NEW_LINE='
'
# crop_text [max_lenght [ellipsis]]
# TODO: Option to crop only at word-delimiters.
fn crop_text {
m=512
e='...'
if(! ~ $#1 0)
m=$1
if(! ~ $#2 0)
e=$2
awk -v 'max='^$"m -v 'ellipsis='$e '
{
nc += 1 + length;
if(nc > max) {
print substr($0, 1, nc - max) " " ellipsis
exit
}
print
}'
}

27
werc/bin/contrib/fix-rc-scripts Executable file
View file

@ -0,0 +1,27 @@
#!/usr/local/plan9/bin/rc
# Fix rc shell scripts to find rc without launching env every time.
# Invoke with rc and plan9 versions of grep and ed in $PATH
# If your system lacks which (e.g. some gnu/linux)
# substitute the full path to rc in this line:
rc=/usr/local/plan9/bin/rc
firstline='#!'$"rc
if(~ $#* 0) files = *
if not files = $*
myname = `{basename $0}
for(file in $files) {
if(test -d $file) $0 $file/*
if not if(~ $file *$myname) {}
if not if(sed 1q $file | grep '^#!/.*[/ ]rc$' > /dev/null) {
{
echo 1c
echo $firstline
echo .
echo wq
} | ed $file > /dev/null
}
}

12
werc/bin/contrib/hgweb.config Executable file
View file

@ -0,0 +1,12 @@
[web]
style = gitweb
allow_archive = bz2
#[paths]
#w9 = /gsoc/hg/w9/
[collections]
#allow_archive = bz2 zip
/gsoc/hg = /gsoc/hg/
#/var/hg = /var/hg/

47
werc/bin/contrib/hgwebdir.cgi Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
#
# An example CGI script to export multiple hgweb repos, edit as necessary
# send python tracebacks to the browser if an error occurs:
import cgitb
cgitb.enable()
# adjust python path if not a system-wide install:
#import sys
#sys.path.insert(0, "/path/to/python/lib")
# If you'd like to serve pages with UTF-8 instead of your default
# locale charset, you can do so by uncommenting the following lines.
# Note that this will cause your .hgrc files to be interpreted in
# UTF-8 and all your repo files to be displayed using UTF-8.
#
#import os
#os.environ["HGENCODING"] = "UTF-8"
from mercurial.hgweb.hgwebdir_mod import hgwebdir
from mercurial.hgweb.request import wsgiapplication
import mercurial.hgweb.wsgicgi as wsgicgi
# The config file looks like this. You can have paths to individual
# repos, collections of repos in a directory tree, or both.
#
# [paths]
# virtual/path = /real/path
# virtual/path = /real/path
#
# [collections]
# /prefix/to/strip/off = /root/of/tree/full/of/repos
#
# collections example: say directory tree /foo contains repos /foo/bar,
# /foo/quux/baz. Give this config section:
# [collections]
# /foo = /foo
# Then repos will list as bar and quux/baz.
#
# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
# or use a dictionary with entries like 'virtual/path': '/real/path'
def make_web_app():
return hgwebdir("hgweb.config")
wsgicgi.launch(wsgiapplication(make_web_app))

Some files were not shown because too many files have changed in this diff Show more