Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
Status
Not open for further replies.
Hello all,

Thanks for all your wicked scripts in this thread.
I just wanted to share my scripts. I've added some exchange rates to my desktop using Geektool 3. Might help someone out there.

These are for Indian Rupees, but you can easily change it to the currency you need.

HTML:
curl --silent http://www.google.com/finance?q=USDINR | grep "span" | sed -e :a -e 's/<[^>]*>//g;//ba' | head -8 | tail -n 5 | sed '/^$/d' | sed -e '$!N;s/\n/ /' -e '$!N;s/\n/ /';
curl --silent http://www.google.com/finance?q=GBPINR | grep "span" | sed -e :a -e 's/<[^>]*>//g;//ba' | head -8 | tail -n 5 | sed '/^$/d' | sed -e '$!N;s/\n/ /' -e '$!N;s/\n/ /';
curl --silent http://www.google.com/finance?q=EURINR | grep "span" | sed -e :a -e 's/<[^>]*>//g;//ba' | head -8 | tail -n 5 | sed '/^$/d' | sed -e '$!N;s/\n/ /' -e '$!N;s/\n/ /';

@pitt1717 - replace USDINR in the code to MUTF:FAMRX, that should do the trick.

These are great scripts. I have modified them to return the exchange rate for Pounds Sterling.

One question: does anyone (@Cyrusyrus?) know how to strip out the text so that instead of getting:

1 GBP = 1.1541 EUR +0.00807

I can just get:

1.15

Many thanks.
 
Anyone know of a geeklet then you can press and it opens up an alias

EG I want a button that opens up System preferences or a button that opens up my HD.
 
Last edited:
I found an alternative to this on another blog since no one here seems willing to help out. Its exactly what I was looking for, although doesn't use yahoo weather.

http://blog.raymangum.com/?p=43
glad you found something that worked, ill use it! :D
only works on US cities... damn you guys!!! :mad:

Anyone know of a geeklet then you can press and it opens up an alias

EG I want a button that opens up System preferences or a button that opens up my HD.
you cant do that. but I use BetterTouchTool to launch quickly programs/scripts, with the touchpad and keys. really useful!

These are great scripts. I have modified them to return the exchange rate for Pounds Sterling.

One question: does anyone (@Cyrusyrus?) know how to strip out the text so that instead of getting:

1 GBP = 1.1541 EUR +0.00807

I can just get:

1.15

Many thanks.
got to show "1 USD = 45.2250 INR" and im pretty sure thats the best you can do with this script. just change "head -5" and "tail -n 2"

try using the script shown here. you can figure out by yourself how to change the script a bit to have what you want. have fun!
 
Last edited:
Ok so I've been doing some thinking.

I realized that something blatantly amiss from geektools is a visual-aid "bar" for things like capacity and usage, not for functionality but for pure beauty for those who like it. For example, instead of merely saying you've used 700/1024 GB on your HDD, it would also display a white bar filled up with black up to the percentage corresponding to 700/1024. Same would apply to cpu usage ( although you basically have Activity Monitor right there for that ) and other things one might find it fits.

Being that I'm no programmer I just had this on my mind for a while and no way to do this. Then it hit me that the calendar our dear mate brenm666 provided has the following piece of code:


def build_separator(year, month)
color = "\e[30m" #black
#color = "\e[37m" #uncomment for white
separator_string = "██" # change this to change separator, best if 2 characters wide
close = "\e[0m" # don't change this
separator = Array.new
for d in (1..days_in_month(year, month))
if year == Time.now.year && month == Time.now.month && d == Time.now.day then
separator[d] = "#{color}#{separator_string}#{close}"
else
separator[d] = "#{separator_string}"
end
end
separator.shift
return separator * "█"
end

-----

Am I wrong to assume we could change the variables from (year, month) to those pertaining to the concept in question ( HDD %, CPU, etc )?

More so, is there anyone here capable of doing this that WOULD be so kind to help out? :p


-Just wanted to throw it out there,

Ivan\\
 
Ok so I've been doing some thinking.

I realized that something blatantly amiss from geektools is a visual-aid "bar" for things like capacity and usage, not for functionality but for pure beauty for those who like it. For example, instead of merely saying you've used 700/1024 GB on your HDD, it would also display a white bar filled up with black up to the percentage corresponding to 700/1024. Same would apply to cpu usage ( although you basically have Activity Monitor right there for that ) and other things one might find it fits.

Being that I'm no programmer I just had this on my mind for a while and no way to do this. Then it hit me that the calendar our dear mate brenm666 provided has the following piece of code:

-----

Am I wrong to assume we could change the variables from (year, month) to those pertaining to the concept in question ( HDD %, CPU, etc )?

More so, is there anyone here capable of doing this that WOULD be so kind to help out? :p


-Just wanted to throw it out there,

Ivan\\

