Commits

hoop committed 4b541cd

Replace uploadr.py with simpleuploadr.py

Comments (0)

Files changed (59)

 *.pyo
 secrets
 .flickrToken
+.flickrHistory
 uploadr.history
+flickrapi
+libs
 Takes snapshots from all installed webcams. Add to cron. You'll need a working browser or
 be able to figure out what URL uploadr.py is trying to send you to on its first run. I
 was able to get this from within Lynx and pasted that URL into Chrome to authenticate
-the API key. Oh yeah, you'll need to signup for one of those too. See the link in
-the secrets file.
+the API key. Oh yeah, you'll need to signup for one of those too.
 
 
 REQUIREMENTS
 ------------
 * streamer
-
+* python-flickrapi <http://stuvel.eu/flickrapi>
 #!/bin/sh
 
-# Set these to your API key | http://www.flickr.com/services/apps/create/apply
-export FLICKR_UPLOADR_PY_API_KEY=""
-export FLICKR_UPLOADR_PY_SECRET=""
-export FLICKR_UPLOADR_IMAGE_DIR="/srv/snapshots/"
+# API Auth Configuration
+export FLICKR_API_KEY=""
+export FLICKR_SECRET=""
+export FLICKR_USERNAME="" # your yahoo username
 
+# File/Directory Configuration
+export FLICKR_IMAGE_PATH=""
+export FLICKR_TOKENFILE=".flickrToken"
+export FLICKR_HISTORYFILE=".flickrHistory"
+
+# Upload defaults information
+export FLICKR_DEF_TITLE=''
+export FLICKR_DEF_DESC=''
+export FLICKR_DEF_TAGS=''
+export FLICKR_DEF_TAGDATE='yes'
+export FLICKR_DEF_IS_PUBLIC='yes'
+export FLICKR_DEF_IS_FRIEND='no'
+export FLICKR_DEF_IS_FAMILY='no'
+export FLICKR_DEF_CONTENT_TYPE='1'
+export FLICKR_DEF_HIDDEN='no'
+
+export FLICKR_PHOTOSET_ID=""
+
+#!/usr/bin/env python
+
+"""Upload a file/directory to flickr and perform some post-upload tasks"""
+
+# Imports
+from os import environ,listdir,path
+from datetime import datetime,date
+from flickrapi import FlickrAPI
+
+# Globals
+# TODO: Load these in from a config file of some sort (settings.py?)
+# TODO: Lead user to auth page
+USERNAME = environ['FLICKR_USERNAME']
+IMAGE_PATH = environ['FLICKR_IMAGE_PATH']
+DATEFMT = '%Y%m%d.%H%M'
+
+UPLOAD_DEFAULTS = dict(
+    title=environ['FLICKR_DEF_TITLE'],
+    description=environ['FLICKR_DEF_DESC'],
+    tags=environ['FLICKR_DEF_TAGS'],
+    is_public='1' if environ['FLICKR_DEF_IS_PUBLIC'] == 'yes' else '0',
+    is_friend='1' if environ['FLICKR_DEF_IS_FRIEND'] == 'yes' else '0',
+    is_family='1' if environ['FLICKR_DEF_IS_FAMILY'] == 'yes' else '0',
+    content_type='1' if environ['FLICKR_DEF_CONTENT_TYPE'] == 'picture' else '3',
+    hidden='1' if environ['FLICKR_DEF_HIDDEN'] == 'no' else '2', )
+
+if environ['FLICKR_DEF_TAGDATE'] == 'yes':
+    UPLOAD_DEFAULTS['tags'] = ' '.join([UPLOAD_DEFAULTS['tags'], str(date.today()), datetime.now().strftime(DATEFMT)])
+
+PHOTOSET_ID = environ['FLICKR_PHOTOSET_ID'] or None
+HISTORYFILE = environ['FLICKR_HISTORYFILE']
+TOKENFILE = environ['FLICKR_TOKENFILE']
+SUPPORTED_TYPES = ['jpeg','jpg','png','gif']
+TOKEN=None
+
+def mark_uploaded(filename):
+    """Mark a file as having been uploaded"""
+    # TODO: SQLite
+    # TODO: Use hash instead of filename
+    f = open(HISTORYFILE,'a')
+    f.write("%s\n" % filename)
+    f.close()
+
+
+def is_uploaded(filename):
+    f = open(HISTORYFILE,'r')
+    files = f.readlines()
+    f.close()
+    return filename+"\n" in files
+
+
+def load_token():
+    """Load flickr authentication token from disk"""
+    return open('.flickrToken','r').read()
+
+
+def get_image_files(path):
+    """Return list of supported image files in given directory"""
+    image_files = []
+    for filename in listdir(path):
+        ext = filename.split('.')[-1].lower()
+        if ext in SUPPORTED_TYPES:
+            image_files.append(filename)
+    return image_files
+        
+
+def main():
+    global TOKEN
+    TOKEN = load_token()
+
+    api_key = environ['FLICKR_API_KEY']
+    secret = environ['FLICKR_SECRET']
+
+    api = FlickrAPI(api_key,secret,username=USERNAME,token=TOKEN)
+    for image in get_image_files(IMAGE_PATH):
+
+        if not is_uploaded(image):
+            response = api.upload(path.join(IMAGE_PATH,image),**UPLOAD_DEFAULTS)
+            photo_id = response.find('photoid').text
+            if PHOTOSET_ID:
+                api.photosets_addPhoto(photo_id=photo_id,photoset_id=PHOTOSET_ID)
+            mark_uploaded(image)
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        quit()
     streamer -c "$CAM" -b 32 -o "$PREFIX/$TODAY-$FRIENDLYNAME.jpeg"
 done
 
