iPhone and Linux

Tuesday, October 27, 2009

Run a script from a Prowl notification

Prowl allows it's notifications to be opened in any app using Apple's custom url scheme. Here's how you can have a Prowl notification run a shell script.

What you need on your phone:
It has to be Jailbroken
Prowl
any BASH shell script that you want to run
curl on the phone: optional - only needed if you want output from the script sent through Prowl.

You're not going to be editing any system files or doing anything dangerous.

First, use my last post to create a fake app which will allow you to run your script by tapping an icon on SpringBoard.

Now, for my example, I will name my script "Test" (not Test.sh. It runs fine without the file extension and I'm not sure it would work later on if it has an extension)

Open your script's Info.plist and right above the "dict" closing tag, add these lines:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Test URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>rss</string>
</array>
</dict>
</array>


So your finished plist should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Test.sh</string>
<key>CFBundleIdentifier</key>
<string>com.myname.Test</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Test</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Test URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>rss</string>
</array>
</dict>
</array>
</dict>
</plist>
Edit "Test URL" and "rss." Change "Test" to the name of your script and rss to any app in Prowl's Redirections.plist.

Open Prowl's Redirections.plist and find rss, or whatever app you are using, and edit the lines below Key and URL to the name of your script:
   <key>Key</key>
<string>Test</string>
<key>URL</key>
<string>Test://</string>
Open Prowl and create a custom redirection by putting in an application name and selecting rss. I'll use "shoe" as an example application name

Using curl on my computer
curl -k https://prowl.weks.net/publicapi/add -F apikey=XXXX -F application="shoe" -F description="click view to run the Test script"

Send that notification with curl, click "view" when it pops up and it will run your script. Of course, there is no output unless you have a method of sending output in the script. Putting this in the script would send you another Prowl notification that the script was ran: curl -k https://prowl.weks.net/publicapi/add -F apikey=XXXX -F application="Test" -F description="the Test script was ran" Or put the output of the script into a variable and use description="$variable"

So what are the uses? Heck if I know. Maybe endless, maybe useless.

Sunday, October 25, 2009

Launching scripts from a SpringBoard icon

MobileTerminal is an app that no geek can live without, but it can be a bit of a pain to open, run a command, then close. It can be much nicer if you can create an icon on your SpringBoard which will run your script when tapped.

All you need to do is create a folder named whatever.app in /Applications. These are the files you need to put inside that folder:

An icon named icon.png
A 320x460 background image named Default.png
A plist file which can be copied from another app (or use the one below)
Your bash shell script
A text file named PkgInfo which only contains these 8 characters: APPL????

Edit the plist to point to that script, give it a unique identifier and custom name and voila!, you will have an icon on your springboard which will run your script when tapped.

Here is an example plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>vuze.sh</string>
<key>CFBundleIdentifier</key>
<string>com.myname.myscript</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>myscript</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>


The strings you will need to change are:
CFBundleExecutable - change this to the name of your script
CFBundleIdentifier - this has to be unique for every app/script and in the "reverse DNS" form of "com.apple.mail" It doesn't matter what you enter, as long as it is unique to that app and in that form.
CFBundleName - this is the name that will appear on the SpringBoard.

If you noticed, the script I was using is called vuze.sh. Vuze is the torrent client I use on my home PC. Using the HTML WebUI Plugin and iZUreus, you can control it from a webpage formatted for your iPhone.

You can view it on your local network using the network IP address or remotely using the true IP address. The logical thing to do would be to create a bookmark in Safari to connect to Vuze any time you want, but what if your IP address changes?

I've already talked about monitoring your computer for IP changes with a script but let's rehash it. Run a script like this on your computer:

#! /bin/sh
date > date
ip=$(lynx -dump checkip.dyndns.org | awk '{ print $4 }' | tr -d "\n")
if
cat ip | grep $ip
then echo "IP hasn't changed. Not sending notification"
# add your notification method here
else
echo "Sending IP change notification"
# add your notification method here
fi
echo $ip > ip

and any time your home IP changes, the new IP will be sent to your iPhone. I send it via Prowl, but you can use SMS, email or whatever. my IP changes about once a month. Any time I get the notification, I put the new IP in a text file in my home directory so I will always have it and can call it from scripts.

The Vuze script is pretty simple. It gets the IP address from that file and uses the openURL utility from Erica Utilities (available in Cydia) to open Safari to the Vuze control page that is running on my home computer.

#! /bin/sh
ip=$(cat /var/mobile/homeip)
openURL http://$ip:6886

The end result is that I can connect anywhere to the Vuze client by tapping an icon on SpringBoard.

Send MobileTerminal output to Prowl

One of the downsides to MobileTerminal is that it doesn't support copy and paste. You can direct the output to a file and open it later to copy the contents if needed, but I worked out a solution that I like better; pipe the output to Prowl.

The output is sent over the internet to the Prowl notification service which then sends it to your phone in the form of a push notification. It's a strange way of getting the output, but it's sure handy.

All you need to do is get the output into a variable, then use curl to post it to the Prowl API. The best way to do capture the input from a pipe is with "< /dev/stdin", which works on my computer but does not work on the phone, so I had to use "cat -"

I named the script "i", so whenever I want to use it, I just add "| i" on the command line and the output goes to Prowl, e.g: echo "Hello World" | i

#! /bin/sh
out=$(cat -)
curl -k https://prowl.weks.net/publicapi/add -d apikey=XXXXX -d application="pipe" -d description="$out"

Monday, October 19, 2009

Custom iPhone icons on the fly

What do you do if you want a new icon for an app but are away from your computer? Here's what I do:

Open Safari and do a google image search for whatever subject the icon is on. Find an image, click it full size, zoom in or out so it fills about 80% of the screen and create a webclip. The icon for that webclip will soon become the icon we want.

In the webclip preview, check that the icon is centered. Cancel, re-center and re-create if necessary. Once the webclip is created, go to /var/mobile/Library/Webclips and find the folder for it and copy the icon to the application directory where you want to use it. Now delete the webclip.

You've just created a new icon using nothing but the iPhone.

Sunday, October 18, 2009

Growing your iMob mob the lazy way

If you play iMob Online and want more people in your mob, you can go to imob-friendcodes.com and put in your iMob code so people can add you. You can do this once per hour, but who has the time?

This script adds your code every 65 minutes, just replace my iMob code with 165662468 (don't forget to add me). You could edit out the "while true do sleep done" loop and set is as an hourly cronjob, but the odds are high that you will submit the info and imob-friendcodes.com will tell you to come back later because it's only been 59 minutes and 59 seconds since your last submission.

I don't play them, but I've tested it with all 6 games from the Godfather developer.

#! /bin/sh
while `true`
do
function postcode
{
curl -d "friend_code=165662468&on0=Friend Code&postback=1" $1
sleep 5s
}
postcode http://imob-friendcodes.com/
postcode http://iknightcode.com/
postcode http://jetfightersfriendcodes.com/
postcode http://ivampirescode.com/
postcode http://girlwarcodes.com/
postcode http://raceordie-codes.com/
sleep 65m
done

Friday, October 16, 2009

My iPhone app purchases

I bought my iPhone in Feb 2009. I saved all emails from iTunes and got bored and wrote a script to extract the information on my purchases. Here is a breakdown

I've downloaded 316 apps (I currently have 21 apps on my phone. I once had 9 pages of apps, but realized I never used them, now I only keep what I use often.)

I've spent $25. I'm not cheap or broke, I just don't buy things I know I don't need. I'm also not into games and have only bought a couple.

Out of the apps I paid for, 2 were actually mistakes. One was a game which I was going to try but accidentally got the full version, and another was a book I thought was free.

I've only continued to use 4 apps regularly after purchase. Two I could live without. Two, Prowl and RSSPlayer, I couldn't live without and they were also the most expensive at $2.99.

Thursday, October 8, 2009

iPhone command line podacatcher

I've been using RSSPlayer to download and listen to podcasts on my iPhone, but it's started to get buggy and misses a lot of new podcast episodes.

I started looking for a simple Linux podcatcher just to check the feeds and tell if there are any new episodes. I stumbled across BashPodder, which is an excellent command line podcatcher, but it downloaded all the episodes and I only wanted to get a list of what was available.

I started looking at the code and realized it was extracting links with xsltproc. I'd never heard of that so checked into it. Basically, it takes an xsl stylesheet and filters things though it. BashPodder uses a file named parse_enclosure.xsl which is available on their website.

I realized I could use that to write a simple shell script to use on the iPhone to notify myself of new podcasts available. Then I realized I could use it to just download the podcasts instead of simply notifying me of them. The podcasts can then be listened to with iFile (from Cydia). All you need on the phone is MobileTerminal, awk, wget (any hacker should already have those), libxslt (I couldn't find it in Cydia but found it here), this script and parse_enclosure.xsl from the BashPodder project.
#! /bin/sh

# This requires the parse_enclosure.xsl file from bashpodder

function fetch {
echo "Checking $2"
wget -q -O .$2 $1
cat .$2 | xsltproc ./parse_enclosure.xsl - > .$2b
if
diff .$2b .$2a | grep \< > /dev/null
then
echo "$2" >> new
diff .$2b .$2a | awk '{ print $2 }' | sed /^$/d >> new
echo >> new
fi
mv .$2b .$2a
rm .$2
}
# Was that enough 2's for you? Sorry, that's
# the downside to using function variables.


# Add your podcast links below and remove the #
# The format must be "fetch link nickname"
# fetch is the name of the function, it will only
# run the function on lines beginning with the word fetch
# The nickname is whatever one-word nickname you want to
# give a podcast. Don't use special characters.
#################FEEDLIST###################
#fetch http://www.site1.com/feed.xml nickname
#fetch http://www.site2.com/feed.xml nickname2
# ...etc
###########################################


if
ls | grep new
then

# If you only want to be
# notified of new podcasts
# and not download them,
# change this line to:
# cat new

cat new | grep http > get; wget -i get; rm get

rm new
else
echo "Sorry, no nothing new"
fi

Blog Archive