no clue how to do it, or even if its possible. but my guess would be that most of the code would change.
but I think the idea isn't worth the work. first you'd have to have a huge amount of squares to be able to see something (100 squares?) then, the amount of memory this would use (cuz you'd have to keep it at a refresh rate of 1 sec) you be too great to be worth it, IMHO.
but if someone would want to work on the script, I'd give it a try! ;)
 
I have a rather important question....

I have had my desktop "pimp'd" out with
Geektool scripts and images for the past
two years.

I feel the need to reformat my iMac. I think
there's some sort of virus or otherwise changing
my dock and removing my email setup. My
iMac has been acting weird for quite some time.

The only thing preventing me from doing a fresh
install is that I know I could never rebuild my
Geektool deskop. What I have built I could never
repeat again. It took a few months to perfect,
and all of it was done little-by-little using tricks and
methods in this thread.

Is there a way to backup Geektool? Is all the
information contained in one file?

I would love nothing more to do a fresh OS X
install and then transfer a single folder with all
my Geektool scripts and VOILA...my desktop is
restored.

Am I asking too much?

Go to the Preferences folder located in the Library folder inside your home folder, and back up every file that starts with "org.tynsoe". After you do a fresh install, put the backed up files into their places and then install Geektool. The files contain all your Geektool preferences so it will work (it worked when I accidentally uninstalled Geektool and then reinstalled it). Hope this helped.
 
Date Ordinal (Suffix)

Firstly would just like to mention what a great resource this thread has been for all of my, and let's be honest, all of our, geeklet needs.

Ok so here is my problem (continuing on from the date suffix issue that has been mentioned already):

What I'd like to do is, in a seperate shell script, only display the date ordinal/suffix (e.g. st, nd, rd, th...). But obviously it should correlate to the actual date.

(See image attachment to see what it looks like at the moment)

The code for what I have at the moment is:

Code:
date +"%d" | sed -E 's/([^1]1)$/\st/'| sed -E 's/([^1]2)$/\nd/' |sed -E 's/([^1]3)$/\rd/' | sed -E 's/([0-9])$/\th/'

This gives me the 10th number of every month before the suffix... odd.

I've also tried this with similar results:

Code:
date +"%d" | sed -E 's/(1)/\st/ ; s/(2)/\nd/ ; s/(3)/\rd/ ; s/(4)/\th/ ; s/(5)/\th/ ; s/(6)/\th/ ; s/(7)/\th/ ; s/(8)/\th/ ; s/(9)/\th/ ; s/(10)/\th/ ; s/(11)/\th/ ; s/(12)/\th/ ; s/(13)/\th/ ; s/(14)/\th/ ; s/(15)/\th/ ; s/(16)/\th/ ; s/(17)/\th/ ; s/(18)/\th/ ; s/(19)/\th/ ; s/(20)/\th/ ; s/(21)/\st/ ; s/(22)/\nd/ ; s/(23)/\rd/ ; s/(24)/\th/ ; s/(25)/\th/ ; s/(26)/\th/ ; s/(27)/\th/ ; s/(28)/\th/ ; s/(29)/\th/ ; s/(30)/\th/ ; s/(31)/\st/' | sed -E 's/  /  /'

But instead I get the 2nd suffix in front of the correct ordinal display... again odd.

I also know about this:

Code:
#!/usr/bin/env ruby
print ["th","st","nd","rd","th","th","th","th","th","th"][Time.now.day.to_s[-1,1].to_i]

But this incorrectly shows the "teen" dates, and replaces the suffix with the standard "th" instead.

So, the crux, is there a way of plainly displaying purely the date suffix? Even if the code just pointed to numbers from 1-31 and then added a suffix accordingly...

-Thanks to all you guys who provided most of this code on here :D-
 

Attachments

  • Screen shot 2011-05-28 at 11.39.55.png
    Screen shot 2011-05-28 at 11.39.55.png
    40 KB · Views: 2,055
So brenm666 and Zetthy were discussing a text based usage bar for disk space and I decided to write one.

Here it is. Save the file as diskusagebar.py in whatever directory you store your geeklet scripts. Remember to make the script executable with the chmod +x command in the terminal.

There are variables that are user customizable, I used the decimal value of a space for the separator. The chr command converts the decimal to an ASCII character.

I've included two attachments, one is the sample output and the other is the configuration I used in Nerdtool. Make sure that the output is able to be colorized, otherwise the script won't display properly. Fixed width fonts work best for the output from this script.
Code:
#!/usr/bin/env python

# +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# DISK USAGE BARS
# ROBERT WOLTERMAN, 2011
# 
# PYTHON PROGRAM THAT PRINTS OUT THE DISK USAGE OF YOUR MAC
# IN A VERY NICE, CUSTOMIZABLE PROGRESS BAR
# +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

# MODULE IMPORTS
import re, shlex, subprocess

# USER EDITABLE VARIABLES
separator   = chr(32)               # SEPARATOR, DEFAULTS TO A SPACE (asciitable.com FOR VALUES)
disks       = ("disk0s2","disk0s3") # THE DISKS TO LOOK FOR
disknames   = ("OS X","SHARE")      # NAMES FOR THE DISKS YOU WANT PRINTS
usedcolor   = '\033[47;1;37m'       # WHITE FORE AND BACKGROUND
unusedcolor = '\033[37;1;49m'       # WHITE FORE AND BLACK BACKGROUND
barsize     = 20                    # NUMBER OF CHARACTERS TO MAKE UP THE BAR
order       = "RL"                  # FORMAT: RL -> RIGHT TO LEFT, LR = LEFT TO RIGHT
textloc     = "RIGHT"               # 'ABOVE', 'BELOW', 'RIGHT', 'LEFT'

# DON'T MODIFY THESE VARIABLES
CMD = "df -h"

# DEFINE OUR PRINTING FUNCTION
class ProgressBar:
    def __init__(self,name,ordr,tloc,bsize,fsize,fused,units):
        self.name      = name
        self.order     = ordr
        self.textloc   = tloc
        self.barsize   = bsize
        self.fieldsize = fsize
        self.fieldused = fused
        self.units     = units
    
    def show(self):
        # FIGURE OUT OUR PERCENTAGE USED BASED ON SIZE OF BARS
        dpcntused = int(round(100*(float(self.fieldused)/self.fieldsize)))
        # FIGURE OUT HOW MANY BLOCKS WE NEED TO USE OF THE INPUT
        # BAR SIZE
        nblksused = int(self.barsize*(dpcntused/100.0))
        # SET UP THE INITIAL PART OF THE BAR
        bheadfoot = unusedcolor+"|"
        
        # GET UNUSED PORTION OF THE BAR
        unstr = unusedcolor
        for i in xrange(self.barsize-nblksused):
            unstr += separator
        
        # GET THE USED PORTION OF THE BAR
        ustr = usedcolor
        for i in xrange(nblksused):
            ustr += separator
        
        # SET UP THE BAR
        barstr = ""
        if   self.order == "RL":
            barstr = bheadfoot + unstr + ustr + bheadfoot
        elif self.order == "LR":
            barstr = bheadfoot + ustr + unstr + bheadfoot
        
        # SET UP THE STRING FORMAT
        outstr = ""
        if   self.textloc == "ABOVE":
            outstr = self.name + " " + str(dpcntused) + "% USED" + "\n" + barstr
        elif self.textloc == "BELOW":
            outstr = barstr + "\n" + self.name + " " + str(dpcntused) + "% USED"
        elif self.textloc == "RIGHT":
            outstr = barstr + " " + self.name + " " + str(dpcntused) + "% USED"
        elif self.textloc == "LEFT":
            outstr = self.name + "\t" + str(dpcntused) + "% USED" + " " + barstr
        
        # PRINT THE OUTPUT
        print outstr

if __name__ == "__main__":

    # GET THE CURRENT DISK USAGE OF THE SYSTEM
    cmd1 = shlex.split(CMD)
    diskdata = subprocess.Popen(cmd1,stdout=subprocess.PIPE).communicate()[0]
    
    diskdata = diskdata.split("\n")
    
    # LOOP THROUGH OUR TUPLE OF DISKS AND SEE IF THEY ARE IN THE DISK OUTPUT
    for i in xrange(len(disks)):
        for line in diskdata:
            if line != []:
                # SPLIT THE LINE ON ANY WHITESPACE
                tmp = line.split()
                # SPLIT THE FIRST SEGMENT WITH A /
                tmp2 = tmp[0].split('/')
                # FIGURE OUT IF WE HAVE A VALID DISK
                if len(tmp2) > 2:
                    # MATCH THE DISK WE'RE LOOKING FOR
                    if tmp2[len(tmp2)-1] == disks[i]:
                        # GET THE SIZE, UNITS, AND USED SPACE
                        size = int(tmp[1][0:len(tmp[1])-2])
                        unit = tmp[1][len(tmp[1])-2:]
                        used = int(tmp[2][0:len(tmp[2])-2])
                        # CREATE OUR PROGRESS BAR CLASS
                        p = ProgressBar(disknames[i],order,textloc,barsize,size,used,unit)
                        # SHOW THE PROGRESS BARs
                        p.show()
                        # EXIT LOOP IF WE MATCHED THE DISK WE WANTED TO LOOK FOR
                        break
    
    # RESET THE COMMAND PROMPT
    subprocess.call("tput sgr0",shell=True)
 

Attachments

  • diskbar.png
    diskbar.png
    27.1 KB · Views: 2,037
  • nerdtoolconfig.png
    nerdtoolconfig.png
    130.6 KB · Views: 146
Firstly would just like to mention what a great resource this thread has been for all of my, and let's be honest, all of our, geeklet needs.

Ok so here is my problem (continuing on from the date suffix issue that has been mentioned already):

What I'd like to do is, in a seperate shell script, only display the date ordinal/suffix (e.g. st, nd, rd, th...). But obviously it should correlate to the actual date.

(See image attachment to see what it looks like at the moment)

The code for what I have at the moment is:

Code:
date +"%d" | sed -E 's/([^1]1)$/\st/'| sed -E 's/([^1]2)$/\nd/' |sed -E 's/([^1]3)$/\rd/' | sed -E 's/([0-9])$/\th/'

This gives me the 10th number of every month before the suffix... odd.

I've also tried this with similar results:

Code:
date +"%d" | sed -E 's/(1)/\st/ ; s/(2)/\nd/ ; s/(3)/\rd/ ; s/(4)/\th/ ; s/(5)/\th/ ; s/(6)/\th/ ; s/(7)/\th/ ; s/(8)/\th/ ; s/(9)/\th/ ; s/(10)/\th/ ; s/(11)/\th/ ; s/(12)/\th/ ; s/(13)/\th/ ; s/(14)/\th/ ; s/(15)/\th/ ; s/(16)/\th/ ; s/(17)/\th/ ; s/(18)/\th/ ; s/(19)/\th/ ; s/(20)/\th/ ; s/(21)/\st/ ; s/(22)/\nd/ ; s/(23)/\rd/ ; s/(24)/\th/ ; s/(25)/\th/ ; s/(26)/\th/ ; s/(27)/\th/ ; s/(28)/\th/ ; s/(29)/\th/ ; s/(30)/\th/ ; s/(31)/\st/' | sed -E 's/  /  /'

But instead I get the 2nd suffix in front of the correct ordinal display... again odd.

I also know about this:

Code:
#!/usr/bin/env ruby
print ["th","st","nd","rd","th","th","th","th","th","th"][Time.now.day.to_s[-1,1].to_i]

But this incorrectly shows the "teen" dates, and replaces the suffix with the standard "th" instead.

So, the crux, is there a way of plainly displaying purely the date suffix? Even if the code just pointed to numbers from 1-31 and then added a suffix accordingly...

-Thanks to all you guys who provided most of this code on here :D-

Assuming that you only want the 'th' to show. You need to add a single period to the very first date command you provided us. Here is the new command for you.

Code:
date +"%d" | sed -E 's/([^1]1)$/\st/'| sed -E 's/([^1]2)$/\nd/' |sed -E 's/([^1]3)$/\rd/' | sed -E 's/(.[0-9])$/\th/'

If you notice, the period goes before the [0-9] in the last sed command and is used to grab all of the decimal values.
 
Still looking for a solution to this. Really, all I need is the first code mentioned to strip out the html tags it includes. Its so close to working perfectly... Would really like someone to take a look and see whats wrong.

Started working on this, but I got hit with a migraine, so it might be a little while.
 
So I'm on a roll with script writing (doesn't hurt that I'm working with python on a day-to-day basis at my job).

dotcommer wanted a script to display the 5 day Yahoo Forecast. The Yahoo Forecast RSS feed has a limit of 2 days from the current day, but the actual Yahoo Weather page for your location has a detailed forecast for 5 days.

Here is it. Save the script as fivedayforecast.py, update the URL variable to be the URL for your locations Yahoo Weather page. Don't forget to chmod +x the file in the Terminal.

Code:
#!/usr/bin/env python

# FIVEDAYFORCAST - VERSION 1
# ROBERT WOLTERMAN - 2011
# GRABS THE 5 DAY WEATHER FORECAST FROM YAHOO WEATHER FOR PRINTING IN GEEKTOOL

# CHANGELOG
# 30 MAY 2011
#  - ADDED 5 DAY HIGH/LOW CODE
# 29 MAY 2011
#  - INITIAL WRITE

# MODULE IMPORTS
import urllib, re, sys, string

# MODIFY THIS WITH YOUR WEATHER URL
URL   = "http://weather.yahoo.com/united-states/iowa/cedar-rapids-2376926/"
UNITS = "F"

# FIGURE OUT COMMAND LINE ARGUMENTS
# FCASTTYPE OF -h IS FOR 5 DAY HIGHS/LOWS
# FCASTTYPE OF -d IS FOR 5 DAY DETAILED
FCASTTYPE = sys.argv[1]

# FOR DEPLOYMENT
url = urllib.urlopen(URL)
urldata = url.read()

# DEBUG
#url = open("./lasvegaswx.txt")
#urldata = url.read()

# SCRIPT VARIABLES
days             = []
fcast            = []
highs            = []
lows             = []
LINESTOGET1      = 14
LINESTOGET2      = 3
count            = 0
fcastlistgrabber = []

if FCASTTYPE == '-d':
    # SPLIT THE WEATHER PAGE UP BY RETURN LINE
    fcastsect = re.split("\n+",urldata)
    # FIND THE DETAILED FORCAST
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-detailedforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+LINESTOGET1]
            break
    
    # BREAK UP THE FCASTLISTGRABBER
    for line in fcastlistgrabber:
        mat = re.search('<li><strong>.*<',line)
        if mat != None:
            days.append(mat.group(0).split('>')[2].split(':<')[0])
        else:
            fcast.append(line)
        
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):
        temp = string.capwords(days[i])
        print temp
        print " " + fcast[i]

