Archive for the ‘scripting’ tag
Quick directory switching
At work, I do a lot of directory traversal: going from one location to another within the whole (global) filesystem structure. So, to conveniently go back to a previous directory, I use pushd and popd, aside from the usual cd:
$ pwd /home/iandexter $ pushd /etc/sysconfig $ pwd /etc/sysconfig $ popd $ pwd /home/iandexter
You can even echo $DIRSTACK to list the current directories in the stack, and push multiple directories.
Downloading Flickr photos, part 2
I made several improvements in the previous script:
#!/usr/bin/python import flickr import urllib import time import re flickr.API_KEY = 'Flick API goes here' print "Registered using API key" user = flickr.people_findByUsername(u'username') print "Found user %s - username" % user.id try: photos = flickr.people_getPublicPhotos(user.id, 500) print "Found the photos" total = 0 for photo in photos: p = flickr.Photo(photo.id) title = re.sub('\s+', '-', p.title) title = re.sub('[^-\w]', '', title) title = "%s_%s" % (title, p.datetaken.split()[0]) for s in p.getSizes(): url = s['source'] photoFile = "%s_%s" % (title, url.split("/")[4]) data = urllib.urlretrieve(url, photoFile) total = total + 1 print "Retrieving %s ..." % photoFile time.sleep(1) except AttributeError: exit print "%s photos retrieved." % total
Python is pretty simple, once you get the hang of it. It also helps that the source for flickr.py is open — I got to fetch some more info regarding the photos I’m downloading, thus incorporating them in the code.
The code could use some more improvement, though: I should have opted for the Flickr error code (flickr.FlickrError) instead of AttributeError. The regex can certainly use more trimming. Perhaps I can save the photo information in a database instead of glomming them in the filename (so I can include tags, group and set memberships, etc.),
This should be elementary to Python devs out there, but for me, it’s just a hobby. ![]()
Downloading Flickr photos
Flickr Leech is a cool web app. It displays all Flickr photos, including those already rendered invisible because of the 200-photo limit in free accounts. But I need more: I want to download these photos for backup.
After looking around, I found several tools that does the job. They didn’t quite work for me, so I decided to hack my own.
Using the Flickr API and a Python wrapper, I came up with the following:
- Get flickr.py and manually add it to the host Python library.
- Get an API key from Flickr.
- Write the script:
#!/usr/bin/python import flickr import urllib flickr.API_KEY = 'API key goes here' user = flickr.people_findByUsername(u'username') photos = flickr.people_getPublicPhotos(user.id, 500) total = 0 for photo in photos: photoURL = "http://static.flickr.com/%s/%s_%s_o.jpg" % (photo.server, photo.id, photo.secret) photoFile = "%s_%s.jpg" % (photo.title, photo.id) data = urllib.urlretrieve(photoURL, photoFile) total = total + 1 print "Downloading %s" % photoFile print "Done with %s photos." % total
- Make the script executable, create a directory where to download files, and execute the script from there.
- Rinse, dry, press.
I know, the script is very rudimentary. It’s my first Python script, and it needs a lot of work: there’s no exception-handling for one. But it worked perfectly for me.
Snag movie audio tracks
Okay, watching movies in the workplace is a definite no-no, but they didn’t say anything about listening to movies. But I’d rather do it offline, so I whipped up a little bookmarklet that will snag the .MP3 URL off the movies I chose.
- First off, select a movie from the list.
- Then list all the URLs in that page by using Javascript’s
document.linksobject. - I noticed that the URI for the MP3 link is always the ninth, so just get the ninth URL:
document.links[8].href. - Using a regular expression, winnow the URL:
document.links[8].href.replace(new RegExp('[?&=]','g'),' ').split(' ')[2] - Drop in the
javascriptresource header, and voila! here’s the bookmarklet that will grab audio track’s URL for download. Right-click and bookmark the link. Or, drag and drop the link to the bookmarks toolbar.
SMTP testing automation
I know there are scripts out there that does full-blown SMTP testing. I’ve used smtp-sink and smtp-source in Postfix for this purpose:
$ smtp-source -s 100 -m 100 -f sender@domain.com -t recipient@domain.com server.address:25
So this was what I recommended to a friend, a Unix engineer in Singapore. But she had a different requirement: she has to establish an SMTP connection through telnet to a remote server, and send a template mail to thousands of recipients. The telnet session goes something like:
[user@host ~]$ telnet remote.host 25 Trying 123.456.789.10... Connected to remotehost.remotedomain (123.456.789.10). Escape character is '^]'. 220 mail.remote.host ESMTP Postfix EHLO some.domain 250-mail.remote.host 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250 8BITMIME MAIL FROM:sender@this.domain 250 Ok RCPT TO:recipient@another.domain 250 Ok DATA 354 End data with<cr><lf>.<cr><lf> Subject: This is a test From: Sender This is only a test. . 250 Ok: queued as D81D7FA927 QUIT 221 Bye Connection closed by foreign host. [user@host ~]$</lf></cr></lf></cr>
With thousands of recipients (no, her employer is not a spammer), this can be quite tedious. I thought of using an alias file at first, but the requirement was SMTP through telnet. So I told her to do the following:
- Create a recipients file,
/tmp/recipients:recipient1@some.domain recipient2@another.domain ... recipientX@yet.another.domain
- Create a message file,
/tmp/message:Subject: This is a test From: Sender This is only a test. - Create a script,
smtp-telnet.sh:#!/bin/bash SENDER=sender@this.domain (echo "HELO some.domain"; sleep 1; echo "MAIL FROM:" $SENDER; sleep 1; for i in `cat /tmp/recipients`; do echo "RCPT TO:" $i; sleep 1; done; echo "DATA"; sleep 1; cat /tmp/message; sleep 1; echo "."; sleep 1; echo "QUIT") | telnet remote.host 25
- Do a
chmod 744 smtp-telnet.shand run the script:$ ./smtp-telnet.sh
The sleep parameter can be increased to compensate for delays. I tested it on 50 users in my local test environment, and it worked for me.
