Migrate from Google Reader to SelfOSS

Google Reader is closing, leaving those of us with hundreds of feeds in the lurch.

If you’d like to get out of the lurch, and don’t like the looks of the magazine-style RSS readers, I’d like to recommend SelfOSS.

It’s a self-hosted option, so you’ll need your own server, but it’s simple to set up, it looks good, and last night I added OPML support so you can import your Google Reader list.

You can see a demo here. The demo is automatically reset every hour.

SelfOSS Demo
SelfOSS Demo

 

Posted in Computers, Programming | Tagged , , | Leave a comment

Home Made Wood Christmas Tree Star

Finished stars with camera flash
Finished stars with camera flash

Last year I made a wooden Christmas Tree star for our family. We liked it so much that this Christmas I made more to give as gifts. Above are the three stars I made this year, below is a picture of our star on our tree.

Materials Needed For the Star

  • Two 1-inch thick boards made from different types of wood.
    • The stronger the grain, the better.
    • I used one red oak, and one maple.
    • One 8x11x1 inch board will yield 3 stars worth
  • White glue, and lots of it. Most wood glue usually dries yellow, so don’t use that.
  • A saw. I used a table-top scroll saw
  • An electric sander or sandpaper
  • A drill with a 5/8 inch bit

Here’s the pattern I made as a PDF for printing, or as an SVG file if you want to edit it (using Inkscape or Illustrator).

Finished star on our tree
Our finished tree star from last year.

Glue both boards together and clamp or weight them until the glue is completely dry. Glue the pattern on top of the boards.

Oak and Maple Boards Glued Together
Oak and Maple Boards Glued Together
Star segment cutout pattern
Star segment cutout pattern

Cut along each line and set aside each whole triangle segment. Remember, the segments are 2 inches thick since the boards are glues together. Cut slowly.

Gluing star segments together
Gluing star segments together

Flip half of the segments over and glue them face-to-face so that each half of the star point has the opposite grain as pictured below. Clamp each pair of segments together so that you end up with 5 points, each point made of 4 pieces of wood.

I had a difficult time cutting exactly straight so there are some gaps between segments. Even with the gaps the star ends up looking nice in the end so don’t worry about them too much.

Star segments cut out and staged
Star segments cut out and staged

When they’re dry, you should have a bunch of star points that look like this. The blue line below indicates where the next cut needs to happen.

Glued star point
Glued star point with 2nd cut line

Brace up the point using a leftover triangle from the first set of cuts and watch those fingers.

Using a partial star point to get the right cut angle on a star point
Using a partial star point to get the right cut angle on a star point

Here’s my 15 star points ready to be glued. I laid them on wax paper so that it’d be easy to peel them off when the glue dried.

Assembling the tree stars on wax paper
Assembling the tree stars on wax paper

I used leftover pieces from the first cuts again to support the ends of the star points while they were drying.

The stars need to dry really well at this point. Sanding and drilling come next. If the glue in the middle of the star isn’t dry, either of these activities could break the star apart.

Dried star ready for sanding
Dried star ready for sanding

I probably would’ve used my palm sander, but I lent it out so the belt sander was going to have to do the trick. I clamped it upside-down to the table and locked the trigger on. It actually worked really really well. I will do this again next time.

Sand off any remaining paper from the pattern, and round the corners and edges to taste.

Sanding surface
Sanding surface

Carefully drill holes most of the way through the star. I started with a 1/4 bit and worked my way up to a 5/8th inch.

Sanded stars with hole drilled in the bottom
Sanded stars with hole drilled in the bottom

Stain and protect the stars however you want. I used a light yellow stain and shellac.

The stands I made are just a simple square of wood routered, with a dowel stuck in the middle. I figured that some people might already have a Christmas Tree star they liked, and this way they could display it on a mantle or something instead.

Stars without camera flash
Stars without camera flash

If you make some stars let me know!

 

Posted in Projects, Something Interesting, Woodworking | Tagged , | 2 Comments

Import Photos (and Videos) Into Date Based Directory Structure

In Linux, Shotwell organizes my photos into Year/Month/Day directories, and that’s the structure I like. I use rsync to copy all my photos to my server where they get backed up.

On Windows 7 I couldn’t seem to make the native Windows import or Picasa import them in the same directory structure. Since I’ve been trying to learn Python, I have been using it for little projects here and there, and used it for this project.

You need Python 2.5+. I’m using 2.7.

