#!/usr/bin/env python2

# Any command line argument will cause this script to run in testing mode. If the
# argument is "push" all the 25day and 10day images will be pushed to the 50Webs 
# server.

# To use this file: 
#    Edit (if needed) charts_input_testing.html 
#    Edit (if needed) this file, getChartsFor50webs_testing.py, and run it with a "test" or "push" argument.
#    Then view the charts_testing.html file on the NUC.
#    Then finally, run publish.bat 

# The testing version of this file is intended for manual execution. Then, when publish.bat
# is run, this is copied over the non-testing version which is referred to in the 
# getChartsFor50webs.bat file (The batch file is used by the scheduled task.)

# System and OS
import sys, os, shutil, random

# Strings
import string

# HTML fetching
import urllib2

# Windows extensions (pywin32-220.win32-py2.7.exe)
import win32com.client
import pywintypes  # supports exceptions names

# time and date functionality
import time
from datetime import datetime

# FTP
from ftplib import FTP


#==Functions====================================================================

def uploadBinaryFile(serverPath, localPath, filename):
    ftp.storbinary('STOR ' + serverPath + filename, open(localPath + filename, 'rb'))

def uploadTextFile(serverPath, localPath, filename):
    ftp.storlines('STOR ' + serverPath + filename, open(localPath + filename, 'r'))
   
def getChart( stationRegion, stationName, sensorName, nDays, imageFileName):
    # One-day charts will use the 24Hour option.
    webpage_url = ("http://" + "192.168.1.106/" + webSite + "/rosy.asp?Region=" + stationRegion + 
                   "&Region_state=old&Location=" + stationName + "&Sensor=" + sensorName + 
                   "&Days=" + nDays + "&chk24Hrs=on&chkRA=on&jS=T&specName=" + imageFileName)
    #print sensorName, webpage_url
    request = urllib2.Request(webpage_url, headers={'User-Agent': 'Mozilla/5.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'})
    page = urllib2.urlopen(request)
    return page
   
