#!/usr/bin/python2
#This program is called on login to display the status of mythtv tuners & recording status
#Also will display alerts generated by xymon.  If the location of xymon changes, this script needs to be updated.

from MythTV import MythBE,MythDB,MythLog
import datetime,time,sys,subprocess,re
import os,glob
from socket import gethostname;

def formatTD(td):
    days = td.days
    hours = td.seconds // 3600
    minutes = (td.seconds % 3600) // 60
    seconds = td.seconds % 60

    if days == 0:
      day_string = ""
    elif days > 1:
      day_string = "%s days, " %days
    else:
      day_string = "%s day, " %days

    if hours > 1:
      hour_string = "%s hours, " %hours
    else:
      hour_string = "%s hour, " %hours

    if minutes > 1:
      minute_string = "%s minutes, " %minutes
    else:
      minute_string = "%s minute, " %minutes

    if seconds > 1:
      second_string = "%s seconds" %seconds
    else:
      second_string = "%s second" %seconds

    return_string = '%s%s%s%s' % (day_string, hour_string, minute_string, second_string)
    return return_string

def print_alerts():
    dir_name = "/home/xymon/var/login_alerts"
    out_alert=""
    try:
        os.chdir(dir_name)
    except:
        pass
        #print "    myth_status: Couldn't change dir to %s" %dir_name

    file_list=glob.glob("*")
    
    if len(file_list) == 0:
        #print "    myth_status:  no alert files found"
        pass
    else:
        for alert_file in file_list:
            out_line=''
            datahost = ''
            dataservice = ''
            datacolor = ''
            datadown = ''
            try:
                #print "    myth_staus: reading in %s" %alert_file
                f=open(alert_file,'r')
                lines=f.readlines()
                f.close()
            except:
                #print "    myth_status: Couldn't open %s for reading" %alert_file
                continue
            
            for line in lines:
                try:
                    data,value=line.split(":")
                except:
                    continue  #exception occured try the next line
                
                if data == 'HOST':
                    datahost = value.strip()
                elif data == 'SERVICE':
                    dataservice = value.strip()
                elif data == 'COLOR':
                    datacolor = value.strip()
                elif data == 'DOWN':
                    datadown = value.strip()
                    sec=int(datadown)
                    td_sec = datetime.timedelta(seconds=sec)
                    td_sec_formated = formatTD(td_sec)
            
            out_line ="    %s on %s %s for %s \n" %(dataservice,
                                                           datahost,datacolor.upper(),
                                                           td_sec_formated)
            out_alert += out_line
                
        print "System Alerts:"
        print "--------------"
        if len(out_alert) > 0:
            print out_alert 
            print "    Go to http://%s and click Health & Maintenance for more information." %gethostname()
        else:
            print "    All systems OK"

    return 


#-------------------------------------------


class tuner_recording_status:
    def __init__ (self,num_upcoming):
        
        self.now = datetime.datetime.now()
        self.farout=99999999
        self.next_start_diff=datetime.timedelta(self.farout)
        self.num_upcoming=num_upcoming
        self.tuner_status_list=[]
        self.conflict_list=[]
        self.upcoming_list=[]
        self.ur=0
        self.db_connection_status = self.check_database_connection()
        if self.db_connection_status == 0:
            self.tuner_status()
            self.conflicts()
            self.upcoming_recordings()

    def get_db_check_status(self):
        return self.db_connection_status
        
    def check_database_connection(self):
        rc=0
        try:
            self.be = MythBE()
            self.db = MythDB()
            self.cursor = self.db.cursor()
        except:
            print "\nCouldn't connect to MythTV service for status"
            rc=1
        return rc
#-----
    def tuner_status(self):
        a=self.be.getRecorderList()
        for i in a:
            outline=''
            cmd="select cardtype,hostname  from capturecard where cardid=%s;" %i
            self.cursor.execute(cmd)
            results=self.cursor.fetchall()
            type = results[0][0]
            hostname = results[0][1]
            id = i
            try:
                c=self.be.getCurrentRecording(i)
                if c.title ==  None:
                    current_recording = "Idle"
                else:
                    current_recording = "Recording %s" %c.title
                outline = "    Tuner %s (%s) on %s : %s " %(id, type, hostname, current_recording)
                self.tuner_status_list.append(outline)
            except:
                outline = "    Tuner %s (%s) on %s : %s " %(id, type, hostname, "Tuner Error")
                self.tuner_status_list.append(outline)

    def get_tuner_status(self):
        return self.tuner_status
    
    def print_tuner_status(self):
        print "Tuner Status:"
        print "-------------"
        if len(self.tuner_status_list) > 0 :
            for line in self.tuner_status_list:
                print line
        else:
            print "    No tuners found"
            
#--------
    def upcoming_recordings(self):
        
        a=self.be.getUpcomingRecordings()
        r=0
        for i in a:
            r += 1
            if r > self.num_upcoming:
                break
            
            title_chan="%s (%s)" %(i.title, i.channame)
            #remove timezone
            start_time=re.split("[-+]\d\d:\d\d",str(i.starttime))[0]
            start_time_struct=datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")
            start_time_out=start_time_struct.strftime("%a %b %d %I:%M%p")
            self.upcoming_list.append([start_time_out,i.hostname, title_chan])
            #print "    %s - %s - %s" %(start_time_out,i.hostname, title_chan)
            diff = start_time_struct - self.now
            if diff < self.next_start_diff :
                self.next_start_diff = diff

        if self.next_start_diff == datetime.timedelta(self.farout):
            self.ur="No recordings are scheduled"
        else:
            self.ur=formatTD(self.next_start_diff)
            

    def get_upcoming_recordings(self):
        return self.upcoming_list
    
    def print_upcoming_recordings(self):
        #print self.get_upcoming_recordings()
        print ""
        print "Upcoming Recordings (Next %s Scheduled):" %(self.num_upcoming)
        print "----------------------------------------"
        if len(self.get_upcoming_recordings()) > 0:
            for i in self.get_upcoming_recordings():
                #print "    %s - %s - %s" %(start_time_out,i.hostname, title_chan)
                print "    %s - %s - %s" %(i[0],i[1],i[2])
        else:
            print "    No upcoming recordings"
        pass

    def get_next_start_time(self):
        return self.ur
    
    def print_next_start_time(self):
        print ""
        print "The next recording starts in:"
        print "-----------------------------"
        print "    %s" %(self.get_next_start_time())
        print ""
    
#-----

    def conflicts(self):
        a=self.be.getConflictedRecordings()
        for i in a:
            out_line=''
            title_chan="%s (%s)" %(i.title, i.channame)
            out_line=(i.starttime,title_chan)
            self.conflict_list.append(out_line)

    def get_conflict_list(self):
        return self.conflict_list
    
    def print_conflict_list(self):
        print ""
        print "Recording Conflicts:"
        print "--------------------"
        if len(self.get_conflict_list()) > 0:
            for i in self.get_conflict_list():
                print "    %s -  %-50s " %(i[0],i[1])
        else:
            print "    No conflicts"

#header="#"*60


def go():
    tuner = tuner_recording_status(12)
    if tuner.get_db_check_status() == 0:
        tuner.print_tuner_status()
        tuner.print_upcoming_recordings()
        tuner.print_conflict_list()
        tuner.print_next_start_time()
    print_alerts()


if __name__ == "__main__":
    go()