Features

It will import all photos and videos (according to mime type, determined by file extension) into date based directories. For jpegs, it tries to use the EXIF tags if possible. As a fallback, and for all other files, it uses the results of os.stat(file)[9] (ctime).

If duplicate file names are encountered, it checks the md5 sum and either doesn’t copy (if the md5s match) or creates numbered versions (DSC0001.JPG, DSC0001_1.JPG, DSC0001_3.JPG).

If you are looking for a different directory structure, it can probably accommodate your needs. The directory names are made with strftime, so any variable strftime understands can be used.

Usage

import_photos.py SRC_DIR DEST_DIR

Eg. G: is my memory card. E:\Photos is the FAT32 partition my Linux and Windows installs share.

import_photos.py G:\ E:\Photos

You can put that into a .bat file for the convenience of single-click imports if your memory card is always in the same place.

Code

I should still be considered a Python newbie, so this code may not be the most Python-ish way to do things. It does seem to work just fine though.

You’ll need exif-py.

 #!/usr/bin/env python 

import os
import sys
import signal
import mimetypes
import EXIF
import time
import shutil
import hashlib

# SETTINGS

# These types will be copied using their EXIF data if possible (falls back to their c_time)
jpegTypes = ['jpeg','pjpeg']

# These types will be copied using their c_time
supportedTypes = ['image','video']

# This is the directory structure that the pictures will be copied into
dirformat = "%Y" + os.sep + "%m" + os.sep + "%d"

# CODE

# Handle Ctrl-c without doing a backtrace
def signal_handler(signal, frame):
        sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)

# Handle incorrect parameters
if len(sys.argv) is not 3:
    print "USAGE: import_photos.py srcpath destpath"
    print ""
    print "Example: import_photos.py G:\ E:\Photos"
    exit()

# Grab parameters
srcdir = sys.argv[1]
destdir = sys.argv[2]

# Get the md5 hash of a file
def md5file(filename):
    f = open(filename,mode='rb')
    d = hashlib.md5()
    while True:
        data = f.read(8192)
        if not data:
            break;
        d.update(data)
    f.close()
    return d.hexdigest()

# Try to copy a file. Handle duplicate names
def copyFile(timestamp,filename):
    destpath =  destdir + os.sep + time.strftime(dirformat,timestamp) + os.sep + os.path.basename(filename)

    if not os.path.exists(os.path.dirname(destpath)):
        os.makedirs(os.path.dirname(destpath))

    # keep modifying destpath with incrementing numbers until we find
    # an unused number or find a duplicate file. If the file is a
    # duplicate, return instead of copying
    if os.path.exists(destpath):
        basename = os.path.basename(filename)
        filenamepart,extension = os.path.splitext(basename)
        counter = 1
        srchash = md5file(filename)

    while os.path.exists(destpath):
        if md5file(destpath) == srchash:
            print "Not re-copying existing file " + filename
            return
        destpath = destdir + os.sep + time.strftime(dirformat,timestamp) + os.sep + filenamepart + "_" + str(counter) + extension
        counter += 1

    print "Copying " + filename + " to " + destpath
    shutil.copy2(filename,destpath)

# Check all files and send appropriate files off to get copied
def probeFile(filename):
    maintype,subtype= mimetypes.guess_type(filename) 
    if maintype is not None:
        destPath = None
        category,subtype = maintype.split('/')

        if subtype in jpegTypes:

            # Try to get exif taken date
            jpg = open(filename,'rb')
            tags = EXIF.process_file(jpg,details=False,stop_tag="EXIF DateTimeOriginal")
            jpg.close()

            if "EXIF DateTimeOriginal" in tags:
                origTime = tags["EXIF DateTimeOriginal"]
                timestamp = time.strptime(str(origTime),"%Y:%m:%d %H:%M:%S")
            else:
                create_date = os.stat(filename)[9]
                timestamp = time.gmtime(create_date)

            copyFile(timestamp,filename)
        elif category in supportedTypes:
            create_date = os.stat(filename)[9] # [9] is st_ctime
            copyFile(time.gmtime(create_date),filename)
        else:
            print "I didn't copy " + filename + " because it's not on our list of supported types (" + maintype + ")"

# Walk the directory and handle media files
for (root, subFolders, files) in os.walk(srcdir):
    for file in files:
        probeFile(root + os.sep + file)
Posted in Programming | Tagged , , , , | Leave a comment