-python thirdparty/uploadr.py/uploadr/uploadr.py
+#python thirdparty/uploadr.py/uploadr/uploadr.py
+./simpleuploadr.py
 

thirdparty/uploadr.py/.git/HEAD

-ref: refs/heads/master

thirdparty/uploadr.py/.git/config

-[core]
-	repositoryformatversion = 0
-	filemode = true
-	bare = false
-	logallrefupdates = true
-[remote "origin"]
-	fetch = +refs/heads/*:refs/remotes/origin/*
-	url = https://github.com/ept/uploadr.py.git
-[branch "master"]
-	remote = origin
-	merge = refs/heads/master

thirdparty/uploadr.py/.git/description

-Unnamed repository; edit this file 'description' to name the repository.

thirdparty/uploadr.py/.git/hooks/applypatch-msg.sample

-#!/bin/sh
-#
-# An example hook script to check the commit log message taken by
-# applypatch from an e-mail message.
-#
-# The hook should exit with non-zero status after issuing an
-# appropriate message if it wants to stop the commit.  The hook is
-# allowed to edit the commit message file.
-#
-# To enable this hook, rename this file to "applypatch-msg".
-
-. git-sh-setup
-test -x "$GIT_DIR/hooks/commit-msg" &&
-	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
-:

thirdparty/uploadr.py/.git/hooks/commit-msg.sample

-#!/bin/sh
-#
-# An example hook script to check the commit log message.
-# Called by git-commit with one argument, the name of the file
-# that has the commit message.  The hook should exit with non-zero
-# status after issuing an appropriate message if it wants to stop the
-# commit.  The hook is allowed to edit the commit message file.
-#
-# To enable this hook, rename this file to "commit-msg".
-
-# Uncomment the below to add a Signed-off-by line to the message.
-# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
-# hook is more suited to it.
-#
-# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
-# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
-
-# This example catches duplicate Signed-off-by lines.
-
-test "" = "$(grep '^Signed-off-by: ' "$1" |
-	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
-	echo >&2 Duplicate Signed-off-by lines.
-	exit 1
-}

thirdparty/uploadr.py/.git/hooks/post-commit.sample

-#!/bin/sh
-#
-# An example hook script that is called after a successful
-# commit is made.
-#
-# To enable this hook, rename this file to "post-commit".
-
-: Nothing

thirdparty/uploadr.py/.git/hooks/post-receive.sample

-#!/bin/sh
-#
-# An example hook script for the "post-receive" event.
-#
-# The "post-receive" script is run after receive-pack has accepted a pack
-# and the repository has been updated.  It is passed arguments in through
-# stdin in the form
-#  <oldrev> <newrev> <refname>
-# For example:
-#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
-#
-# see contrib/hooks/ for a sample, or uncomment the next line and
-# rename the file to "post-receive".
-
-#. /usr/share/doc/git-core/contrib/hooks/post-receive-email

thirdparty/uploadr.py/.git/hooks/post-update.sample

-#!/bin/sh
-#
-# An example hook script to prepare a packed repository for use over
-# dumb transports.
-#
-# To enable this hook, rename this file to "post-update".
-
-exec git-update-server-info

thirdparty/uploadr.py/.git/hooks/pre-applypatch.sample

-#!/bin/sh
-#
-# An example hook script to verify what is about to be committed
-# by applypatch from an e-mail message.
-#
-# The hook should exit with non-zero status after issuing an
-# appropriate message if it wants to stop the commit.
-#
-# To enable this hook, rename this file to "pre-applypatch".
-
-. git-sh-setup
-test -x "$GIT_DIR/hooks/pre-commit" &&
-	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
-:

thirdparty/uploadr.py/.git/hooks/pre-commit.sample

-#!/bin/sh
-#
-# An example hook script to verify what is about to be committed.
-# Called by git-commit with no arguments.  The hook should
-# exit with non-zero status after issuing an appropriate message if
-# it wants to stop the commit.
-#
-# To enable this hook, rename this file to "pre-commit".
-
-if git-rev-parse --verify HEAD >/dev/null 2>&1
-then
-	against=HEAD
-else
-	# Initial commit: diff against an empty tree object
-	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-fi
-
-# If you want to allow non-ascii filenames set this variable to true.
-allownonascii=$(git config hooks.allownonascii)
-
-# Cross platform projects tend to avoid non-ascii filenames; prevent
-# them from being added to the repository. We exploit the fact that the
-# printable range starts at the space character and ends with tilde.
-if [ "$allownonascii" != "true" ] &&
-	# Note that the use of brackets around a tr range is ok here, (it's
-	# even required, for portability to Solaris 10's /usr/bin/tr), since
-	# the square bracket bytes happen to fall in the designated range.
-	test "$(git diff --cached --name-only --diff-filter=A -z $against |
-	  LC_ALL=C tr -d '[ -~]\0')"
-then
-	echo "Error: Attempt to add a non-ascii file name."
-	echo
-	echo "This can cause problems if you want to work"
-	echo "with people on other platforms."
-	echo
-	echo "To be portable it is advisable to rename the file ..."
-	echo
-	echo "If you know what you are doing you can disable this"
-	echo "check using:"
-	echo
-	echo "  git config hooks.allownonascii true"
-	echo
-	exit 1
-fi
-
-exec git diff-index --check --cached $against --

thirdparty/uploadr.py/.git/hooks/pre-rebase.sample

-#!/bin/sh
-#
-# Copyright (c) 2006, 2008 Junio C Hamano
-#
-# The "pre-rebase" hook is run just before "git-rebase" starts doing
-# its job, and can prevent the command from running by exiting with
-# non-zero status.
-#
-# The hook is called with the following parameters:
-#
-# $1 -- the upstream the series was forked from.
-# $2 -- the branch being rebased (or empty when rebasing the current branch).
-#
-# This sample shows how to prevent topic branches that are already
-# merged to 'next' branch from getting rebased, because allowing it
-# would result in rebasing already published history.
-
-publish=next
-basebranch="$1"
-if test "$#" = 2
-then
-	topic="refs/heads/$2"
-else
-	topic=`git symbolic-ref HEAD` ||
-	exit 0 ;# we do not interrupt rebasing detached HEAD
-fi
-
-case "$topic" in
-refs/heads/??/*)
-	;;
-*)
-	exit 0 ;# we do not interrupt others.
-	;;
-esac
-
-# Now we are dealing with a topic branch being rebased
-# on top of master.  Is it OK to rebase it?
-
-# Does the topic really exist?
-git show-ref -q "$topic" || {
-	echo >&2 "No such branch $topic"
-	exit 1
-}
-
-# Is topic fully merged to master?
-not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
-if test -z "$not_in_master"
-then
-	echo >&2 "$topic is fully merged to master; better remove it."
-	exit 1 ;# we could allow it, but there is no point.
-fi
-
-# Is topic ever merged to next?  If so you should not be rebasing it.
-only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
-only_next_2=`git-rev-list ^master           ${publish} | sort`
-if test "$only_next_1" = "$only_next_2"
-then
-	not_in_topic=`git-rev-list "^$topic" master`
-	if test -z "$not_in_topic"
-	then
-		echo >&2 "$topic is already up-to-date with master"
-		exit 1 ;# we could allow it, but there is no point.
-	else
-		exit 0
-	fi
-else
-	not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
-	perl -e '
-		my $topic = $ARGV[0];
-		my $msg = "* $topic has commits already merged to public branch:\n";
-		my (%not_in_next) = map {
-			/^([0-9a-f]+) /;
-			($1 => 1);
-		} split(/\n/, $ARGV[1]);
-		for my $elem (map {
-				/^([0-9a-f]+) (.*)$/;
-				[$1 => $2];
-			} split(/\n/, $ARGV[2])) {
-			if (!exists $not_in_next{$elem->[0]}) {
-				if ($msg) {
-					print STDERR $msg;
-					undef $msg;
-				}
-				print STDERR " $elem->[1]\n";
-			}
-		}
-	' "$topic" "$not_in_next" "$not_in_master"
-	exit 1
-fi
-
-exit 0
-
-################################################################
-
-This sample hook safeguards topic branches that have been
-published from being rewound.
-
-The workflow assumed here is:
-
- * Once a topic branch forks from "master", "master" is never
-   merged into it again (either directly or indirectly).
-
- * Once a topic branch is fully cooked and merged into "master",
-   it is deleted.  If you need to build on top of it to correct
-   earlier mistakes, a new topic branch is created by forking at
-   the tip of the "master".  This is not strictly necessary, but
-   it makes it easier to keep your history simple.
-
- * Whenever you need to test or publish your changes to topic
-   branches, merge them into "next" branch.
-
-The script, being an example, hardcodes the publish branch name
-to be "next", but it is trivial to make it configurable via
-$GIT_DIR/config mechanism.
-
-With this workflow, you would want to know:
-
-(1) ... if a topic branch has ever been merged to "next".  Young
-    topic branches can have stupid mistakes you would rather
-    clean up before publishing, and things that have not been
-    merged into other branches can be easily rebased without
-    affecting other people.  But once it is published, you would
-    not want to rewind it.
-
-(2) ... if a topic branch has been fully merged to "master".
-    Then you can delete it.  More importantly, you should not
-    build on top of it -- other people may already want to
-    change things related to the topic as patches against your
-    "master", so if you need further changes, it is better to
-    fork the topic (perhaps with the same name) afresh from the
-    tip of "master".
-
-Let's look at this example:
-
-		   o---o---o---o---o---o---o---o---o---o "next"
-		  /       /           /           /
-		 /   a---a---b A     /           /
-		/   /               /           /
-	       /   /   c---c---c---c B         /
-	      /   /   /             \         /
-	     /   /   /   b---b C     \       /
-	    /   /   /   /             \     /
-    ---o---o---o---o---o---o---o---o---o---o---o "master"
-
-
-A, B and C are topic branches.
-
- * A has one fix since it was merged up to "next".
-
- * B has finished.  It has been fully merged up to "master" and "next",
-   and is ready to be deleted.
-
- * C has not merged to "next" at all.
-
-We would want to allow C to be rebased, refuse A, and encourage
-B to be deleted.
-
-To compute (1):
-
-	git-rev-list ^master ^topic next
-	git-rev-list ^master        next
-
-	if these match, topic has not merged in next at all.
-
-To compute (2):
-
-	git-rev-list master..topic
-
-	if this is empty, it is fully merged to "master".

thirdparty/uploadr.py/.git/hooks/prepare-commit-msg.sample

-#!/bin/sh
-#
-# An example hook script to prepare the commit log message.
-# Called by git-commit with the name of the file that has the
-# commit message, followed by the description of the commit
-# message's source.  The hook's purpose is to edit the commit
-# message file.  If the hook fails with a non-zero status,
-# the commit is aborted.
-#
-# To enable this hook, rename this file to "prepare-commit-msg".
-
-# This hook includes three examples.  The first comments out the
-# "Conflicts:" part of a merge commit.
-#
-# The second includes the output of "git diff --name-status -r"
-# into the message, just before the "git status" output.  It is
-# commented because it doesn't cope with --amend or with squashed
-# commits.
-#
-# The third example adds a Signed-off-by line to the message, that can
-# still be edited.  This is rarely a good idea.
-
-case "$2,$3" in
-  merge,)
-    perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
-
-# ,|template,)
-#   perl -i.bak -pe '
-#      print "\n" . `git diff --cached --name-status -r`
-#	 if /^#/ && $first++ == 0' "$1" ;;
-
-  *) ;;
-esac
-
-# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
-# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

thirdparty/uploadr.py/.git/hooks/update.sample

-#!/bin/sh
-#
-# An example hook script to blocks unannotated tags from entering.
-# Called by git-receive-pack with arguments: refname sha1-old sha1-new
-#
-# To enable this hook, rename this file to "update".
-#
-# Config
-# ------
-# hooks.allowunannotated
-#   This boolean sets whether unannotated tags will be allowed into the
-#   repository.  By default they won't be.
-# hooks.allowdeletetag
-#   This boolean sets whether deleting tags will be allowed in the
-#   repository.  By default they won't be.
-# hooks.allowmodifytag
-#   This boolean sets whether a tag may be modified after creation. By default
-#   it won't be.
-# hooks.allowdeletebranch
-#   This boolean sets whether deleting branches will be allowed in the
-#   repository.  By default they won't be.
-# hooks.denycreatebranch
-#   This boolean sets whether remotely creating branches will be denied
-#   in the repository.  By default this is allowed.
-#
-
-# --- Command line
-refname="$1"
-oldrev="$2"
-newrev="$3"
-
-# --- Safety check
-if [ -z "$GIT_DIR" ]; then
-	echo "Don't run this script from the command line." >&2
-	echo " (if you want, you could supply GIT_DIR then run" >&2
-	echo "  $0 <ref> <oldrev> <newrev>)" >&2
-	exit 1
-fi
-
-if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
-	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
-	exit 1
-fi
-
-# --- Config
-allowunannotated=$(git config --bool hooks.allowunannotated)
-allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
-denycreatebranch=$(git config --bool hooks.denycreatebranch)
-allowdeletetag=$(git config --bool hooks.allowdeletetag)
-allowmodifytag=$(git config --bool hooks.allowmodifytag)
-
-# check for no description
-projectdesc=$(sed -e '1q' "$GIT_DIR/description")
-case "$projectdesc" in
-"Unnamed repository"* | "")
-	echo "*** Project description file hasn't been set" >&2
-	exit 1
-	;;
-esac
-
-# --- Check types
-# if $newrev is 0000...0000, it's a commit to delete a ref.
-zero="0000000000000000000000000000000000000000"
-if [ "$newrev" = "$zero" ]; then
-	newrev_type=delete
-else
-	newrev_type=$(git-cat-file -t $newrev)
-fi
-
-case "$refname","$newrev_type" in
-	refs/tags/*,commit)
-		# un-annotated tag
-		short_refname=${refname##refs/tags/}
-		if [ "$allowunannotated" != "true" ]; then
-			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
-			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
-			exit 1
-		fi
-		;;
-	refs/tags/*,delete)
-		# delete tag
-		if [ "$allowdeletetag" != "true" ]; then
-			echo "*** Deleting a tag is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	refs/tags/*,tag)
-		# annotated tag
-		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
-		then
-			echo "*** Tag '$refname' already exists." >&2
-			echo "*** Modifying a tag is not allowed in this repository." >&2
-			exit 1
-		fi
-		;;
-	refs/heads/*,commit)
-		# branch
-		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
-			echo "*** Creating a branch is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	refs/heads/*,delete)
-		# delete branch
-		if [ "$allowdeletebranch" != "true" ]; then
-			echo "*** Deleting a branch is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	refs/remotes/*,commit)
-		# tracking branch
-		;;
-	refs/remotes/*,delete)
-		# delete tracking branch
-		if [ "$allowdeletebranch" != "true" ]; then
-			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	*)
-		# Anything else (is there anything else?)
-		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
-		exit 1
-		;;
-esac
-
-# --- Finished
-exit 0

thirdparty/uploadr.py/.git/index

Binary file removed.

thirdparty/uploadr.py/.git/info/exclude

-# git-ls-files --others --exclude-from=.git/info/exclude
-# Lines that start with '#' are comments.
-# For a project mostly in C, the following would be a good set of
-# exclude patterns (uncomment them if you want to use them):
-# *.[oa]
-# *~

thirdparty/uploadr.py/.git/logs/HEAD

-0000000000000000000000000000000000000000 6242364b49a7c47d4cfd8cfc34db9a50b856ef1a Charles Hooper <chooper@chooper-wind.(none)> 1301023530 -0400	clone: from https://github.com/ept/uploadr.py.git

thirdparty/uploadr.py/.git/logs/refs/heads/master

-0000000000000000000000000000000000000000 6242364b49a7c47d4cfd8cfc34db9a50b856ef1a Charles Hooper <chooper@chooper-wind.(none)> 1301023530 -0400	clone: from https://github.com/ept/uploadr.py.git

thirdparty/uploadr.py/.git/objects/01/3e7e8cb367a57a102c22fa85967f91c3fd7980

Binary file removed.

thirdparty/uploadr.py/.git/objects/14/428bbc83cd9817e45a0fe2d61aa21331273049

Binary file removed.

thirdparty/uploadr.py/.git/objects/1f/3c42d49c2390416090a17318e42ca854467cba

Binary file removed.

thirdparty/uploadr.py/.git/objects/31/9611d602f41e2bb50ff0efc6f337651845fd45

Binary file removed.

thirdparty/uploadr.py/.git/objects/33/dd6cf4d011227bffb01c79eb996b43474766b6

Binary file removed.

thirdparty/uploadr.py/.git/objects/47/33c78e94b78952ae61509d35e9e3eca641c9e9

Binary file removed.

thirdparty/uploadr.py/.git/objects/55/edaf6ee0b7eb33b9315aa0650758f9275a9151

Binary file removed.

thirdparty/uploadr.py/.git/objects/57/1a9352a19882c71850d59e15a37d9bb67f10bf

Binary file removed.

thirdparty/uploadr.py/.git/objects/60/ad50ea47fe73f8f55aa7df38a06187c6214a0c

Binary file removed.

thirdparty/uploadr.py/.git/objects/62/42364b49a7c47d4cfd8cfc34db9a50b856ef1a

Binary file removed.

thirdparty/uploadr.py/.git/objects/62/a782f7c3a0e7e7975d7589e2b215f42821e043

Binary file removed.

thirdparty/uploadr.py/.git/objects/72/ab79e3ca3f23afe02fd513ef29a7a89b5947c3

Binary file removed.

thirdparty/uploadr.py/.git/objects/84/c9f5975074bcad99b8144937d758302b5bf8a1

Binary file removed.

thirdparty/uploadr.py/.git/objects/8a/7e92aa45d980b91a63c7e28f116f44322e4d30

Binary file removed.

thirdparty/uploadr.py/.git/objects/90/383662627b339853bb1f5eab9c4726dc0be19b

-x���JC1�]�)f_(7���X��"E)n\N&�Z0�ᒾ���Y
-�
-��<s봔v��

thirdparty/uploadr.py/.git/objects/93/f356363ac2be2562ffcca8725151bfddd05f05

-x��A
-�0E]���3I�Dܸ�i2�B��4��������y~Kii@�<��

thirdparty/uploadr.py/.git/objects/94/b675afd0cb8890d86ce71f93075057568c690e

Binary file removed.

thirdparty/uploadr.py/.git/objects/9b/37a862dc185a6accceb65f4911f71b1d4635fb

Binary file removed.

thirdparty/uploadr.py/.git/objects/a4/9dc2a6a80af056d6f909d7e025052e19baed2d

Binary file removed.

thirdparty/uploadr.py/.git/objects/a7/123f49eaa0cc9ee7d08ef5d41dcdd3f3ba499a

Binary file removed.

thirdparty/uploadr.py/.git/objects/af/bc6c79c5b24a89ceba082e756a6d3418abfb6f

Binary file removed.

thirdparty/uploadr.py/.git/objects/b2/6304c1086e624fc19254dee7c0282a25835182

Binary file removed.

thirdparty/uploadr.py/.git/objects/c5/34e2fdc5dba7ac9551c35c9279c1fbbf005229

Binary file removed.

thirdparty/uploadr.py/.git/objects/c8/d7b626aacea0d7865a1df6f458c87f16f339ef

-x��K
-1D]��V�|��	����LG�	!����`��W����'���

thirdparty/uploadr.py/.git/objects/d0/d1bb4f7cfe17c2c5e694911926719316e9f7d8

-x��K
-1D]����$"�E�
-m�Qq�	!����`��WPUa���AY�����hfo]`�N:N�}��jFd���8E֢R���"�	��K�t�i��\L�Z�]�J� h�ϵ��Z�,\k�R��̵�5�m���p'�cm�ڠ�=�A������+�����>�X�J�M_�U�

thirdparty/uploadr.py/.git/objects/d3/b8d49867cea1717ef9b9d463e00e23210d5de3

Binary file removed.

thirdparty/uploadr.py/.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391

Binary file removed.

thirdparty/uploadr.py/.git/objects/f9/241354d9ddc31f5e3eb08bbdb14d724af83301

Binary file removed.

thirdparty/uploadr.py/.git/packed-refs

-# pack-refs with: peeled 
-6242364b49a7c47d4cfd8cfc34db9a50b856ef1a refs/remotes/origin/master

thirdparty/uploadr.py/.git/refs/heads/master

-6242364b49a7c47d4cfd8cfc34db9a50b856ef1a

thirdparty/uploadr.py/.git/refs/remotes/origin/HEAD

-ref: refs/remotes/origin/master

thirdparty/uploadr.py/.gitignore

-.loadpath
-.project
-.pydevproject
-.settings
-.DS_Store
-*.pyc

thirdparty/uploadr.py/COPYRIGHT

-The original Uploadr.py is (c) Cameron Mallory, September 2005; license: 
-"You may use this code however you see fit in any form whatsoever."
-
-Includes the xmltramp library, (c) Aaron Swartz, 2003; licensed under the GNU GPL 2.
-
-Further changes made to this program are (c) Martin Kleppmann, 2009; to preserve
-licence compatibility, these and all future contributions are licensed under the
-GNU GPL 2.
-
-This program is free software; you can redistribute it and/or modify it under the
-terms Version 2 of the GNU General Public License as published by the Free Software
-Foundation.
-
-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.

thirdparty/uploadr.py/README.rst

-Uploadr.py
-==========
-
-Uploadr.py is a simple Python script for uploading your photos to Flickr. Unlike
-many GUI applications out there, it lends itself to automation; and because it's
-free and open source, you can just change it if you don't like it.
-
-
-Authentication
---------------
-
-To use this application, you need to obtain your own Flickr API key and secret
-key. You can apply for keys `on the Flickr website
-<http://www.flickr.com/services/api/keys/apply/>`_.
-
-When you have got those keys, you need to set environment variables so that they
-can be used by this application. For example, if you use Bash, add the following
-lines to your ``$HOME/.bash_profile``::
-
-    export FLICKR_UPLOADR_PY_API_KEY=0123456789abcdef0123456789abcdef
-    export FLICKR_UPLOADR_PY_SECRET=0123456789abcdef
-
-
-License
--------
-
-Uploadr.py consists of code by Cameron Mallory, Martin Kleppmann, Aaron Swartz and
-others. See ``COPYRIGHT`` for details.

thirdparty/uploadr.py/uploadr/__init__.py

Empty file removed.

thirdparty/uploadr.py/uploadr/uploadr.py

                     "tags"      : str( FLICKR["tags"] ),
                     "is_public" : str( FLICKR["is_public"] ),
                     "is_friend" : str( FLICKR["is_friend"] ),
-                    "is_family" : str( FLICKR["is_family"] )
+                    "is_family" : str( FLICKR["is_family"] ),
+                    "description" : str( FLICKR["description"] ),
                 }
                 sig = self.signCall( d )
                 d[ api.sig ] = sig

thirdparty/uploadr.py/uploadr/xmltramp.py

-"""xmltramp: Make XML documents easily accessible."""
-
-__version__ = "2.16"
-__author__ = "Aaron Swartz"
-__credits__ = "Many thanks to pjz, bitsko, and DanC."
-__copyright__ = "(C) 2003 Aaron Swartz. GNU GPL 2."
-
-if not hasattr(__builtins__, 'True'): True, False = 1, 0
-def isstr(f): return isinstance(f, type('')) or isinstance(f, type(u''))
-def islst(f): return isinstance(f, type(())) or isinstance(f, type([]))
-
-empty = {'http://www.w3.org/1999/xhtml': ['img', 'br', 'hr', 'meta', 'link', 'base', 'param', 'input', 'col', 'area']}
-
-def quote(x, elt=True):
-	if elt and '<' in x and len(x) > 24 and x.find(']]>') == -1: return "<![CDATA["+x+"]]>"
-	else: x = x.replace('&', '&amp;').replace('<', '&lt;').replace(']]>', ']]&gt;')
-	if not elt: x = x.replace('"', '&quot;')
-	return x
-
-class Element:
-	def __init__(self, name, attrs=None, children=None, prefixes=None):
-		if islst(name) and name[0] == None: name = name[1]
-		if attrs:
-			na = {}
-			for k in attrs.keys():
-				if islst(k) and k[0] == None: na[k[1]] = attrs[k]
-				else: na[k] = attrs[k]
-			attrs = na
-		
-		self._name = name
-		self._attrs = attrs or {}
-		self._dir = children or []
-		
-		prefixes = prefixes or {}
-		self._prefixes = dict(zip(prefixes.values(), prefixes.keys()))
-		
-		if prefixes: self._dNS = prefixes.get(None, None)
-		else: self._dNS = None
-	
-	def __repr__(self, recursive=0, multiline=0, inprefixes=None):
-		def qname(name, inprefixes): 
-			if islst(name):
-				if inprefixes[name[0]] is not None:
-					return inprefixes[name[0]]+':'+name[1]
-				else:
-					return name[1]
-			else:
-				return name
-		
-		def arep(a, inprefixes, addns=1):
-			out = ''
-
-			for p in self._prefixes.keys():
-				if not p in inprefixes.keys():
-					if addns: out += ' xmlns'
-					if addns and self._prefixes[p]: out += ':'+self._prefixes[p]
-					if addns: out += '="'+quote(p, False)+'"'
-					inprefixes[p] = self._prefixes[p]
-			
-			for k in a.keys():
-				out += ' ' + qname(k, inprefixes)+ '="' + quote(a[k], False) + '"'
-			
-			return out
-		
-		inprefixes = inprefixes or {u'http://www.w3.org/XML/1998/namespace':'xml'}
-		
-		# need to call first to set inprefixes:
-		attributes = arep(self._attrs, inprefixes, recursive) 
-		out = '<' + qname(self._name, inprefixes)  + attributes 
-		
-		if not self._dir and (self._name[0] in empty.keys() 
-		  and self._name[1] in empty[self._name[0]]):
-			out += ' />'
-			return out
-		
-		out += '>'
-
-		if recursive:
-			content = 0
-			for x in self._dir: 
-				if isinstance(x, Element): content = 1
-				
-			pad = '\n' + ('\t' * recursive)
-			for x in self._dir:
-				if multiline and content: out +=  pad 
-				if isstr(x): out += quote(x)
-				elif isinstance(x, Element):
-					out += x.__repr__(recursive+1, multiline, inprefixes.copy())
-				else:
-					raise TypeError, "I wasn't expecting "+`x`+"."
-			if multiline and content: out += '\n' + ('\t' * (recursive-1))
-		else:
-			if self._dir: out += '...'
-		
-		out += '</'+qname(self._name, inprefixes)+'>'
-			
-		return out
-	
-	def __unicode__(self):
-		text = ''
-		for x in self._dir:
-			text += unicode(x)
-		return ' '.join(text.split())
-		
-	def __str__(self):
-		return self.__unicode__().encode('utf-8')
-	
-	def __getattr__(self, n):
-		if n[0] == '_': raise AttributeError, "Use foo['"+n+"'] to access the child element."
-		if self._dNS: n = (self._dNS, n)
-		for x in self._dir:
-			if isinstance(x, Element) and x._name == n: return x
-		raise AttributeError, 'No child element named \''+n+"'"
-		
-	def __hasattr__(self, n):
-		for x in self._dir:
-			if isinstance(x, Element) and x._name == n: return True
-		return False
-		
- 	def __setattr__(self, n, v):
-		if n[0] == '_': self.__dict__[n] = v
-		else: self[n] = v
- 
-
-	def __getitem__(self, n):
-		if isinstance(n, type(0)): # d[1] == d._dir[1]
-			return self._dir[n]
-		elif isinstance(n, slice(0).__class__):
-			# numerical slices
-			if isinstance(n.start, type(0)): return self._dir[n.start:n.stop]
-			
-			# d['foo':] == all <foo>s
-			n = n.start
-			if self._dNS and not islst(n): n = (self._dNS, n)
-			out = []
-			for x in self._dir:
-				if isinstance(x, Element) and x._name == n: out.append(x) 
-			return out
-		else: # d['foo'] == first <foo>
-			if self._dNS and not islst(n): n = (self._dNS, n)
-			for x in self._dir:
-				if isinstance(x, Element) and x._name == n: return x
-			raise KeyError
-	
-	def __setitem__(self, n, v):
-		if isinstance(n, type(0)): # d[1]
-			self._dir[n] = v
-		elif isinstance(n, slice(0).__class__):
-			# d['foo':] adds a new foo
-			n = n.start
-			if self._dNS and not islst(n): n = (self._dNS, n)
-
-			nv = Element(n)
-			self._dir.append(nv)
-			
-		else: # d["foo"] replaces first <foo> and dels rest
-			if self._dNS and not islst(n): n = (self._dNS, n)
-
-			nv = Element(n); nv._dir.append(v)
-			replaced = False
-
-			todel = []
-			for i in range(len(self)):
-				if self[i]._name == n:
-					if replaced:
-						todel.append(i)
-					else:
-						self[i] = nv
-						replaced = True
-			if not replaced: self._dir.append(nv)
-			for i in todel: del self[i]
-
-	def __delitem__(self, n):
-		if isinstance(n, type(0)): del self._dir[n]
-		elif isinstance(n, slice(0).__class__):
-			# delete all <foo>s
-			n = n.start
-			if self._dNS and not islst(n): n = (self._dNS, n)
-			
-			for i in range(len(self)):
-				if self[i]._name == n: del self[i]
-		else:
-			# delete first foo
-			for i in range(len(self)):
-				if self[i]._name == n: del self[i]
-				break
-	
-	def __call__(self, *_pos, **_set): 
-		if _set:
-			for k in _set.keys(): self._attrs[k] = _set[k]
-		if len(_pos) > 1:
-			for i in range(0, len(_pos), 2):
-				self._attrs[_pos[i]] = _pos[i+1]
-		if len(_pos) == 1 is not None:
-			return self._attrs[_pos[0]]
-		if len(_pos) == 0:
-			return self._attrs
-
-	def __len__(self): return len(self._dir)
-
-class Namespace:
-	def __init__(self, uri): self.__uri = uri
-	def __getattr__(self, n): return (self.__uri, n)
-	def __getitem__(self, n): return (self.__uri, n)
-
-from xml.sax.handler import EntityResolver, DTDHandler, ContentHandler, ErrorHandler
-
-class Seeder(EntityResolver, DTDHandler, ContentHandler, ErrorHandler):
-	def __init__(self):
-		self.stack = []
-		self.ch = ''
-		self.prefixes = {}
-		ContentHandler.__init__(self)
-		
-	def startPrefixMapping(self, prefix, uri):
-		if not self.prefixes.has_key(prefix): self.prefixes[prefix] = []
-		self.prefixes[prefix].append(uri)
-	def endPrefixMapping(self, prefix):
-		self.prefixes[prefix].pop()
-	
-	def startElementNS(self, name, qname, attrs):
-		ch = self.ch; self.ch = ''	
-		if ch and not ch.isspace(): self.stack[-1]._dir.append(ch)
-
-		attrs = dict(attrs)
-		newprefixes = {}
-		for k in self.prefixes.keys(): newprefixes[k] = self.prefixes[k][-1]
-		
-		self.stack.append(Element(name, attrs, prefixes=newprefixes.copy()))
-	
-	def characters(self, ch):
-		self.ch += ch
-	
-	def endElementNS(self, name, qname):
-		ch = self.ch; self.ch = ''
-		if ch and not ch.isspace(): self.stack[-1]._dir.append(ch)
-	
-		element = self.stack.pop()
-		if self.stack:
-			self.stack[-1]._dir.append(element)
-		else:
-			self.result = element
-
-from xml.sax import make_parser
-from xml.sax.handler import feature_namespaces
-
-def seed(fileobj):
-	seeder = Seeder()
-	parser = make_parser()
-	parser.setFeature(feature_namespaces, 1)
-	parser.setContentHandler(seeder)
-	parser.parse(fileobj)
-	return seeder.result
-
-def parse(text):
-	from StringIO import StringIO
-	return seed(StringIO(text))
-
-def load(url): 
-	import urllib
-	return seed(urllib.urlopen(url))
-
-def unittest():
-	parse('<doc>a<baz>f<b>o</b>ob<b>a</b>r</baz>a</doc>').__repr__(1,1) == \
-	  '<doc>\n\ta<baz>\n\t\tf<b>o</b>ob<b>a</b>r\n\t</baz>a\n</doc>'
-	
-	assert str(parse("<doc />")) == ""
-	assert str(parse("<doc>I <b>love</b> you.</doc>")) == "I love you."
-	assert parse("<doc>\nmom\nwow\n</doc>")[0].strip() == "mom\nwow"
-	assert str(parse('<bing>  <bang> <bong>center</bong> </bang>  </bing>')) == "center"
-	assert str(parse('<doc>\xcf\x80</doc>')) == '\xcf\x80'
-	
-	d = Element('foo', attrs={'foo':'bar'}, children=['hit with a', Element('bar'), Element('bar')])
-	
-	try: 
-		d._doesnotexist
-		raise "ExpectedError", "but found success. Damn."
-	except AttributeError: pass
-	assert d.bar._name == 'bar'
-	try:
-		d.doesnotexist
-		raise "ExpectedError", "but found success. Damn."
-	except AttributeError: pass
-	
-	assert hasattr(d, 'bar') == True
-	
-	assert d('foo') == 'bar'
-	d(silly='yes')
-	assert d('silly') == 'yes'
-	assert d() == d._attrs
-	
-	assert d[0] == 'hit with a'
-	d[0] = 'ice cream'
-	assert d[0] == 'ice cream'
-	del d[0]
-	assert d[0]._name == "bar"
-	assert len(d[:]) == len(d._dir)
-	assert len(d[1:]) == len(d._dir) - 1
-	assert len(d['bar':]) == 2
-	d['bar':] = 'baz'
-	assert len(d['bar':]) == 3
-	assert d['bar']._name == 'bar'
-	
-	d = Element('foo')
-	
-	doc = Namespace("http://example.org/bar")
-	bbc = Namespace("http://example.org/bbc")
-	dc = Namespace("http://purl.org/dc/elements/1.1/")
-	d = parse("""<doc version="2.7182818284590451"
-	  xmlns="http://example.org/bar" 
-	  xmlns:dc="http://purl.org/dc/elements/1.1/"
-	  xmlns:bbc="http://example.org/bbc">
-		<author>John Polk and John Palfrey</author>
-		<dc:creator>John Polk</dc:creator>
-		<dc:creator>John Palfrey</dc:creator>
-		<bbc:show bbc:station="4">Buffy</bbc:show>
-	</doc>""")
-
-	assert repr(d) == '<doc version="2.7182818284590451">...</doc>'
-	assert d.__repr__(1) == '<doc xmlns:bbc="http://example.org/bbc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://example.org/bar" version="2.7182818284590451"><author>John Polk and John Palfrey</author><dc:creator>John Polk</dc:creator><dc:creator>John Palfrey</dc:creator><bbc:show bbc:station="4">Buffy</bbc:show></doc>'
-	assert d.__repr__(1,1) == '<doc xmlns:bbc="http://example.org/bbc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://example.org/bar" version="2.7182818284590451">\n\t<author>John Polk and John Palfrey</author>\n\t<dc:creator>John Polk</dc:creator>\n\t<dc:creator>John Palfrey</dc:creator>\n\t<bbc:show bbc:station="4">Buffy</bbc:show>\n</doc>'
-
-	assert repr(parse("<doc xml:lang='en' />")) == '<doc xml:lang="en"></doc>'
-
-	assert str(d.author) == str(d['author']) == "John Polk and John Palfrey"
-	assert d.author._name == doc.author
-	assert str(d[dc.creator]) == "John Polk"
-	assert d[dc.creator]._name == dc.creator
-	assert str(d[dc.creator:][1]) == "John Palfrey"
-	d[dc.creator] = "Me!!!"
-	assert str(d[dc.creator]) == "Me!!!"
-	assert len(d[dc.creator:]) == 1
-	d[dc.creator:] = "You!!!"
-	assert len(d[dc.creator:]) == 2
-	
-	assert d[bbc.show](bbc.station) == "4"
-	d[bbc.show](bbc.station, "5")
-	assert d[bbc.show](bbc.station) == "5"
-
-	e = Element('e')
-	e.c = '<img src="foo">'
-	assert e.__repr__(1) == '<e><c>&lt;img src="foo"></c></e>'
-	e.c = '2 > 4'
-	assert e.__repr__(1) == '<e><c>2 > 4</c></e>'
-	e.c = 'CDATA sections are <em>closed</em> with ]]>.'
-	assert e.__repr__(1) == '<e><c>CDATA sections are &lt;em>closed&lt;/em> with ]]&gt;.</c></e>'
-	e.c = parse('<div xmlns="http://www.w3.org/1999/xhtml">i<br /><span></span>love<br />you</div>')
-	assert e.__repr__(1) == '<e><c><div xmlns="http://www.w3.org/1999/xhtml">i<br /><span></span>love<br />you</div></c></e>'	
-	
-	e = Element('e')
-	e('c', 'that "sucks"')
-	assert e.__repr__(1) == '<e c="that &quot;sucks&quot;"></e>'
-
-	
-	assert quote("]]>") == "]]&gt;"
-	assert quote('< dkdkdsd dkd sksdksdfsd fsdfdsf]]> kfdfkg >') == '&lt; dkdkdsd dkd sksdksdfsd fsdfdsf]]&gt; kfdfkg >'
-	
-	assert parse('<x a="&lt;"></x>').__repr__(1) == '<x a="&lt;"></x>'
-	assert parse('<a xmlns="http://a"><b xmlns="http://b"/></a>').__repr__(1) == '<a xmlns="http://a"><b xmlns="http://b"></b></a>'
-	
-if __name__ == '__main__': unittest()