login

Site Migration

20:24 rson: if there is anything i could ever suggest that you'd listen to, let
            it be this.  do it.

Wise words from someone who’s been there before. That’s rson telling me that I should move my site to some sort of framework. Make things cleaner, easier to maintain, and get away from that goddamn php I seem to be so fond of.

I had been thinking about doing this myself for quite some time. As silly as it sounds, I was unhappy with my urls. The whole site (from a purely url-appearance standpoint) was inconsistent. I dreamed for /feed/ and /posts/my_post/.

I could also feel my spider web of php and html spiralling away from me. I was spending too much time monitoring comments, tweaking the syntax highlighting, and figuring out the best way to format bread crumbs based on not only filepath but also custom translations from content.php to all posts and similar.

Yesod

Then I found Yesod, a web framework based on haskell. As anyone who’s ever been to this site knows, I love haskell. It’s just a cool language. So if I were going to move to some sort of framework, this would be it.

So, using the Yesod Docs, the haddock documentation, and even the actual source for the Yesod Docs, I was able to hobble my site over to the framework. It wasn’t easy, but there’s a lot of benefit there.

My breadcrumbs went from 100 lines of php to about 14 lines of haskell. And those 14 lines are simply defining what Routes are children of what other Routes.

My posts have tags now. This extra bit of post-metadata was even added later without disrupting any existing code.

My Rss feed is dynamically created whenever it’s loaded.

And probably most important of all, urls used throughout the site are type safe, compile-time-guaranteed to be valid.

What that means is that I don’t type the url directly, I insert a haskell function that corresponds to those pages’ Routes. And no, they aren’t built from regular expressions; each Route is generated as a distinct type as defined by me.

Routes can also have arguments. Right now you’re viewing the output of the PostR Route using site_migration as its argument. But the best part of all that is that the compiler validates every link in my site each time it’s compiled to ensure it’s in scope and type checks!

Sell Out!

As part of the transition, I’m also giving up some control over code snippets and comments. I enjoyed the DIY approach but it was getting cumbersome (and less and less KISS as things went on).

Instead, I’m stealing two more ideas from the Yesod Docs site. The new site uses git’s gist feature for code snippets and disqus for comments. I know, I originally said I, “didn’t want to farm comments out to 3rd party javascript,” but disqus is really nice and I’m getting sick of all the overhead that comes with my homebrew php setup.

I’m really sorry to anyone who’s left comments so far on the site. I appreciate them greatly. I still have them and I’ll continue to look into ways to port them over to disqus, but so far, it’s not looking too promising.

I’ve changed my approach to posts and am now using pandoc to write them. This means that I don’t need gist anymore thanks to pandoc’s great syntax highlighting features. I’m also working on my own Yesod module for Comments to get things back the way it was on the old site. That’s a bit of a work in progress at the moment and will be its own post when it’s done… I’ll be keeping disqus around for a while.

Lighttpd

Another change I’m making is from Apache over to Lighttpd (pronounced: lighty). To be honest, I just couldn’t get (Fast)CGI working with apache and I had it running with lighttpd in minutes. Hopefully it’ll be faster and easier to maintain too, we’ll see…

So anyway, enjoy the new site; let me know if anything is broken or missing – I’m still in the process of migrating old posts, so give me some time before reporting that.

The site’s source is also in my git repo if anyone’s interested.

published on Oct 10, 2010, tagged with haskell, website

PHP Authentication

Recently I had the opportunity to write some php pages (some mine, some others) that required simple authentication. Nothing worthy of social security or credit card numbers; but just enough to keep something from being public.

In my case it was an admin script for the comments left on this site. I could view all of the most recent comments and click a link to mark any as spam. Doing this would remove all comments made with that IP address as well as blacklist it from any future additions.

Anyway, the authentication part was simple. It only took a little googling, so I thought I’d share the method I landed on.

Authenticate

First, I wrote a small php script to hold the authentication logic. It would have one method, authenticate() that would accept an array of (user => password) values. If it fails, the page can’t go any further. I just keeps prompting for user/pass until there’s a valid login or the user hits cancel. At which time you’ll see a Not authorized page.

It serves its purpose easily, with the added bonus that it’s hidden behind a simple authenticate() call that I can update as needed.

<?php