elif FCASTTYPE == '-h':
    # SEARCH FOR THE 5 DAY
    fcastsect = re.split('\r+',urldata)
    count = 0
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-fivedayforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+2]
            break
        mat = re.search('<tr class="fiveday-icons">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+1])
        mat = re.search('<tr class="fiveday-temps">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+2])
    
    for line in fcastlistgrabber:
        # DAYS
        tmp = line.split('<th>')
        for i in xrange(len(tmp)):
            mat = re.search('.*</th>',tmp[i])
            if mat != None:
                days.append(mat.group(0).split('</th>')[0])
        
        # CONDITIONS
        tmp = line.split('<br/>')
        for i in xrange(len(tmp)):
            mat = re.search('.*\n{0,1}.*</div>',tmp[i])
            if mat != None:
                tmp2 = mat.group(0).split('</div>')[0].split('\n')
                if tmp2[0][0] != " " and len(tmp2) == 2:
                    tmp3 = tmp2[0].split('-')
                    fcast.append(tmp3[0] + tmp2[1])
                elif len(tmp2) == 1:
                    fcast.append(tmp2[0])
        
        # HIGH/LOW
        tmp = line.split('<td>')
        for i in xrange(len(tmp)):
            mat = re.search('.*<div>.*</div></td>',tmp[i])
            if mat != None:
                highs.append(int(mat.group(0).split('&#')[0].split(': ')[1]))
                lows.append(int(mat.group(0).split('&#')[1].split(': ')[1]))
                
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):    
        print "%s:\n %s\n H: %3d%s L: %3d%s" % (days[i],fcast[i],highs[i],UNITS,lows[i],UNITS)

To set up the geeklet to display the Detailed Forecast, use a shell with the following command:
Code:
python ~/path/to/fivedayforecast.py -d

To set up the geeklet to display the 5-Day High/Low Forecast, use a shell with the following command:
Code:
python ~/path/to/fivedayforecast.py -h

Here is the sample output I get from running the Python script in Terminal:
Code:
 python fivedayforecast.py -h
Today:
 Partly Cloudy/Wind
 H:  87F L:  70F
Tomorrow:
 Scattered T-storms
 H:  84F L:  57F
Wed:
 Mostly Sunny
 H:  85F L:  66F
Thu:
 Scattered T-storms
 H:  89F L:  68F
Fri:
 Mostly Sunny
 H:  96F L:  68F
Code:
$ python fivedayforecast.py -d
Today
 Windy with a mix of clouds and sun. High 89F. Winds S at 25 to 35 mph. Winds could occasionally gust over 40 mph.
Tonight
 Windy with isolated thunderstorms developing. Low around 70F. Winds S at 20 to 30 mph. Chance of rain 30%.
Tomorrow
 Partly to mostly cloudy skies with scattered thunderstorms mainly in the morning. A few storms may be severe. High 84F. Winds SW at 15 to 25 mph. Chance of rain 60%.
Tomorrow Night
 Mostly clear. Low 57F. Winds W at 10 to 20 mph.
Wednesday
 More sun than clouds. Highs in the mid 80s and lows in the mid 60s.
Thursday
 Clouds giving way to sun . Highs in the mid 80s and lows in the upper 60s.
Friday
 More sun than clouds. Highs in the upper 80s and lows in the upper 60s.
 
Last edited:
So I'm on a roll with script writing (doesn't hurt that I'm working with python on a day-to-day basis at my job).

dotcommer wanted a script to display the 5 day Yahoo Forecast. The Yahoo Forecast RSS feed has a limit of 2 days from the current day, but the actual Yahoo Weather page for your location has a detailed forecast for 5 days.

Here is it. Save the script as fivedayforecast.py, update the URL variable to be the URL for your locations Yahoo Weather page. Don't forget to chmod +x the file in the Terminal.

Code:
#!/usr/bin/env python

# FIVEDAYFORCAST - VERSION 1
# ROBERT WOLTERMAN - 2011
# GRABS THE 5 DAY WEATHER FORECAST FROM YAHOO WEATHER FOR PRINTING IN GEEKTOOL

# CHANGELOG
# 30 MAY 2011
#  - ADDED 5 DAY HIGH/LOW CODE
# 29 MAY 2011
#  - INITIAL WRITE

# MODULE IMPORTS
import urllib, re, sys, string

# MODIFY THIS WITH YOUR WEATHER URL
URL   = "http://weather.yahoo.com/united-states/iowa/cedar-rapids-2376926/"
UNITS = "F"

# FIGURE OUT COMMAND LINE ARGUMENTS
# FCASTTYPE OF -h IS FOR 5 DAY HIGHS/LOWS
# FCASTTYPE OF -d IS FOR 5 DAY DETAILED
FCASTTYPE = sys.argv[1]

# FOR DEPLOYMENT
url = urllib.urlopen(URL)
urldata = url.read()

# DEBUG
#url = open("./lasvegaswx.txt")
#urldata = url.read()

# SCRIPT VARIABLES
days             = []
fcast            = []
highs            = []
lows             = []
LINESTOGET1      = 14
LINESTOGET2      = 3
count            = 0
fcastlistgrabber = []

if FCASTTYPE == '-d':
    # SPLIT THE WEATHER PAGE UP BY RETURN LINE
    fcastsect = re.split("\n+",urldata)
    # FIND THE DETAILED FORCAST
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-detailedforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+LINESTOGET1]
            break
    
    # BREAK UP THE FCASTLISTGRABBER
    for line in fcastlistgrabber:
        mat = re.search('<li><strong>.*<',line)
        if mat != None:
            days.append(mat.group(0).split('>')[2].split(':<')[0])
        else:
            fcast.append(line)
        
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):
        temp = string.capwords(days[i])
        print temp
        print " " + fcast[i]