def updateCharts(station):
    stationRegion = station[0]
    stationName = station[1]

    newImageLine = "not found"
    multiDayChartsUpdated = False
    
    # Get the wind chart from the local Waconia site.
    windPage24hr = getChart( stationRegion, stationName, "Wind40", "1", "WindChart")

    # Find the div that references the image files.
    for line in windPage24hr:
        #print "once per line..."
        if "id='directions'" in line:
            print "Found the new 'directions' line in source file."
            newImageLine = line

   
    # Get the temperature and pressure charts from the local Waconia site.
    getChart( stationRegion, stationName, "Temperature", "1", "TemperatureChart")
    #getChart( stationRegion, stationName, "Pressure",    "1", "PressureChart")
    
    
    # Copy the image files to the 50webs-dev site on NUC.
    pathToSourceFolderForImages = 'C:\\Users\\Jim\\Documents\\webcontent\\waconia\\' + sitePath + '\\chart-images\\'
    pathToTargetFolder = "C:\\Users\\Jim\\Documents\\webcontent\\waconia\\50webs-dev\\"
    
    shutil.copy(pathToSourceFolderForImages + 'WindChart.jpg', pathToTargetFolder + 'chart-images')
    shutil.copy(pathToSourceFolderForImages + 'TemperatureChart.jpg', pathToTargetFolder + 'chart-images')
    #shutil.copy(pathToSourceFolderForImages + 'PressureChart.jpg', pathToTargetFolder + 'chart-images')
    
    # Upload the image files to the 50Webs host.
    if (not testingMode) and (webHost == "50Webs"):
        uploadBinaryFile('chart-images/', pathToSourceFolderForImages, 'WindChart.jpg')
        uploadBinaryFile('chart-images/', pathToSourceFolderForImages, 'TemperatureChart.jpg')
        #uploadBinaryFile('chart-images/', pathToSourceFolderForImages, 'PressureChart.jpg')
    
    # Get a 25-day pressure chart for Alaska and Barking Sands. Trigger this based on the first location in
    # the randomized site list. This special trigger will keep this from frequent uploads.
    #print "station trigger (PAQT, PHBK) = ", stationList[0][1], stationList[1][1]
    print "station trigger (PATQ or RMTN) = ", stationName
    
    #if (stationList[0][1]=="PAQT" and stationList[1][1]=="PHBK"):
    if (stationName == "PATQ") or (stationName == "RMTN") or pushImagesToServer:
        getChart( "Misc", "PATQ", "Pressure",    "25", "25DayPressureChart-1")
        getChart( "Misc", "PATQ", "Temperature", "25", "25DayTemperatureChart")
        getChart( "Misc", "PATQ", "Wind40",      "25", "25DayWindChart")
        getChart( "CR",   "300A", "Pressure"   , "25", "25DayPressureChart-2")
        getChart( "Misc", "PHBK", "Pressure",    "25", "25DayPressureChart-3")
        #getChart( "CR",   "KTTD", "DeltaP2",     "10", "DeltaPressureChart")
        getChart( "CR", "PORTLAND", "DeltaP1",    "10", "DeltaPressureChart")
        
        shutil.copy(pathToSourceFolderForImages + '25DayPressureChart-1.jpg',  pathToTargetFolder + 'chart-images')
        shutil.copy(pathToSourceFolderForImages + '25DayTemperatureChart.jpg', pathToTargetFolder + 'chart-images')
        shutil.copy(pathToSourceFolderForImages + '25DayWindChart.jpg',        pathToTargetFolder + 'chart-images')
        shutil.copy(pathToSourceFolderForImages + '25DayPressureChart-2.jpg',  pathToTargetFolder + 'chart-images')
        shutil.copy(pathToSourceFolderForImages + '25DayPressureChart-3.jpg',  pathToTargetFolder + 'chart-images')
        shutil.copy(pathToSourceFolderForImages + 'DeltaPressureChart.jpg',    pathToTargetFolder + 'chart-images')
        
        if ((not testingMode) or pushImagesToServer) and (webHost == "50Webs"):
            uploadBinaryFile('chart-images/', pathToSourceFolderForImages, '25DayPressureChart-1.jpg')
            uploadBinaryFile('chart-images/', pathToSourceFolderForImages, '25DayTemperatureChart.jpg')
            uploadBinaryFile('chart-images/', pathToSourceFolderForImages, '25DayWindChart.jpg')
            uploadBinaryFile('chart-images/', pathToSourceFolderForImages, '25DayPressureChart-2.jpg')
            uploadBinaryFile('chart-images/', pathToSourceFolderForImages, '25DayPressureChart-3.jpg')
            uploadBinaryFile('chart-images/', pathToSourceFolderForImages, 'DeltaPressureChart.jpg')
        
        print "25-day pressure charts have updated."
        multiDayChartsUpdated = True
    
    # Edit the local html file to include the specifics of the div that holds the 
    # two images: chart and second # y-axis scale. Also update the two timestamps.
    
    inputFile = open(pathToTargetFolder + inputHTMLFileName, 'r')
    outputFile = open(pathToTargetFolder + outputHTMLFileName, 'w')

    for oldLine in inputFile:
        if ("id='directions'" in oldLine) and (newImageLine <> "not found"):
            print "Found the 'directions' line in input file."
            #print "Old line= ", oldLine
            #print "New line= ", newImageLine
            outputFile.write(newImageLine)
            
        elif "24-hour charts" in oldLine:
            print 'Updated the 24hr-charts timestamp.'
            outputFile.write("(24-hour charts updated " + datetime.now().strftime("%A, %B %d, %Y at %I:%M%p") + " Central).\n")
        
        elif ("Multi-day charts" in oldLine) and multiDayChartsUpdated:
            print 'Updated the multi-day-charts timestamp.'
            outputFile.write("(Multi-day charts updated " + datetime.now().strftime("%A, %B %d, %Y at %I:%M%p") + " Central).\n")
            
        else:
            outputFile.write(oldLine)
            #print oldLine,

    inputFile.close()
    outputFile.close()
    
    # Upload the html file from the 50Webs dev site on the NUC to 50Webs.
    if (webHost == "50Webs"):
        uploadTextFile('', 'C:\\Users\\Jim\\Documents\\webcontent\\waconia\\50webs-dev\\', outputHTMLFileName)

    # Replace the old input file with the newly generated output file. This carries over the prior time-stamp on
    # the multi-day charts even if they are not updated.
    shutil.copyfile(pathToTargetFolder + outputHTMLFileName, pathToTargetFolder + inputHTMLFileName)
    

#==Main=========================================================================

# Generate the image and send the image and page (for all hours after 6am).
if (datetime.now().hour > 6):

    # My Firebase site uses a scheduled batch file to publish the image and html files. 
    webHost = "Firebase"  # "50Webs"

    pushImagesToServer = False

    if len(sys.argv) > 1:
        # If there is a command line argument, run this in testing mode.
        print "In testing mode..."
        testingMode = True
        
        if sys.argv[1] == "push":
            pushImagesToServer = True
        
    else:
        testingMode = False

    # Shift gears if in testing mode. Note: a "push" is always in testing mode and uses the
    # dev site for ASP runs and images.
    if testingMode == True:
        webSite = "waconia-dev"
        inputHTMLFileName = "charts_input_testing.html"
        outputHTMLFileName = "charts_testing.html"
        sitePath = "website-dev"    
    else:
        webSite = "waconia"
        inputHTMLFileName = "charts_input.html"
        outputHTMLFileName = "charts.html"
        sitePath = "website-prod"

        
    # Connect to the server.
    if (webHost == "50Webs"):
        ftp = FTP('jimandlaurie.50webs.com')
        ftp.login(user='jb_miller', passwd='77d9b54688')
        ftp.cwd('/waconia.timetocode.org')
        #ftp.dir()

    # List of Stations.
    # Note that RMTN does not have a pressure sensor now.
    stationList = [ ['CR','RMTN'], ['CR','RMTN'], ['CR','KRLD'], ['MN','KMKT.2'], ['Misc','PATQ'], ['Misc','PHOG'] ]

    random.shuffle(stationList)
    randomStation = stationList[0]
    print randomStation

    updateCharts( randomStation)

    if (webHost == "50Webs"):
        ftp.quit()