Managing a tumblr posts-queue locally with #Tags

A year ago, I posted a quite confused/ing article regarding a script useful to post a picture per day on a Tumblr. This article went outdated fast enough since Tumblr changed their (poorly documented) API.

David Moreno “Damog”, author of WWW::Tumblr, updated his trunk so it properly supports the new API. So here’s my updated version of my post-image-to-tumblr script.

To use it, you first need to do some black magic with this init-auth script. Update August 12th, this is fixed and no longer necessary: And when it’s done, it’s still not ready, because so far I’m not able to use the data[0] field as described in the API doc (hints welcome). So there is need to add some config snippet to be able to first upload the relevant image to a third party server with scp and then use the source field (URI) instead of the fakakte data field.

The configuration ~/.tumblrrc should look as:

base_url =

consumer_key = alongstringalongstringalongstringalongstring
consumer_secret = alongstringalongstringalongstringalongstring
token = alongstringalongstringalongstringalongstring
token_secret = alongstringalongstringalongstringalongstring

# would be necessary only if getting error 400 when posting
#workaround_login = user@server
#workaround_dir = /var/www/tempdir
#workaround_url = http://server/tempdir

The script expects you to have a git repository ~/tmp/tumblr containing two subdirectories: queue and over, queue containing your image queue. You can override this path with the parameter content=

If an image have metadata with a Description field (XMP) containing a comma separated list of #Tags, #Another Tag, it will be posted with Tumblr tags (ignoring strings not starting with #).

In my case, as shorcut, I added a Makefile in ~/tmp/tumblr that contains:

SHELL := /bin/bash 

	git pull
	git add over queue
	-git commit -am "Updated by a bunch of anonymous unanimous hamsters"
	git push
	make count

	@in_queue=`ls -1 queue/ | wc -l` && echo "$$in_queue file(s) in the queue total,"
	@in_queue=`ls -1 queue/ | wc -l` && in_queue=`echo $$in_queue - 5 | bc` && echo "so $$in_queue file(s) that can actually be posted,"
	@in_queue=`ls -1 queue/ | wc -l` && in_queue=`echo $$in_queue - 5 | bc` && if [ $$in_queue -gt 0 ]; then echo "enough until: "`date --date "$$in_queue days"`; else echo "not enough at all."; fi
	@cd queue && limit="9M" && if ((`find  . -size +$$limit | wc -l` > 0)); then echo "" && echo `find  . -size +$$limit | wc -l`" file(s) of size > $$limit :" && find  . -size +$$limit ; fi 

	@cd queue && limit="1M" && echo `find  . -size +$$limit -name "*.gif"| wc -l`" file(s) with size > $$limit :" && find  . -size +$$limit  -name "*.gif" && find  . -size +$$limit -name "*.gif" -print0 | xargs -0 -I file convert file file.miff
	@cd queue && for i in *.miff; do newsize="100000" && for run in `seq 1 25`; do if [ ! -e "$$i.gif" ] || [ `stat -c %s "$$i.gif"` -gt 1000000 ]; then echo "$$i.gif too big (`stat -c %s $$i.gif`, run $$run, newsize $$newsize)" && convert -colors 128 +dither -layers optimize  -resize $$newsize@ $$i $$i.gif && newsize=`expr $$newsize - 4500` ;  fi ; done ;  done
	@cd queue && for i in *.miff; do newsize="100000" && if [ ! -e "$$i.gif" ] || [ `stat -c %s "$$i.gif"` -le 1000000 ]; then echo "$$i.gif is fine, removing the miff" && rm -f $$i; fi; done
	cd queue && for i in *; do let cut_start=$${#i}-19 cut_end=$${#i}-4 && if (($$cut_start < 1)); then cut_start=1; fi && mv $$i `mktemp --dry-run --tmpdir=. -t XXXXXXX`-`basename $$i $${i%%.*} | cut -c $$cut_start-$$cut_end`.`echo $${i##*.} | tr A-Z a-z`; done 

 	cd queue && count=0 && for i in *; do count=`expr $$count + 1` && case $$count in [0-5]) prefix=A;; [6-9]) prefix=C;; 1[0-5]) prefix=E;; 1[5-9]) prefix=G;; 2[0-9]) prefix=I;; 3[0-9]) prefix=K;; 4[0-9]) prefix=M;; 5[0-9]) prefix=O;; *) prefix=Q;; esac && mv $$i $$prefix`echo $$i | tr A-Z a-z`; done

 	git log --stat -n100 --pretty=format:"%s of %ad" > ChangeLog

For the record, last year I posted an RFP, if you are a DD, I could probably offer you a beer to work on it. 🙂

Managing a tumblr posts-queue locally

For a change, today I won’t describe how I did something but how I did not.

I had I mind to use tumblr with a daily automated post of a picture. I devised it would be nice if a daily cronjob on my local server was updating a git directory and then post the first image in the queue.

First, I found out that tumblr refuses to handle mail sent directly by mutt and the local server smtp. So I then tried having mutt sending the mail using gmail authenticated smtp. I did not work either. But it works fine to any other recipient. And it works if directly sent with gmail web interface. We’ve made it incredibly easy to post from your desktop or mobile phone. Just send an email to the custom email address for the blog you’d like to publish to they claimed. Go figure, that probably something they implied by the confusing sentence Send posts directly to your mobile posting email address. You cannot email another email address and then forward the email from there. I understand spam is an issue they have to care about, but how comes that even gmail authentication isn’t proof enough of goodwill?

Anyway I ended up with a non working script for the simple task of sending a mail.

Update, May 21st:

Today, as the queue mecanism of the website was broken, I googled around and found the perl module WWW::Tumblr wrote by David Moreno Damog using the Tumblr API (which I was reluctant to use at first, because it’s unclear how stable such API can stay over time) and wrote another script using this module that works like a charm. It requires a ~/.tumblrrc file (defining email= and password=) and a git-managed directory with subdirs queue/ and over/.

I posted a RFP WWW::Tumblr on Debian.

It upload files in alphabetical order. But you can always run something like the following to randomize it:

cd queue && for i in *; do let cut_start=${#i}-19 cut_end=${#i}-4 && if (($cut_start < 1)); then cut_start=1; fi && mv $i `mktemp --dry-run --tmpdir=. -t XXXXXXX`-`basename $i ${i%%.*} | cut -c $cut_start-$cut_end`.`echo ${i##*.} | tr A-Z a-z`; done