function do_auth() {
    // prompt for password
    header('WWW-Authenticate: Basic realm="pbrisbin dot com"');
    header('HTTP/1.0 401 Unauthorized');

    // if user cancels
    header('Content-type: text/plain');
    echo 'Not authorized.';
    exit;
}

function authenticate($_valid_users) {
    // credentials not known
    if (!isset($_SERVER['PHP_AUTH_USER']))
        do_auth();

    $user = $_SERVER['PHP_AUTH_USER'];
    $pass = $_SERVER['PHP_AUTH_PW'];

    // user not known
    if (!isset($_valid_users[$user]))
        do_auth();

    // bad password
    if ($_valid_users[$user] != $pass)
        do_auth();
}

?>

Usage is fairly simple; on any page that needs authentication, use the following:

<?php require_once('path/to/authentication.php');

$valid_users = array( 'user1' => 'password1'
                    , 'user2' => 'password2'
                    );

authenticate($valid_users);

// rest of page logic...

?>

Is it awesome? Is it safe? Is it secure? Probably not. But it serves the purpose I need. And, is it easy? Yes.

The PHP header() function has to be the absolute first thing to generate any output from your page. This means you can’t embed this authentication logic in a page with any printed HTML (static or coded) ahead of it.

published on Oct 2, 2010, tagged with php, website

XMonad Modules

This page is to serve as both an apology and an announcement. I’ve recently modularized my xmonad.hs. I’m sorry.

This is no longer true. I’ve since gone through a bit of a config cleanse, deciding it makes my life easier to live closer to defaults and not carry around a lot of extra configuration or features (that I don’t actively use).

As part of this cleanse, I’ve stripped my config back down to a very lean xmonad.hs that can easily live within the confines of a single file.

Who cares?

I know of at least one person who stops by my site on a regular basis to update his xmonad.hs to match the latest version of mine. I’ve also seen, on a few occasions, someone mention that they use brisbin33’s xmonad config when discussing an issue on the forums or in IRC. True, for all I know, there could be only three people using some form of my config – but to them, I’m sorry.

