Various Programs & Scripts
These posts contain various programs & scripts that don’t really deserve their own project pages. Well, some of them do have project pages but most don’t.
Many of these will no longer work (software is an ever evolving ecosystem), but you’re free to salvage what you can.
Localtime
Localtime is a small, light-weight go daemon for keeping the timezone up-to-date. It uses geoclue2 and systemd-timedated to do all the heavy lifting so it’s able to run with minimal privileges. See the project page for more information.
Pipe to Emacs
While there are many ways to pipe to emacs, they all involve either shuttling text by repeatedly calling emacsclient or writing to a temporary file. However, neither are necessary.
Basically, while emacs can’t (yet) read from a named pipe (FIFO), it can read standard output from a process so, one gratuitous use of cat
later…
(defun pager-read-pipe (fname)
(let ((buf (generate-new-buffer "*pager*"))
(pname (concat "pager-" fname)))
(with-current-buffer buf (read-only-mode))
(switch-to-buffer buf)
(let ((proc (start-process pname buf "/usr/bin/cat" fname)))
(set-process-sentinel proc (lambda (proc e) ()))
(set-process-filter proc (lambda (proc string)
(when (buffer-live-p (process-buffer proc))
(with-current-buffer (process-buffer proc)
(save-excursion
;; Insert the text, advancing the process marker.
(let ((inhibit-read-only t))
(goto-char (process-mark proc))
(insert string)
(set-auto-mode)
(set-marker (process-mark proc) (point))))))))
proc)))
…and you can read a from named pipe. As an added bonus, this function will try to autodetect the correct mode.
To actually use this, I recommend the following shell script:
#!/bin/bash
set -e
cleanup() {
trap - TERM INT EXIT
if [[ -O "$FIFO" ]]; then
rm -f "$FIFO" || :
fi
if [[ -O "$DIR" ]]; then
rmdir "$DIR" || :
fi
}
trap "cleanup" TERM INT EXIT
SOCKET="${XDG_RUNTIME_DIR:-/run/user/$UID}/emacs/server"
# Create a named pipe in /dev/shm
DIR=$(mktemp -d "/dev/shm/epipe-$$.XXXXXXXXXX")
FIFO="$DIR/fifo"
mkfifo -m 0600 "$DIR/fifo"
# Ask emacs to read from the names socket.
emacsclient -s "$SOCKET" -n --eval "(pager-read-pipe \"$FIFO\")" >/dev/null <&-
exec 1>"$FIFO"
cleanup # Cleanup early. Nobody needs the paths now...
cat
You will probably need to set the SOCKET
variable to your emacs socket filename.
Usage:
dmesg --follow | epipe
Gazetta
Gazetta is a static site generator written in rust (currently powering this website). You can find more details on the project page.
Platter
Announcing platter, a file server for direct file transfers. See the project page for details.
Turn the Zim Desktop Wiki into a calendar
Caveat lector: I wrote this post in high school; it’s likely outdated and poorly written.
Why
I recently switched to Arch Linux and decided to ditch evolution (a good but bloated program). Claws Mail works perfectly as an email manager but I couldn’t get its calendar plugin to work properly. I have been using Zim for a while and noticed that it had a very basic calendar plugin; this was exactly what I needed. The plugin allows users to create pages in their wikis for individual days: no complex forms to fill out, just a simple page to keep track of what you are doing on a given day.
What
As Zim lacks desktop integration so I wrote two python scripts for conky integration:
zim-conky_cal.py
Prints a calendar (like the cal command) with the current date and appointments highlighted.
zim-conky_events.py
Lists the next 5 events or all of the events in the current month and the next, whichever comes first.
I also wrote a program for adding events to the calendar (zim-cal.py and zim-cal.ui). Select some text, run the program and double click the date to add your text to calendar. You can also input your own text by clicking the edit button (the big button on the right).
How
First: Enable the calendar plugin (Edit->Preferences->Plugins->Calendar).
Download: zimcal.tar.bz2
Conky scripts
- Edit CAL_PATH to point to the folder that stores your Zim calendar.
- Add
${execpi 300 /path/to/zim-conky_cal.py}
and${execpi 300 /path/to/zim-conky_events.py}
to your conkyrc
Zim-Cal program
- Edit CAL_PATH to point to the folder that stores your Zim calendar.
- Make PROG_PATH point to the directory where you put “zim-cal.ui”
- If you intend to use this program regularly, you should probably assign a global hotkey to it in your window manager.
Kupfer Plugins
Caveat lector: I wrote this post in high school; it’s likely outdated and poorly written.
After getting frustrated with GNOME-Do’s memory hogging, I switched to Kupfer. Kupfer is a lightweight, extensible application launcher like Do (as it is now called) but much more powerful and easier to extend (it is written in python).
My Plugins
So far, I’ve written the following plugins:
gwibber\_plugin.py
: This plugin allows you to send messages from Kupfer through Gwibber (with no configuration).exaile\_plugin.py
: This plugin allows you to pause, play, skip, and go backwards in Exaile. It is based on the Rhytmbox plugin.
+1: evolution\_plugin.py
: I did not write this plugin (although I did do a fair bit of editing). The Evolution plugin adds an evolution contact source (and works with the built in email plugin).
Download: kupfer-plugins.tar.gz
Service Manager for Karmic
> Caveat lector: I wrote this post in high school; it’s likely outdated and poorly written.
Annoyingly, as karmic has mostly switched to Upstart, it does not include a service manager. While I hope that the gnome service-manager will be updated to include support for upstart soon I have, for the interim, written a very simple service manager.
Be warned: When I say “very simple” I mean “very simple, noob unfriendly, and potentially dangerous”. While it should not harm your computer, I make no guarantees because it is my first PyGTK program and was written in my spare time over a couple of days. A word of warning, the code is very messy and inefficient (understatement).
Dark-Minimal Lock Dialog
Caveat lector: I wrote this post in high school; it’s likely outdated and poorly written.
I finally uploaded my first contribution to gnome-look.org: Dark-Minimal Lock Dialog.
Screenshot
Download
Identi.ca feed fetcher script
Caveat lector: I wrote this post in high school; it’s likely outdated and poorly written.
Attached is a simple Identi.ca feed fetcher script written in python. It is a console program and has no gui. It will display the same content as would appear on a users Identi.ca homepage for a given user. Edit the configuration at the head of the script before use.
It works well with conky; simply add ${exec python /path/to/script.py}
to your conky file and it will update whenever your conky refreshes. If your conky config is set to update very frequently, please use ${execi interval /path/to/script.py}
so that you are not constantly polling identi.ca’s server.
- Edit 1: Updated script to correctly encode text and to include replies.
- Edit 2: Inline script to fix broken link.
Script:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2008 Steven
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Blog: http://blog.stebalien.com
import feedparser
import textwrap
import unicodedata
### SETTINGS ###
# Username (lowercase)
USER = "stebalien"
# Width in charictars of output
WIDTH = 50
# Number of posts to display
POSTS = 10
# Indent of posts
INDENT_FIRST = 3
INDENT_REST = 5
################
def formatPost(string):
#string = string..replace(unicode("“", "utf-8"), '"').replace(unicode("”", "utf-8"), '"').replace(unicode("…", "utf-8"), '...').replace(unicode("’", "utf-8"), "'")
string = unicodedata.normalize('NFKD', string).encode('ascii','ignore')
parts = string.partition(':')
return parts[0] + parts[1] \
+ "\n" + wrapper.fill('\n' \
+ parts[2]) \
+ "\n\n"
wrapper = textwrap.TextWrapper()
wrapper.subsequent_indent = ' '*INDENT_FIRST
wrapper.initial_indent = ' '*INDENT_REST
wrapper.width = WIDTH
# Get and display feed
all_feed = feedparser.parse("http://identi.ca/" + USER + "/all/rss")
reply_feed = feedparser.parse("http://identi.ca/" + USER + "/replies/rss")
n = 0
i = 0
while ((i+n) < POSTS):
while (reply_feed.entries[n].updated_parsed > all_feed.entries[i].updated_parsed):
print "> " + formatPost(reply_feed.entries[n].title)
n=n+1
print " " + formatPost(all_feed.entries[i].title)
i=i+1
Banshee Plugin for mumbles
Caveat lector: I wrote this post in high school; it’s likely outdated and poorly written.
I Just wrote a banshee plugin for mumbles. It works much better than banshee’s default notification daemon integration. Clicking on the notification brings banshee to the front. Install it like you would any other mumbles plugin (see two posts back or look for instructions on the mumbles homepage).
Plugin (python 2.5) + Source: banshee-plugin_mumbles.tar.gz