Next Image
Make the current image sticky.
Previous Image
randys.org - randys.org

Archive for the ‘General Nerdery’ Category

How-To: Automated Backups to Amazon’s S3 with Duplicity

I’ve been using Amazon’s S3 service for a couple months now. It was working OK using s3sync and a cron job, but it seemed like it wasn’t actually making incremental backups and I wasn’t 100% sure that it was backing up everything (i.e. it appeared to be crapping out once in a while). I searched around for various S3 backup solutions and found a handy utility called duplicity. Even more handy that it is available for most distributions (Archlinux, the debs, and Fedora anyway).

From the duplicity home page:

Duplicity backs directories by producing encrypted tar-format volumes and uploading them to a remote or local file server. Because duplicity uses librsync, the incremental archives are space efficient and only record the parts of files that have changed since the last backup. Because duplicity uses GnuPG to encrypt and/or sign these archives, they will be safe from spying and/or modification by the server.

What you’ll need

You’ll need to make sure you have a few things installed before you install duplicity. Namely librsync and GnuPG. Luckily, if the duplicity package is available for your distribution, you probably needn’t worry.

Here’s a rundown of the steps involved:

  1. Generate a new GnuPG key
  2. Create a simple shell script wrapper
  3. Create a cron job

Generating a new Key

Start by generating a new gpg key for duplicity. Or if you have an existing one, you can use that.

N.B. I set this up on a Slice running Arch64 and had problems generating a new key (gpg --gen-key). Apparently, it could not generate enough entropy. Not a problem though: Just generate the keys else where and import them later if this happens to you.

#~ gpg --gen-key
gpg (GnuPG) 1.4.7; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

Please select what kind of key you want: (1) DSA and Elgamal (default) (2) DSA (sign only) (5) RSA (sign only) Your selection?

Default (DSA and Elgamal) is fine here.

DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)

The default (2048) is more than enough for this. Change it to whatever you want.

Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)

Unless you want the key to expire (I don’t see why one would want that), the default is what we want.

Key does not expire at all
Is this correct? (y/N)

Um, yes, this is correct.

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: DuplicityBackup Email address: duplicity@mydomain.com Comment: Key for Duplicity You selected this USER-ID: "DuplicityBackup (Key for Duplicity) <duplicity@mydomain.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

Enter whatever information you want here and type ‘O’ for ‘Okay’

You need a Passphrase to protect your secret key.

Enter Passphrase:

Enter something. Anything. The more complex the better. This is your private data. Remember that it’s being transfered over http to a server you don’t own. I don’t care if it is Amazon. Remember what you type because you’ll need it later while creating the wrapper script.

gpg: key 9929DAB1 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u pub 1024D/9929DAB1 2007-11-15 Key fingerprint = 3378 8E93 4349 0E7F 44F3 7C81 2460 5A11 9929 DAB1 uid DuplicityBackup (Key for Duplicity) <duplicity@mydomain.com> sub 2048g/5385A6BB 2007-11-15

And you’re done. Make note of the key (in this case, 9929DAB1) as we’ll need that later too.

But I already have a key I want to use

OK, fine, but chances are, if you have a key already, you know how to get it. However, if you don’t know how to get your key, gpg --list-keys. You want the key in the ‘pub’ line… after the forward slash ‘/’

The Wrapper

This can be written in any language really. I chose shell because it’s easy and basic. You could run the duplicity now on the command line, but writing a wrapper is much more convenient and makes adding a cron job later a lot easier. Here’s what you’ll need:

  • Your Amazon S3 Access Key ID and Secret Access Key. If you don’t have one, you’ll have to sign up for one.
  • Your GPG key
  • Your GPG key’s passphrase
  • A list of directories you want to back up

Here’s a basic script that works for me:

#!/bin/bash
# Export some ENV variables so you don't have to type anything
export AWS_ACCESS_KEY_ID=&lt;your-access-key-id&gt;
export AWS_SECRET_ACCESS_KEY=&lt;your-secret-access-key&gt;
export PASSPHRASE=&lt;your-gpg-passphrase&gt;

GPG_KEY=&lt;your-gpg-key&gt;

# The source of your backup
SOURCE=/

# The destination
# Note that the bucket need not exist
# but does need to be unique amongst all
# Amazon S3 users. So, choose wisely.
DEST=s3+http://&lt;your-bucket-name&gt;