Anyone who blindly updates to my most recent xmonad.hs may get hit with the following error:

  xmonad.hs:21:7:
      Could not find module `ScratchPadKeys':
         Use -v to see a list of the files searched for.

  Failed, modules loaded: none.

That’s because I’ve offloaded some of the more module-ish chunks of my config into, well, modules.

Why?

I noticed, when browsing the XMonad source (I know, shut-up), that the default recompile command includes the option -ilib this tells ghc to include source files in ./lib. It was a light-bulb moment.

I had gathered some pretty sophisticated code in my little xmonad.hs: custom data types and instances, reusable utilities, etc. Why not put them in their own files and import them into a nice clean config as I would with any normal contrib module?

So, if you’re following my xmonad.hs, please continue to do so. Just be advised you’ll need a few files in lib if you want to use the functionality they offer.

published on Aug 31, 2010, tagged with dzen, haskell, website, xmonad

Haskell RSS Reader

I’ve been looking for a good Haskell project for a while now. The language is just awesome, and I’ve been getting more and more comfortable with it lately thanks to reading Real World Haskell. I even got the opportunity to write some haskell for a project at work (I’m a consultant on a Microsoft product, crazy).

I wanted something challenging but doable; something to keep me interested but still stretch my abilities. I had made some smaller utilities to manage the pages on my site, so I was getting familiar with parsing XML using some haskell libraries as well as starting to wrap my head around the IO Monad a bit more. Well, I just completed (what I think is) a slick little RSS reader using just haskell and dzen.

For those that don’t know, RSS feeds are basically just site headlines; a very simple XML page that lists items, each item containing a title, description, and link.

So my reader would read in a listing of feed urls, put together all of the RSS items from each url, and then display them using dzen.

I put it in the upper right of my left monitor, configured to look like part of my existing dzen status bars.

The title text remains static and is clickable (opens the url of the feed item), and the description text is a ticker text that rolls by right-to-left one character at a time.

Installation

First, you would have to download RssReader.hs and Dzen.hs from my old xmonad library and place them in a directory along side a file called rssreader.hs. This file would serve the same purpose xmonad.hs does for XMonad: it would be both a configuration file and the main application itself, gluing together imported functions into a runnable main.

Here’s an example:

import Dzen
import RssReader

-- 
-- this is it, the whole application in one line!
-- 

main :: IO ()
main = spawnDzen dzenConf >>= spawnReader readerConf

-- 
-- and the configuration part...
-- 

-- set a width and some text formatting
readerConf :: ReaderConf
readerConf = defaultReaderConf
  { titleFormat = dzenFG "#909090"
  , descrFormat = shorten 200 
  , tickerWidth = 150 
  }

  where
    -- some helpers
    dzenFG c s  = concat ["^fg(", c, ")", s, "^fg()"]
    shorten n s = if length s > n then (take n s) ++ "..." else s

-- start with the default dzen and override some things
dzenConf :: DzenConf
dzenConf = defaultDzen
  { x_position  = Just $ Percent 60 -- start 60% across screen 0
  , width       = Just $ Percent 40 -- and span the other 40%
  , font        = Just "Verdana-8"  -- if you have an xft-capable dzen                                                        
  , fg_color    = Just "#606060"
  , bg_color    = Just "#303030"
  }

Once that’s all set, you can run ghc --make -o rssreader rssreader.hs inside this directory to create an executable which you can run standalone.

Dependencies

The following packages would be required either from Hackage or your distribution’s package manager:

HackageArch linux
httpextra/haskell-http
tagsoupaur/haskell-tagsoup

Known Issues

Some unprintable characters seem to still come through. I try to clean the strings as much as possible, but I still see boxes in dzen from time to time.

The rssreader and the spawned dzen are not tied together process-wise. This means that you can kill rssreader and a frozen dzen remains, or you can quit the dzen and rssreader will be left as a zombie.

published on Aug 15, 2010, tagged with dzen, haskell, xmonad

Web Preview

Recently, I made the switch (again) away from Uzbl as my main browser. Jumanji is a really nice browser in that it’s as light as Uzbl but feels more polished. It provides almost all of the features I had to build into Uzbl myself right out of the box. The tab-completion on the commands and urls is incredibly useful and negates the need for all the external history and bookmark scripts that I was using with Uzbl. The only part I really miss is (obviously) the controllability and configurability.

I only ever used this controllability for one thing: previewing web pages as I write them. I had a nice little script that would go out and ask each Uzbl instance what its URI was, and if it matched the URI version of the filename I was currently editing it would send the reload command to this browser.

You just cannot do something like this in any other browser.

So I figured, if I relegate Uzbl to this one single simple use, it’s configurability could be leveraged such that I could strip out anything that didn’t serve this one purpose and the browser would be incredibly responsive.

In the end, I’m actually amazed at how well this worked out. During my testing, I actually spent a good ten minutes troubleshooting a nonexistent bug because the page was reloading so fast that I thought nothing was happening.

This works nicely for me because my desktop is my web server. All I have to do is vim /srv/http/pages/foo.html and I’m editing http://localhost/pages/foo.html directly.

I’m not saying it’s impossible to pull this off with a remote server, this just makes things easier. It’s up to you to port my script for use in a remote server setting.

First thing you’ll need is my script, download the raw version into your $PATH.

Adjust the in-script variables srv_dir and srv_url to match your environment. These variables are used to turn a filename like /srv/http/pages/foo.html into a url like http://localhost/pages/foo.html.

Recently the script has changed slightly to work with my new framework; I now just define file_url as a direct modification of $2.

Make sure you’ve got uzbl installed and uzbl-core is also in your $PATH.

Add the following uber simplistic configuration file for uzbl at ~/.config/uzbl/config:

set socket_dir         = /tmp
set status_background  = #303030
set uri_section        = \@[\@uri]\@
set status_format      = <span font_family="Verdana" foreground="#909090">@uri_section</span>
set title_format_short = Uzbl - \@TITLE
set title_format_long  = @title_format_short

This just makes sure a socket is placed in /tmp and makes the status bar a little more pleasing on the eyes.

Only the socket_dir declaration is actually needed for the script to function.

Finally, add the following to your ~/.vimrc:

command! Open :! webpreview --open %
command! Reload :! webpreview --reload %

au BufWritePost /srv/http/pages/* silent Reload

This defines an Open and Reload command to be used directly within vim and also sets up an auto command to fire whenever I hit :w on a page I’m editing.

In my vimrc, these are conditional for html and php filetypes and, as you can see, the auto-refresh only happens if I’m editing a file under my server’s pages directory. You’ll want to do something similar so that the script doesn’t run for all files all the time.

That’s all that’s needed. Fire up your favorite text editor and give it a try.

published on Jul 26, 2010, tagged with arch, uzbl, website