elif FCASTTYPE == '-h':
    # SEARCH FOR THE 5 DAY
    fcastsect = re.split('\r+',urldata)
    count = 0
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-fivedayforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+2]
            break
        mat = re.search('<tr class="fiveday-icons">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+1])
        mat = re.search('<tr class="fiveday-temps">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+2])
    
    for line in fcastlistgrabber:
        # DAYS
        tmp = line.split('<th>')
        for i in xrange(len(tmp)):
            mat = re.search('.*</th>',tmp[i])
            if mat != None:
                days.append(mat.group(0).split('</th>')[0])
        
        # CONDITIONS
        tmp = line.split('<br/>')
        for i in xrange(len(tmp)):
            mat = re.search('.*\n{0,1}.*</div>',tmp[i])
            if mat != None:
                tmp2 = mat.group(0).split('</div>')[0].split('\n')
                if tmp2[0][0] != " " and len(tmp2) == 2:
                    tmp3 = tmp2[0].split('-')
                    fcast.append(tmp3[0] + tmp2[1])
                elif len(tmp2) == 1:
                    fcast.append(tmp2[0])
        
        # HIGH/LOW
        tmp = line.split('<td>')
        for i in xrange(len(tmp)):
            mat = re.search('.*<div>.*</div></td>',tmp[i])
            if mat != None:
                highs.append(int(mat.group(0).split('&#')[0].split(': ')[1]))
                lows.append(int(mat.group(0).split('&#')[1].split(': ')[1]))
                
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):    
        print "%s:\n %s\n H: %3d%s L: %3d%s" % (days[i],fcast[i],highs[i],UNITS,lows[i],UNITS)

To set up the geeklet to display the Detailed Forecast, use a shell with the following command:
Code:
python ~/path/to/fivedayforecast.py -d

To set up the geeklet to display the 5-Day High/Low Forecast, use a shell with the following command:
Code:
python ~/path/to/fivedayforecast.py -h

Here is the sample output I get from running the Python script in Terminal:
Code:
 python fivedayforecast.py -h
Today:
 Partly Cloudy/Wind
 H:  87F L:  70F
Tomorrow:
 Scattered T-storms
 H:  84F L:  57F
Wed:
 Mostly Sunny
 H:  85F L:  66F
Thu:
 Scattered T-storms
 H:  89F L:  68F
Fri:
 Mostly Sunny
 H:  96F L:  68F
Code:
$ python fivedayforecast.py -d
Today
 Windy with a mix of clouds and sun. High 89F. Winds S at 25 to 35 mph. Winds could occasionally gust over 40 mph.
Tonight
 Windy with isolated thunderstorms developing. Low around 70F. Winds S at 20 to 30 mph. Chance of rain 30%.
Tomorrow
 Partly to mostly cloudy skies with scattered thunderstorms mainly in the morning. A few storms may be severe. High 84F. Winds SW at 15 to 25 mph. Chance of rain 60%.
Tomorrow Night
 Mostly clear. Low 57F. Winds W at 10 to 20 mph.
Wednesday
 More sun than clouds. Highs in the mid 80s and lows in the mid 60s.
Thursday
 Clouds giving way to sun . Highs in the mid 80s and lows in the upper 60s.
Friday
 More sun than clouds. Highs in the upper 80s and lows in the upper 60s.

Thank you very much for putting in the effort to create this! I also appreciate you commenting everything. Makes it easier for me to pick it apart and learn from it. I have a big book on python collecting dust, so this makes we want to pull it out again.

A suggestion though, I added another return to the code so that the day/forecast are separated by a blank return. It looked nicer and easier to read that way, but I would also suggest adding in the option to either bold, or underline the day in the forecast, for even better readability. I don't know how to format printed text from python though.
 
Thank you very much for putting in the effort to create this! I also appreciate you commenting everything. Makes it easier for me to pick it apart and learn from it. I have a big book on python collecting dust, so this makes we want to pull it out again.

A suggestion though, I added another return to the code so that the day/forecast are separated by a blank return. It looked nicer and easier to read that way, but I would also suggest adding in the option to either bold, or underline the day in the forecast, for even better readability. I don't know how to format printed text from python though.

I had wondered about adding another return line...

I don't think it's possible to do font styles like that within the command line, I will research it though, as I agree that it could make it easier to read. As an interim, you could always print out a bunch of dashes between the date and the forecast.

For the detailed, the print loop would change to the following:
Code:
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):
        temp = string.capwords(days[i])
        print temp
        print "-------------------"
        print " " + fcast[i] + "\n"