duplicity
    --encrypt-key=${GPG_KEY} \
    --sign-key=${GPG_KEY} \
    --include=/boot \
    --include=/etc \
    --include=/home \
    --include=/root \
    --include=/var/lib/mysql \
    --exclude=/** \
    ${SOURCE} ${DEST}

# Reset the ENV variables. Don't need them sitting around
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export PASSPHRASE=

And, that’s pretty much it. Save the file as something creative, like, backup and make it executable (chmod 700 backup). If you want to test it first (and you have the disk space), change the destination to some /tmp directory or external HDD. Once you’ve got it working the way you want, set it up as a cron job. Daily, weekly, monthly… doesn’t matter.

Duplicity is a nice backup solution for any situation, not just Amazon’s S3. It can handle HTTP, SCP and local backups as well. I highly recommend reading the duplicity man page and checking out the various command line arguments and availble options.

A couple of Thanks goes out to Tim McCormack’s and Ben and Ron’s articles which got me started.


Tim points out that, adding your GPG PASSPHRASE to the shell script might not be the most secure method, especially in a shared environment. I agree, however, it kind of defeats the purpose of automated backups if you have to actually enter your passphrase (twice) on the command line when calling the wrapper script. One way I managed to go around this is to create a simple C++ application that prints the passphrase.

Here’s the C++ code:

#include <stdio.h>
int main()
{
    printf("your-gpg-passphrase");
    return 0;
}

Compile

#~ gcc gpg-passphrase.c -o gpg-passphrase

Make it executable by your user and set the sticky bit so no one else can execute it

#~ chmod 700 gpg-passphrase

~ chmod +s gpg-passphrase

Modify the wrapper script to use the binary for the passphrase

export PASSPHRASE=$(gpg-passphrase)

You might go as far as to do the same thing for your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as well. There are probably other ways around this, but this was a quick a dirty way to not have readable strings in shell scripts. I figure, if someone has rooted my server, I’ve got bigger problems to worry about than my data sitting on Amazon’s S3.

• • •

How Old Is Your Login?

See here, Bullet point number one:

Logging in with an account originally created in Mac OS X 10.1 or earlier that has a password of 8 or more characters.

Mac OS X 10.1 came out just over six years ago in 2001. If you’ve been using the “upgrade” option every time you update your OS X version, I think it’s time you performed a fresh install. Especially on such an old system (what do you have, an original Quicksilver? No? Older?). If you’ve made it this long without having to do a clean install, congratulations. You’re one of very small number of people. Hell, I haven’t kept a computer for longer than two or three years.

I bought my first Apple in 1997 — PowerPC G3 300Mhz (of the Beige kind). I bought my second Apple in 2000 — Quicksilver 733Mhz (non-shiny doors). Sold the G3 in 2002 (or so). I bought my first Powerbook in 2003 (G4 1Ghz Titanium) slightly used from a nice girl (with buyer’s remorse) in San Francisco. It took a dump about two years ago and I succumbed to way of cheap x86 hardware and Linux. But I redeemed myself about a year and a half ago when I bought my second Apple laptop (Macbook Pro 2.16Ghz).

I digress. What I’m saying is that, even if you’re lucky enough to have the same computer for the last six years (or more), I doubt you’d be as lucky going through four separate system upgrades (assuming you upgraded every version). Even if you didn’t and you went from 10.1 directly to 10.5, I highly doubt Apple spent much time testing that upgrade path (if at all).

• • •

Sliced Goodness

Welp, I’ve switched over this domain (randys.org) to Slicehost’s DNS servers so you should be reading this from a freshly installed Archlinux running Ruby on Rails and Mephisto (along with MySQL, PHP, Apache, yadda yadda yadda). It appears to be a noticeable improvement in terms of speed.

void appears to be a little off. Looks like my static file server isn’t configured properly… or something.

• • •

How-To: Install Archlinux on Slicehost

I recently acquired a 256 Slice from Slicehost. While their distribution selection is good, I was hoping for something, well, different. My old VPS is rocking Ubuntu (quite well) but I just want something else. Slicehost’s other distributions weren’t going to cut it.

  1. Ubuntu Dapper – Already running that.. that’s how I got here.
  2. CentOS 4.3 – Um, no. Never liked RedHat. Hate RPMs. Package management is a nightmare.
  3. Gentoo 2006.1 – I’ve used Gentoo in the past (a lot) and enjoyed it. I even tried it on my old VPS. I just don’t have the patience to wait for shit to compile.
  4. Debian Etch – Debian is a true soldier. Secure and stable. However, not up-to-date enough for my tastes (that’s why I went with Ubuntu).
  5. Fedora 6 – See #2.

Enter Archlinux.

This little how-to was taken from various places on the net, but the bulk of it is from Anders’ Blargh post and a couple of comments in a previous post of mine. So, let’s dive in.

Back It Up!

If you have any valuable information on your slice, now would be the time to make a backup of the important stuff you want to keep.

Bootstrapping

First thing you want to do is bootstrap Arch64 to directory on your current distribution. If you happen to have a 64bit version running at home, you could do this locally and it should still work (in theory).

# export PACMAN_VERSION=3.0.5-2

export XEN_MODULES_VERSION=2.6.16.29

wget http://www.randys.org/assets/2007/8/17/archbootstrap-packages-20070817

wget ftp://ftp.archlinux.org/current/os/x86_64/pacman-${PACMAN_VERSION}.pkg.tar.gz

tar zxvf pacman-${PACMAN_VERSION}.pkg.tar.gz -C /

mkdir /arch

At this point, you might want to edit /etc/pacman.conf and /etc/pacman.d/current to your liking. Picking a close/fast mirror will help speed things along.

# pacman.static -Sy cat archbootstrap-packages-20070817 -r /arch

Now you need to bind /dev, /sys and /proc to the bootstrap directory so you can chroot in.

# for s in dev sys proc; do mount /$s /arch/$s --bind; done

Copy some important files for the chroot.

# cp /etc/mtab /arch/etc/

cp /etc/fstab /arch/etc/

cp /etc/resolv.conf /arch/etc/

We also need to copy the all important xen kernel modules from the existing slice into our Arch64 bootstrap directory.

# cp -r /lib/modules/${XEN_MODULES_VERSION}-xen /arch/lib/modules/

Now we’re ready to chroot into your new Arch64 directory.

# chroot /arch /bin/bash

One of gotchas I had was when I went to SSH into my newly booted Arch64 Slice. It would connect and I could enter my password, but it would hang and never drop me to a command line prompt. Did a little searching and found that it was all because /dev/pts was not being mounted at boot time. Easy fix.

#[] echo "none  /dev/pts    devpts  gid=5,mode=620  0 0" >> /etc/fstab

Edit /etc/locale.gen and enable any locales you require. en_US.UTF-8 UTF-8 and en_US ISO-8859-1 are popular choices. Now generate the locales.

#[] locale-gen

Edit /etc/pacman.conf and /etc/pacman.d/(current|extra|community) in your chroot to your liking. If you don’t do it here, you can always do it when you get it running. But we’re about to install openssh, so now is as good a time as any.

#[] pacman -Sy openssh

Now you nee to add sshd to our DAEMONS array in /etc/rc.conf file

#[] vim /etc/rc.conf
    ...
    DAEMONS=(syslog-ng network netfs crond sshd)
    ...

While you’re in /ect/rc.conf, go ahead and setup your network interfaces and gateway. You can get the current information from your running Slice (for Ubuntu cat /etc/network/interfaces)

    ...
    eth0="eth0 XXX.XXX.XXX.XXX netmask 255.255.255.0 broadcast XXX.XXX.XXX.XXX"
    INTERFACES=(lo eth0)
    gateway="default gw XXX.XXX.XXX.XXX"
    ROUTES=(gateway)
    ...

Next, you’ll need to modfy /etc/hosts.allow so you can actually connect to our new Arch64 VPS via ssh.

#[] echo "sshd : ALL : allow" >> /etc/hosts.allow

If there’s any other tweaks you want to make, make them now. Otherwise, exit the chroot.

One thing I did before exiting the chroot to cut down on the bootstrap size is to clear pacman’s cache directory. It should probably save you 100MB+ and there’s no need to keep them at this point.

#[] pacman -Scc

[] exit

Unmount the dev, sys and proc filesystems you mounted earlier.

# umount /arch/dev

umount /arch/sys

umount /arch/proc

Now we’ll archive the files.

# cd /arch && tar cjvf /archbootstrap-$(date +%Y%m%d).tar.bz2 *

That’s it. You’re all set. If you want to keep a copy of this so you don’t have to do all this again, do it now.

# scp /archbootstrap-$(date +%Y%m%d).tar.bz2 <username>@<hostname>:<path>

Dealing with Slicehost

At this point you should have a working Arch64 install ready to be installed. Now you need to login to the Slicehost manager and put your slice into Rescue Mode. Login to your slice via SSH. Once logged in you’ll need to mount your slice’s partition and copy the archive to the rescue disk.

#[r] mkdir /mnt/oldslice

[r] mount /dev/sda1 /mnt/oldslice

[r] cp /mnt/oldslice/archbootstrap-* /root

[r] umount /mnt/oldslice

Next, format your old slice partition and re-mount it so you can install Arch64.

#[r] mke2fs -j /dev/sda1

[r] mount /dev/sda1 /mnt/oldslice

[r] tar xjvfp /root/archbootstrap-*.tar.bz2 -C /mnt/oldslice/

And that’s about it. You should now have a working Arch64 installation on your new Slice! Probably a good idea to double check all your settings before rebooting your slice, but, then you do have access to the rescue console.

Enjoy! And thanks to Anders for pointing me in the right direction.


If you find any errors or have any additions, please let me know and I’ll update this post.

• • •

VPSLink, I’m breaking up with you

It’s not you, it’s me (again)

It’s been a year since I first signed up with VPSLink. They’ve been a decent host for the most part. They had some troubles in the beginning with disk I/O and server loads, but those have pretty much been kept at a minimum as of late. I still experience high server load from time to time (like earlier today), but for the most part it’s generally OK. Nonetheless, I’ve decided to move on (again). Try something different. Something new. Something, better?

It’s not that I don’t like VPS technology. I do. In fact, I don’t think I could go back to a shared hosting environment again (sorry DH). I think it’s the virtualization technology (and perhaps the limitations of OpenVZ/Virtuozzo(TM)).

How you doin’?

When I first started looking for a VPS provider last year, I briefly signed up for one particular Xen provider. The server itself was pretty good, but the support and communication were lacking. I quickly ditched that host for VPSLink. Unfortunately, I paid for a year in advance and they don’t refund unused months so I was stuck in a mediocre relationship with a host I wasn’t happy with.

Then I met Slicehost. They use Xen and are reasonably priced for the same stats I’m getting over at VPSLink (actually, Slicehost is a smidgen cheaper). It’s build by developers, for developers and has a growing community. Last week I emailed support to ask a question just to see how quickly they respond. I got a response within 30 minutes. Fast enough for me.

Here’s a list:

  • Xen based virtualization
  • Proper VPS/Server ratio (<= 24 per Server depending on the Slice)
  • Quad Core, 64bit CPUs and OS
  • OS of choice. If I don’t like what they offer, I can install what I want
  • Growing community of users (Wiki, Forum, IRC, and Campfire)

To Close for Comfort

My VPSLink account is now due (by the 18th) and I just submitted a request for a new Slice yesterday. I’m cutting a little close. I’m trying to get things setup locally so help migrate everything over as quickly as possible, however, I’m fairly confident that nothing will go as planned. There will inevitably be some down time… the question is, how much?

• • •

Work, Ruby, VMware, Cable vs. DSL

Work Politics and the Stationary Career Path

Work has been a pain. There’s really no other way to describe it. Everyone is getting pissy because of tight deadlines and it’s only a matter of time before the finger pointing begins. I’m OK with that. Finger pointing doesn’t affect me as much. I just shrug it off and laugh. Usually in front of the person doing the pointing.

One of the things that really bugs me though is the fact that my career there feels stagnant. I’ve asked for a title increase once and been shot down. It’s not the fact that I was shot down that upsets me. It’s the response I received from upper management. Something about “implications” surround the idea of promoting me. I’ve been told by several people at the company that my name comes up often as the “go-to” person when it comes to getting things done and picking up where others left off. I’ve been told by higher paid employees that I am far more knowledgeable than they are and that I am highly regarded.

I don’t get it. I think they want me to quit. I’ll ask again, but I fear I will either get the same response or worse, no response.

Ruby

I was all gung-ho the other night about diving into Rails. I still am. I am just running out of steam these days. Between the nine hours at the day job and a couple hours after on the side gig that doesn’t pay, I just can’t find the time.

It is going to happen though. It is. Shut up.

VMware and Unity

Is it me, or is VMware really giving Parallels a run for their money? I’ve been using VMware Fusion as my virtual machine of choice for the past several months. I’ve always felt that VMware has had a slight leg up on Parallels in the performance department. Now with Unity, I think VMware has a solid lead in the VM race. It is just an awesome product. I highly recommend trying it out. It’s still in beta, but so far, I haven’t had any issues running XP or Ubuntu (Feisty). Best of all, if F R double E whilst in beta.

Cable vs. DSL

We’re cutting back on the spending around the house lately. One of the things I’ve chosen to sacrifice is Cable to DSL. As much as I hate the pone company, I’m willing to save $20 or so bucks per month for (what I thought was) a slightly slower interweb. Slightly was a total understatement. While downloading the latest VMware, I really felt the pain. First off, my download speed was a measly 68Kb/s and then to top that off, the transfer died 50MB into the download. Luckily, I just hooked this all up tonight and have not canceled cable just yet. I pulled out the cable modem and finished the download in four minutes (averaging ~700Kb/s). Pathetic. I think if I do a cost per bandwidth, I’m actually getting ripped off by DSL.

There was a whole host of other mishaps with the DSL order, but, I’m not going to get into that.

• • •

Personal goal: Learn Ruby (on Rails)

The time has come. I need to discipline myself to learn Ruby (on rails). It’s been around for quite a while now and I just have dig in. So I’m making a new personal goal: learn Ruby or bust.

The problem is that breaking the PHP habit will be dificult. Although, I’ve become more OOP aware and always try to create objects instead of random functions. I suppose I could stick with PHP and use Cake or Zend’s Framework to build MVC style applications, but, that sounds increasingly boring these days. I need something new to obsess over.

So, I’m off to learn. I can’t really learn by book; it just doesn’t work for me. I have to get my hands dirty. What better way to do that than to build something. I’m not talking about building a blog in 15 minutes (especially since there several other blogging type applications written in RoR already). It will have to be something somewhat unique that will keep me interested enough in the language and challenging enough to keep me busy. I’m open to suggestions and always open to collaboration (if anyone is interested).

• • •

Mephisto: How-to add monthly archives to the side-bar

One of the odd things I’m finding with Mephisto is that none of the templates I looked at had monthly archives in the sidebar. That’s generally not that strange, but Mephisto doesn’t really paginate (out of the box, anyway) sections (categories), so the lack of any way for a user (that would be you) to navigate to older posts is beyond me. So the search for some Liquid code to display monthly archives began.

Mephisto’s documentation is seriously lacking, but what can you expect from a small development team with no funding behind the app. Most of the links I followed were to the Mephisto Google Group. I took this snippet from one particular thread:

 <ul>
 {% for month in section.months %}
     {{ section | monthly_articles: month | assign_to: 'monthly_articles' }}
     <li>
     {% if monthly_articles %}
         {{ section | link_to_month: month }} ({{ monthly_articles | size }})
     {% else %}
         {{ month | format_date: 'my' }}
     {% endif %}
     </li>
 {% endfor %}
 </ul>

But this would still spit out months with no posts. We can’t have that! So, I turned it into this:

{% if section.months.size > 0 %}
<ul>
    <li class="head">Archives</li>
    {% for month in section.months %}
    {{ section | monthly_articles: month | assign_to: 'monthly_articles' }}
        {% if monthly_articles.size > 0 %}
            <li><span class="right">{{ monthly_articles | size }}</span>
            {{ section | link_to_month: month }} </li>
        {% endif %}
    {% endfor %}
</ul>
{% endif %}

Much better! Now I have this:

• • •

Long time, no post

I know it’s been a while. I’m sorry. I went through a phase where I just didn’t feel like contributing very much (hence the Tumblr episode). Don’t worry, the vast void of meaninglessness is still available and I’ll still be posting uninteresting tid-bits I find on the intertubes there.

So, last night I took it upon myself to give this site another chance. This time, with the help of Mephisto (another RoR blogging app). The install went smoothly. The conversion was a little bit of a pain, but I managed to make it work with a little help. So far, I like Mephisto. Better than Typo. It has less ‘bells and whistles’ but manages to have the essentials. And, it feels faster on my poor little 256MB VPS. It’s been running over night (granted with minimal to no traffic) and it’s currently sitting at ~40MB of memory (compared to the 60 – 80MB that Typo would suck on regularly).

Don’t get me wrong, Typo is a wonderful product. However, because I’m limited on RAM, I became frustrated with Rails thinking it was a complete memory hog. But that’s not the case really since I’m running Mephisto wich uses the same framework and the memory consumption is almost half of what Typo was using. If I had twice the memory, I’d probably still be using Typo… but I don’t and I can’t afford to throw more money into a site that doesn’t reciprocate.

I’m hoping to really dig into Ruby now. My crappy side gig with .e is winding down and I’m pretty much fed up with my day job so I’d like to move completely away from the Java/.NET environment I’m forced to work in everyday. Nothing would make me happier than be able to work on my Mac (or any Mac for that fact) doing PHP or better still, Ruby/Rails work. Call me snoby, I don’t care. It is what it is.

• • •

Scrobble This: last.fm recent tracks AJAX style

So, I’ve been reading up a bit on prototype.js and its Ajax helpers. It’s an amazing tool and helped me write the bit of info at the top of the page. It’s pretty basic, but here’s the code that does most of the work:

function lastfm()
{
    new Ajax.Request('/as/recenttracks.xml',
    {
        method: 'get',
        onLoading: function() {

    },
    onLoaded: function(transport) {
        if (transport.overrideMimeType) {
            transport.overrideMimeType('application/xml');
        }
    },
    onSuccess: function(transport) {
        var response = transport.responseXML.documentElement;
        updateLastfm(response);
    },
    onFailure: failedLastfm()
});

}

The only issue I ran into was that I was originally using the RSS flavor of recent tracks, however it didn’t split up the artist and track information. It displays it as <title>[artist] – [track]</title>. That en-dash in the middle was preventing me from using title.split() on the JavaScript side of things. Really weird.

Also, since I’m a complete newbie with Ruby, I couldn’t figure out how (read: didn’t take the time to learn) to grab the content from a remote server and serve it up to the JavaScript. I’m sure it’s pretty simple… but I was at work and in a hurry. So, being that I know PHP, I just created a script to download the file and save it to the local disk and setup a cronjob.

Here’s the PHP script:

class lastfm
{
    private $user;
    private $reports;
    private $basews;
    public $saveto;

function __construct($user)
{
    $this-&gt;user = $user;
    $this-&gt;basews = 'http://ws.audioscrobbler.com/1.0/user/';
    $this-&gt;reports = array(
        'recenttracks.xml',
        'weeklyartistchart.xml',
        'weeklytrackchart.xml',
        'topartists.xml'
    );
    $this-&gt;saveto = '.';
}

public function go()
{
    for ($i = 0; $i &lt; count($this-&gt;reports); $i++)
    {
        try
        {
            $opts = array('http' =&gt; array('method' =&gt; 'GET', 'header' =&gt; 'Content-type: text/plain; charset=utf-8'));
            $context = stream_context_create($opts);

            $fp = fopen($this-&gt;saveto.DIRECTORY_SEPARATOR.$this-&gt;reports[$i], 'w+');
            $stream = fopen($this-&gt;basews.$this-&gt;user.'/'.$this-&gt;reports[$i], 'r', false, $context);
            $string = stream_get_contents($stream);
            fwrite($fp, $string);
            fclose($fp);
            fclose($stream);
            echo 'Saved ' . $this-&gt;saveto.DIRECTORY_SEPARATOR.$this-&gt;reports[$i] . "\n";
        }
        catch (Exception $e)
        {
            echo $e-&gt;getMessage() . "\n";
        }
    }
}

public function setSaveto($path)
{
    if (is_dir($path))
    {
        if (ereg('\/$', $path))
        {
            $path = ereg_replace('\/$', '', $path);
        }
        $this-&gt;saveto = $path;
    }
    else
    {
        $this-&gt;createDir($path);
        $this-&gt;setSaveto($path);
    }
}

private function createDir($path)
{
    if (!is_dir($path))
    {
        $res = `mkdir -p $path`;
    }
}

}

I’ll hit up the Rails API Docs one of these days and write a simple Ruby script that does all the work of the PHP script. Even better would be to process the XML document using ruby that just returns a string of HTML and use Ajax.PeriodicalUpdater($(e), ...).

• • •

All content Copyright © 1999 — 2010 Randy Sesser | Happily Hosted by WebFaction
Entries (RSS) | Comments (RSS)