#!/usr/bin/python2
# This is a simple script that takes live GOES data from gsfc.nasa.gov,
# does some dynamic scaling, composites a state overlay on top, and publishes
# the result as a .png file.
# An associated webpage allows a web browser to have a live view.
# This script is called at by cron on a regular basis.

from PIL import Image, ImageOps, ImageDraw, ImageFont
from urllib2 import urlopen, Request, URLError
import os, datetime

# Some global definitions
maxval      = 80
goespath    = 'http://goes.gsfc.nasa.gov/goeseast/conus/vis/latest.tif'
goesoffline = '1609172300G13I01.tif'
overlaypath = '/var/www/alpha.nitk.in/conus_1006011745_G13I01_states.tif'
outpath     = '/var/www/alpha.nitk.in/goesconus.png'
rotpath     = '/var/www/alpha.nitk.in/goesrotate/conus-{:03d}.png'
lastsizepath= '/var/www/alpha.nitk.in/lastsize.txt'

# The overlay is downloaded from the below URL and stored locally to minimize HTTP traffic.
#overlay   = 'http://goes.gsfc.nasa.gov/goeseast/conus/maps/conus_1006011745_G13I01_states.tif'

# Check if the file changed sizes; return if not.
request = Request(goespath)
request.get_method = lambda : 'HEAD'

# Try to open the file twice - this sometimes times out.
try:             newlength = urlopen(request).info()["Content-Length"]
except URLError: newlength = urlopen(request).info()["Content-Length"]

try:    oldlength = open(lastsizepath, 'r').read()
except: oldlength = None
if newlength == oldlength: exit()
open(lastsizepath, 'w').write(newlength)

base = Image.open(urlopen(goespath))
overlay = Image.open(overlaypath)

# Get the TIFF comment with timestamp and stuff. See below for details.
# http://goes.gsfc.nasa.gov/text/goesfaq.html#tiffcomment
try:                   comment = base.tag_v2[270]
except AttributeError: comment = '\nGOES 13 Imager frame ??? at UTC 00:00:00.000 day 00 of 0000'
line = comment.split('\n')[1].split()

# Parse the date string into something standard.
timestring = '{time} {doy:03d} {year}'.format(
	time=line[7].split('.')[0],
	doy=int(line[9]),
	year=line[11])
stamp = datetime.datetime.strptime(timestring, '%H:%M:%S %j %Y')

# Put together a minimalist string with satellite number, date, time, and frame ID.
imagetext = 'GOES {num}: {date} (frame {frame:3d})'.format(
	num   = line[1],
	date  = stamp,
	frame = int(line[4])
	)

# Scale GOES data
lut = range(256)
for i in lut: lut[i] = i*256/maxval
base = base.point(lut)

# Overlay states
mask = ImageOps.invert(overlay.convert("L"))
base.paste(overlay, None, mask)

# Add the comment to the image.
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf', 20)
draw = ImageDraw.Draw(base)
draw.text((20, 5), imagetext, font=font, fill=128)

# Write to disk
base.save(outpath)

# Rotate to save two days or so of images.
# image299 -> image300, 298 -> 299, and so on down to 0.
# These are used for https://alpha.nitk.in/goesrotate.html
for x in range(299, -1, -1):
    try:            os.rename(rotpath.format(x), rotpath.format(x+1))
    except OSError: print "Could not open {}. Skipping.".format(rotpath.format(x))
base.save(rotpath.format(0))