For the 5 day high/low, the print loop would be:
Code:
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):    
        print "%s:\n-------------------\n %s\n H: %3d%s L: %3d%s\n" % (days[i],fcast[i],highs[i],UNITS,lows[i],UNITS)

Both of these add a return line right before the next day.

I believe in code commenting; I'm glad you were able to pick out what I was doing with the comments. The only confusing part of this code was the regular expressions to grab the sections of HTML we needed.
 
I had wondered about adding another return line...

I don't think it's possible to do font styles like that within the command line, I will research it though, as I agree that it could make it easier to read. As an interim, you could always print out a bunch of dashes between the date and the forecast.

For the detailed, the print loop would change to the following:
Code:
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):
        temp = string.capwords(days[i])
        print temp
        print "-------------------"
        print " " + fcast[i] + "\n"

For the 5 day high/low, the print loop would be:
Code:
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):    
        print "%s:\n-------------------\n %s\n H: %3d%s L: %3d%s\n" % (days[i],fcast[i],highs[i],UNITS,lows[i],UNITS)

Both of these add a return line right before the next day.

I believe in code commenting; I'm glad you were able to pick out what I was doing with the comments. The only confusing part of this code was the regular expressions to grab the sections of HTML we needed.

What about trying to utilize ASCII escape sequences? There's one listed here for setting formatting of outputs. I don't know if this works with python though:

http://ascii-table.com/ansi-escape-sequences.php
 
What about trying to utilize ASCII escape sequences? There's one listed here for setting formatting of outputs. I don't know if this works with python though:

http://ascii-table.com/ansi-escape-sequences.php

Well damn, I knew there were escape sequences for colors, but not for underline. My quick google-fu earlier failed me.

Here is the complete code with the underline in it:
Code:
#!/usr/bin/env python

# FIVEDAYFORCAST - VERSION 1
# ROBERT WOLTERMAN - 2011
# GRABS THE 5 DAY WEATHER FORECAST FROM YAHOO WEATHER FOR PRINTING IN GEEKTOOL

# CHANGELOG
# 31 MAY 2011
#  - ADDED UNDERLINE TO DAY WHEN PRINTING OUTPUT
# 30 MAY 2011
#  - ADDED 5 DAY HIGH/LOW CODE
# 29 MAY 2011
#  - INITIAL WRITE

# MODULE IMPORTS
import urllib, re, sys, string

# MODIFY THIS WITH YOUR WEATHER URL
URL   = "http://weather.yahoo.com/united-states/iowa/cedar-rapids-2376926/"
UNITS = "F"

# FIGURE OUT COMMAND LINE ARGUMENTS
# FCASTTYPE OF -h IS FOR 5 DAY HIGHS/LOWS
# FCASTTYPE OF -d IS FOR 5 DAY DETAILED
FCASTTYPE = sys.argv[1]

# FOR DEPLOYMENT
url = urllib.urlopen(URL)
urldata = url.read()

# DEBUG
#url = open("./lasvegaswx.txt")
#urldata = url.read()

# SCRIPT VARIABLES
days             = []
fcast            = []
highs            = []
lows             = []
LINESTOGET1      = 14
LINESTOGET2      = 3
count            = 0
fcastlistgrabber = []

if FCASTTYPE == '-d':
    # SPLIT THE WEATHER PAGE UP BY RETURN LINE
    fcastsect = re.split("\n+",urldata)
    # FIND THE DETAILED FORCAST
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-detailedforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+LINESTOGET1]
            break
    
    # BREAK UP THE FCASTLISTGRABBER
    for line in fcastlistgrabber:
        mat = re.search('<li><strong>.*<',line)
        if mat != None:
            days.append(mat.group(0).split('>')[2].split(':<')[0])
        else:
            fcast.append(line)
        
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):
        temp = string.capwords(days[i])
        print "\033[4m" + temp + "\033[0m"
        print " " + fcast[i] + "\n"

elif FCASTTYPE == '-h':
    # SEARCH FOR THE 5 DAY
    fcastsect = re.split('\r+',urldata)
    count = 0
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-fivedayforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+2]
            break
        mat = re.search('<tr class="fiveday-icons">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+1])
        mat = re.search('<tr class="fiveday-temps">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+2])
    
    for line in fcastlistgrabber:
        # DAYS
        tmp = line.split('<th>')
        for i in xrange(len(tmp)):
            mat = re.search('.*</th>',tmp[i])
            if mat != None:
                days.append(mat.group(0).split('</th>')[0])
        
        # CONDITIONS
        tmp = line.split('<br/>')
        for i in xrange(len(tmp)):
            mat = re.search('.*\n{0,1}.*</div>',tmp[i])
            if mat != None:
                tmp2 = mat.group(0).split('</div>')[0].split('\n')
                if tmp2[0][0] != " " and len(tmp2) == 2:
                    tmp3 = tmp2[0].split('-')
                    fcast.append(tmp3[0] + tmp2[1])
                elif len(tmp2) == 1:
                    fcast.append(tmp2[0])
        
        # HIGH/LOW
        tmp = line.split('<td>')
        for i in xrange(len(tmp)):
            mat = re.search('.*<div>.*</div></td>',tmp[i])
            if mat != None:
                highs.append(int(mat.group(0).split('&#')[0].split(': ')[1]))
                lows.append(int(mat.group(0).split('&#')[1].split(': ')[1]))
                
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):    
        print "\033[4m%s\033[0m:\n %s\n H: %3d%s L: %3d%s\n" % (days[i],fcast[i],highs[i],UNITS,lows[i],UNITS)
 
Can somebody help me find the shell script that lets me pull my BusyCal data into Geek Tool? I saw that a previous person here had done it, and I just cant seem to find the script. Can anyone point me in the right direction?
 
Well damn, I knew there were escape sequences for colors, but not for underline. My quick google-fu earlier failed me.

Here is the complete code with the underline in it:
Code:
#!/usr/bin/env python

# FIVEDAYFORCAST - VERSION 1
# ROBERT WOLTERMAN - 2011
# GRABS THE 5 DAY WEATHER FORECAST FROM YAHOO WEATHER FOR PRINTING IN GEEKTOOL

# CHANGELOG
# 31 MAY 2011
#  - ADDED UNDERLINE TO DAY WHEN PRINTING OUTPUT
# 30 MAY 2011
#  - ADDED 5 DAY HIGH/LOW CODE
# 29 MAY 2011
#  - INITIAL WRITE

# MODULE IMPORTS
import urllib, re, sys, string

# MODIFY THIS WITH YOUR WEATHER URL
URL   = "http://weather.yahoo.com/united-states/iowa/cedar-rapids-2376926/"
UNITS = "F"

# FIGURE OUT COMMAND LINE ARGUMENTS
# FCASTTYPE OF -h IS FOR 5 DAY HIGHS/LOWS
# FCASTTYPE OF -d IS FOR 5 DAY DETAILED
FCASTTYPE = sys.argv[1]

# FOR DEPLOYMENT
url = urllib.urlopen(URL)
urldata = url.read()

# DEBUG
#url = open("./lasvegaswx.txt")
#urldata = url.read()

# SCRIPT VARIABLES
days             = []
fcast            = []
highs            = []
lows             = []
LINESTOGET1      = 14
LINESTOGET2      = 3
count            = 0
fcastlistgrabber = []

if FCASTTYPE == '-d':
    # SPLIT THE WEATHER PAGE UP BY RETURN LINE
    fcastsect = re.split("\n+",urldata)
    # FIND THE DETAILED FORCAST
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-detailedforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+LINESTOGET1]
            break
    
    # BREAK UP THE FCASTLISTGRABBER
    for line in fcastlistgrabber:
        mat = re.search('<li><strong>.*<',line)
        if mat != None:
            days.append(mat.group(0).split('>')[2].split(':<')[0])
        else:
            fcast.append(line)
        
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):
        temp = string.capwords(days[i])
        print "\033[4m" + temp + "\033[0m"
        print " " + fcast[i] + "\n"

elif FCASTTYPE == '-h':
    # SEARCH FOR THE 5 DAY
    fcastsect = re.split('\r+',urldata)
    count = 0
    for line in fcastsect:
        count += 1
        mat = re.search('<div id="yw-fivedayforecast">',line)
        if mat != None:
            fcastlistgrabber = fcastsect[count-1:count+2]
            break
        mat = re.search('<tr class="fiveday-icons">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+1])
        mat = re.search('<tr class="fiveday-temps">',line)
        if mat != None:
            fcastlistgrabber.append(fcastsect[count-1:count+2])
    
    for line in fcastlistgrabber:
        # DAYS
        tmp = line.split('<th>')
        for i in xrange(len(tmp)):
            mat = re.search('.*</th>',tmp[i])
            if mat != None:
                days.append(mat.group(0).split('</th>')[0])
        
        # CONDITIONS
        tmp = line.split('<br/>')
        for i in xrange(len(tmp)):
            mat = re.search('.*\n{0,1}.*</div>',tmp[i])
            if mat != None:
                tmp2 = mat.group(0).split('</div>')[0].split('\n')
                if tmp2[0][0] != " " and len(tmp2) == 2:
                    tmp3 = tmp2[0].split('-')
                    fcast.append(tmp3[0] + tmp2[1])
                elif len(tmp2) == 1:
                    fcast.append(tmp2[0])
        
        # HIGH/LOW
        tmp = line.split('<td>')
        for i in xrange(len(tmp)):
            mat = re.search('.*<div>.*</div></td>',tmp[i])
            if mat != None:
                highs.append(int(mat.group(0).split('&#')[0].split(': ')[1]))
                lows.append(int(mat.group(0).split('&#')[1].split(': ')[1]))
                
    # PRINT OUT THE FORECAST
    for i in xrange(len(days)):    
        print "\033[4m%s\033[0m:\n %s\n H: %3d%s L: %3d%s\n" % (days[i],fcast[i],highs[i],UNITS,lows[i],UNITS)

Nicely done. Thank you again for your willingness to update and improve upon this. We really need to post this around so others can benefit from this. I think people are tired of just a near-sighted forecast from yahoo. haha.

Now, I have one more addition to this script; flexibility. I think you could set up the script so that it dynamically grabs the current IP, figures out the location (zip), and then substitutes it back into the yahoo weather url.

One guy was getting something set up and working on page 83 https://forums.macrumors.com/posts/9969975/. Looks like he used a site that automatically identifies the ip address and spits out a zip, so I'm thinking all you'd need to do is tell python to go to this url, grab the text, pars it, take out the specific piece that has the zip, save as a variable, then use that in the url address. What do you think?

EDIT:
Unfortunately, it seems Yahoo weather has changed to WOEID tags for its weather... Thats a pain in the ass. It looks like you'd have to identify the ip, send the ip to convert to a zip, then send that zip to someplace to convert to a WOEID, then input that variable into the url. I did a little digging but this is about as useful as I could find on converting the zip to a WOEID:

http://arguments.callee.info/2010/03/26/convert-zip-code-to-yahoo-woeid/

and then one guy actually turned it into a functioning page: http://arguments.callee.info/sandbox/zip-woeid/

And here's a resource directed more at python. Similar situation, but directs to the two day, not the 5 day:
http://www.thomasupton.com/blog/2008/04/yahoo-weather-feeds-with-python/

Hope that helps.
 
Last edited:
Nicely done. Thank you again for your willingness to update and improve upon this. We really need to post this around so others can benefit from this. I think people are tired of just a near-sighted forecast from yahoo. haha.

Now, I have one more addition to this script; flexibility. I think you could set up the script so that it dynamically grabs the current IP, figures out the location (zip), and then substitutes it back into the yahoo weather url.

One guy was getting something set up and working on page 83 https://forums.macrumors.com/posts/9969975/. Looks like he used a site that automatically identifies the ip address and spits out a zip, so I'm thinking all you'd need to do is tell python to go to this url, grab the text, pars it, take out the specific piece that has the zip, save as a variable, then use that in the url address. What do you think?

EDIT:
Unfortunately, it seems Yahoo weather has changed to WOEID tags for its weather... Thats a pain in the ass. It looks like you'd have to identify the ip, send the ip to convert to a zip, then send that zip to someplace to convert to a WOEID, then input that variable into the url. I did a little digging but this is about as useful as I could find on converting the zip to a WOEID:

http://arguments.callee.info/2010/03/26/convert-zip-code-to-yahoo-woeid/

and then one guy actually turned it into a functioning page: http://arguments.callee.info/sandbox/zip-woeid/

And here's a resource directed more at python. Similar situation, but directs to the two day, not the 5 day:
http://www.thomasupton.com/blog/2008/04/yahoo-weather-feeds-with-python/

Hope that helps.

Thanks for the link to the other MacRumors forum thread, I couldn't find that after you mentioned it before. I have been thinking about how to do the automatic zip code pull since you mentioned it, but this is more of a kick in the butt to try and get it to work.

I'm actually using Thomas Upton's forecast script on my Mac, although a little modified to extract other information from the Yahoo Weather RSS Page. I pulled the weather icons from the Yahoo Weather widget, changed them to all white, write a Python script that would take the condition # and then copy the proper weather image to a temporary png file that Geektool displays. I grabbed the condition # out of Thomas' code that I modified, just added another parse statement on the XML.

I'm looking into the WOEID stuff. I do like the idea of pulling your external IP, grabbing the zip code, getting the WOEID, storing the zip and WOEID locally so you don't always have to ping Yahoo for that information, and then getting the forecast.

It might take a bit to get this all hashed out, I'm not sure I have to work this weekend and there is stuff the wife wants to do since there is a festival going on in town Saturday.
 
DD/MM/YY script

Does anyone have a DD/MM/YY calender script that I can use?

Thanks

EDIT: figured it out.
 
Last edited:
Here's mine, made up a variety of scripts, message me if you want a particular one, although they're not hard to find. The background is a custom one using photoshop brushes.

1. RAM and CPU
2. Wifi name
3. Download and Upload
4. Ethernet and Airport
5. Comp specs
6. Time and Date
7. Weather
8. Battery Charge
9. Email


Screenshot2011-06-06at175335.png
 
Just found this thread

Hi All,

I just found this thread looking for a working stock ticker script. Well I came across post 751 and it worked great. But I did some tweaks to make it easy to reproduce and choose your stock symbol quickly with out editing the script. So I made two scripts one that is for when the stock is up.. and one for when it is down and you can overlay them. The way the script works if its for up it only shows if the stock is up... and vise verse. So you can set two different colors for up and down.

Here is the script for up:
Code:
#!/bin/sh

# StockUp.sh
# Usage:
# StockUp.sh AAPL
# Apple is AAPL

mysymbol="$1"
curl http://www.google.ca/finance?q="$1" | sed -n '/price-panel style/,/ Close/p' | sed -e :a -e 's/<[^>]*>//g;/</N;//ba'| sed '/^$/d' | sed -e '$!N;s/\n/ /' -e '$!N;s/\n/ /' | head -1  | sed 's/^/'"$1"': /g'| sed '/-/d'

Here is the script for down:
Code:
#!/bin/sh

# StockDown.sh
# Usage:
# StockDown.sh AAPL
# Apple is AAPL

mysymbol="$1"
curl http://www.google.ca/finance?q="$1" | sed -n '/price-panel style/,/ Close/p' | sed -e :a -e 's/<[^>]*>//g;/</N;//ba'| sed '/^$/d' | sed -e '$!N;s/\n/ /' -e '$!N;s/\n/ /' | head -1  | sed 's/^/'"$1"': /g'| sed -n '/-/p'

And here is a screen shot of my desktop:
Screen%20shot%202011-06-06%20at%209.13.34%20PM.jpg


If there is any questions about the script I posted or anything you see on my desktop don't hesitate to ask.
 
Status
Not open for further replies.
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.