diff options
| author | Britney Fransen <brfransen@gmail.com> | 2023-02-12 04:53:27 (GMT) | 
|---|---|---|
| committer | Britney Fransen <brfransen@gmail.com> | 2023-02-12 04:53:27 (GMT) | 
| commit | e09439b06ef0ad8e3784b1a698596a561838a75c (patch) | |
| tree | f01055b420aa8f2319424c5f62d626cd75b8df37 /linhes | |
| parent | 7f2c55e380f909b1d551340e3f174672de507cc3 (diff) | |
| download | linhes_pkgbuild-e09439b06ef0ad8e3784b1a698596a561838a75c.zip linhes_pkgbuild-e09439b06ef0ad8e3784b1a698596a561838a75c.tar.gz linhes_pkgbuild-e09439b06ef0ad8e3784b1a698596a561838a75c.tar.bz2 | |
linhes-system: add lh_myth_status.py
myth_mtc.py: fix some paths
myth2videos: initial inclusion
myth2mkv & myth2mp3: change /myth paths
Diffstat (limited to 'linhes')
| -rwxr-xr-x | linhes/linhes-system/PKGBUILD | 16 | ||||
| -rwxr-xr-x | linhes/linhes-system/lh_myth_status.py | 271 | ||||
| -rwxr-xr-x | linhes/linhes-system/myth2mkv | 4 | ||||
| -rwxr-xr-x | linhes/linhes-system/myth2mp3 | 6 | ||||
| -rwxr-xr-x | linhes/linhes-system/myth2videos | 148 | ||||
| -rwxr-xr-x | linhes/linhes-system/myth_mtc.py | 4 | 
6 files changed, 435 insertions, 14 deletions
| diff --git a/linhes/linhes-system/PKGBUILD b/linhes/linhes-system/PKGBUILD index 88194ce..966184b 100755 --- a/linhes/linhes-system/PKGBUILD +++ b/linhes/linhes-system/PKGBUILD @@ -1,21 +1,21 @@  pkgname=linhes-system  pkgver=9.0.0 -pkgrel=42 +pkgrel=43  arch=('x86_64')  #install=$pkgname.install  pkgdesc="Everything that makes LinHES a system"  license=('GPL2') -depends=('cronie' 'dbus-python' 'dvb-firmware' 'flatpak' 'firefox' 'glances' 'kdialog' 'libnotify' +depends=('cronie' 'dbus-python' 'dvb-firmware' 'expect' 'flatpak' 'firefox' 'glances' 'kdialog' 'libnotify'           'logrotate' 'linhes-templates' 'linhes-theme' 'mlocate' 'ncdu'           'openssh' 'pacman-contrib' 'rsyslog' 'ttf-overlock' 'wget' 'x11vnc')  binfiles="add_storage.py balance_storage_groups.py empty_storage_groups.py remove_storage.py            checkXFSfrag.sh enableIRWake.sh idle.py lh_system_start.sh lh_notify-send -          lh_home_check.sh jobqueue_helper.py gen_lib_xml.py +          lh_home_check.sh lh_myth_status.py jobqueue_helper.py gen_lib_xml.py            diskspace.sh find_orphans.py optimize_mythdb.py myth_mtc.py            misc_recent_recordings.pl misc_status_config.py misc_status_info.sh            misc_upcoming_recordings.pl misc_which_recorder.pl            create_media_dirs.sh be_check.py -          myth2mkv myth2mp3 udev_link.sh" +          myth2mkv myth2mp3 myth2videos udev_link.sh"  source=($binfiles      'myth_mtc.cron' 'paccache.cron' 'flatpak_update.cron' 'xfs_defrag.cron'      'readme_is_xml' 'add_storage.readme' 'LinHES-release' 'lh_log_care.cron' @@ -33,12 +33,13 @@ sha256sums=('525bfe29b63d3ec5a17a32fa29745e24070020490c3f5b6dd6b03250348fb324'              '644414148e514e4a56d68959cb427ddde4129a961cbf09cd1a0a39129d58a0b1'              '6d4fb0ed1a5ed961b3a3884dce093118e50c2981a9cd5837d20abc5a6d4fd8aa'              '87875d9e5f5ce18208f419698ce69b6bcbcd08955a57a4a13940e715af58b787' +            '3b3d774701ee52054f6592258b98b9f18c3f7f9a93982ef07c7a3c7cf9445b82'              '91bdec992bb2c933e15625c181f2195c402060b879168ebf35944cb064c904b9'              '5cacfdd02833e5a3130d765573e772e6bd5030336ba86239c5e4db5ffa36fc69'              'ebdb3ee0212e0cc72526bb5e50a032573e1894acb7bf75617243b0b49aa1f8f2'              '4d006f0fe3b13e67de1b961d611e81911905a30d140849dfdb8e5c0dc4da2f7c'              'e371c6a289c68fe200d7da856c20a8c579efa23178f4d62235f7359d7f6e49a1' -            'd63ce11809600e77ff187eee3751a8635045ef14c6333f1584f5e35f15a679a1' +            '29bf341afcbd54ce9a040596fa6a86622bbfe08addad0c673f68661fb93642b4'              'd2d69b2bf6315bd37ff5f5b2f0cde8ab2fb89bae18f8796dc5208ffc1a9d743e'              'a3f8ba840853e4a189dd52520a6958f4030e1cc3391200a6aeef055fb469f0b4'              '1819085bd2c9106482c5f243b95fddf3dae69212330ab76cb493add5c26a45a4' @@ -46,8 +47,9 @@ sha256sums=('525bfe29b63d3ec5a17a32fa29745e24070020490c3f5b6dd6b03250348fb324'              '1d12a128a01dbf6327a80daab9edfdc57d393d02074d19c6a5bd54560cc6b0c0'              'bffcc13e4b480f720feb2b3c781bc4247c63303250c3d885022c699573d45a33'              '51093acab5e5a4de51a55f4bdf7b935f4f69edf3d84f1c37db710853ec95eca8' -            '9ea1b5583cd38f53bb79d9e4ccae91a028db0b6850162d7991b19122c564b9c9' -            'a81fdb81d8890e73b7891756623d536a133410ea43205b7152a295ad9ab8f3c9' +            'ad4ddabbc34d5e1b308ece33cabf91d750f44894c52a18325762dea026152973' +            'a961cfdc6f02b12fb445777dd2c144fed96306ca2f430cc8853ae307c759c1ad' +            'd8574104b75c6d41284488612ec5583c50a8dab438492fa42c47231add4cfc54'              '6bdbf593d3e1348d1a8f7c4c17cb2e893f7e18ae355daf978173e669cfe3be80'              '9e97b4d68c9e8988daacadd40f1de9f0b5945d870eba596a2ceb5e0c023fa9c0'              '186203d3c0520bb3d611da99d33a7713e9c1563814285f1f101097234f214b2f' diff --git a/linhes/linhes-system/lh_myth_status.py b/linhes/linhes-system/lh_myth_status.py new file mode 100755 index 0000000..ea8c6f2 --- /dev/null +++ b/linhes/linhes-system/lh_myth_status.py @@ -0,0 +1,271 @@ +#!/usr/bin/python +#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,pytz,re,socket,subprocess,sys,time +from dateutil.parser import parse +from tzlocal import get_localzone + +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(pytz.utc) +        self.currTZ = get_localzone() +        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,displayname  from capturecard where cardid=%s;" %i +            self.cursor.execute(cmd) +            results=self.cursor.fetchall() +            type = results[0][0] +            hostname = results[0][1] +            displayname = results[0][2] +            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 (%s) on %s : %s " %(id, displayname, type, hostname, current_recording) +                self.tuner_status_list.append(outline) +            except: +                outline = "    Tuner %s - %s (%s) on %s : %s " %(id, displayname, 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) +            # convert timezone to local timezone +            start_time=parse(str(i.starttime)) +            start_time=start_time.astimezone(self.currTZ) +            start_time_out=start_time.strftime("%a %b %d %I:%M%p") +            self.upcoming_list.append([start_time_out,i.hostname, title_chan]) + +            diff = start_time - 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) +            # convert timezone to local timezone +            start_time=parse(str(i.starttime)) +            start_time=start_time.astimezone(self.currTZ) +            start_time_out=start_time.strftime("%a %b %d %I:%M%p") +            out_line=(start_time_out,i.hostname,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 - %s - %s" %(i[0],i[1],i[2])) +        else: +            print("    No conflicts") + +#header="#"*60 + + +def go(): +    welcomeFile=open("/etc/LinHES-release", "r") +    print("Welcome to %s on %s\n" %(welcomeFile.readline().rstrip(), socket.gethostname())) +    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() diff --git a/linhes/linhes-system/myth2mkv b/linhes/linhes-system/myth2mkv index 51a0c9b..6edb804 100755 --- a/linhes/linhes-system/myth2mkv +++ b/linhes/linhes-system/myth2mkv @@ -31,12 +31,12 @@  #                      #  ######################## -OUTDIR=/myth/video +OUTDIR=/data/storage/disk0/media/video  LOGPATH=/var/log/mythtv  LOGFILE=${LOGPATH}/myth2mkv-$$.log  # TMPDIR is for large transient files -TMPDIR=/myth/tmp +TMPDIR=/data/storage/disk0/media/tmp  # x264 tuning:  # Tune x264 based on content. Valid options for TUNING are: diff --git a/linhes/linhes-system/myth2mp3 b/linhes/linhes-system/myth2mp3 index ebc588b..e5960be 100755 --- a/linhes/linhes-system/myth2mp3 +++ b/linhes/linhes-system/myth2mp3 @@ -16,12 +16,12 @@ BITRATE=256k		#ie. 128k, 160k, 192k, 224k, 256k  USECUTLIST=Y		#Y or N  # where the converted audio is stored -OUT_DIR=/myth/music +OUT_DIR=/data/storage/disk0/media/music  # create temp filename so multiple instances won't conflict  TMPNAME=toMP3-$$ -TMPFILE=/myth/tmp/$TMPNAME -TMPCUTFILE=/myth/tmp/$TMPNAME.mpg +TMPFILE=/data/storage/disk0/media/tmp/$TMPNAME +TMPCUTFILE=/data/storage/disk0/media/tmp/$TMPNAME.mpg  FFINPUTFILE=$1  TITLE=`echo $2 | sed 's/\//_/g'` diff --git a/linhes/linhes-system/myth2videos b/linhes/linhes-system/myth2videos new file mode 100755 index 0000000..c4d3246 --- /dev/null +++ b/linhes/linhes-system/myth2videos @@ -0,0 +1,148 @@ +#!/bin/sh +# copy recording to videos +# version 0.3 + +# usage: +# first parameter must be %DIR%/%FILE% of the recording +# second parameter must be the desired base name of the output +# third parameter must be %CHANID% if you set USECUTLIST=Y +# fourth parameter must be %STARTTIME% if you set USECUTLIST=Y +# fifth parameter must be %JOBID% for the User Job status to be updated in MythTV +# in the mythtv setup screen invoke this script like this: +# MYTHTV User Job Command: +# /usr/bin/myth2videos "%DIR%/%FILE%" "%TITLE% - %SUBTITLE%" "%CHANID%" "%STARTTIME%" "%JOBID%" + +# options: +USECUTLIST=Y		# Y or N + +# where the video is stored +OUT_DIR=/data/storage/disk0/media/video + + +#------FUNCTIONS--------------- +update_comment() +# Arg_1 = COMMENT +{ +if [ $NO_JOBID -eq 0 ]; then +    `jobqueue_helper.py -j ${JOBID} -cs "${1}"` +fi +} + +update_status() +# Arg_1 = status code +{ +if [ $NO_JOBID -eq 0 ]; then +    `jobqueue_helper.py -j ${JOBID} -cs "${1}"` +fi +} + +check_myth_jobcmds() +# check the myth database for stop pause or resume commands +{ +if [ $NO_JOBID -eq 0 ]; then +    CURRENT_CMD=`jobqueue_helper.py -m "select cmds from jobqueue where id = ${JOBID}"` +    case "$CURRENT_CMD" in +	# JOB_RUN +	0) ;; +	# JOB_PAUSE +    1) `jobqueue_helper.py -j ${JOBID} -ss 6`;; +	# JOB_RESUME +    2) `jobqueue_helper.py -j ${JOBID} -ss 4` +       `jobqueue_helper.py -j ${JOBID} -cmds 0`;; +	# JOB_STOP +    4) `jobqueue_helper.py -j ${JOBID} -ss 5` +       `jobqueue_helper.py -j ${JOBID} -cmds 0` +       clean_up_files +       echo "Copy Cancelled" >> $LOGFILE +       `jobqueue_helper.py -j ${JOBID} -ss 320` + 	   exit ;; +    esac +fi +} + +clean_up_files() +# clean up left over files +{ +unlink $TMPFILE 2> /dev/null +unlink $TMPFILE.map 2> /dev/null +} + +#-------MAIN SCRIPT------------ + +# check if %JOBID% is passed from command line +JOBID=${5} +if [ -z "$JOBID" ]; then +    NO_JOBID=1 +else +    NO_JOBID=0 +fi + +# create temp filename so multiple instances won't conflict +TMPNAME=toVIDEOS-$$ +TMPFILE=/data/storage/disk0/media/tmp/$TMPNAME.mpg +MENINPUTFILE=$1 +TITLE=`echo $2 | sed 's/\//_/g'` + +# log file location +LOGFILE=/var/log/mythtv/myth2videos.log +CDate="`date`" +echo "" >> $LOGFILE +echo $CDate >> $LOGFILE +echo "File to copy: $MENINPUTFILE     Name: $TITLE" >> $LOGFILE +echo "$2   $3   $4   $5" >> $LOGFILE + +# start timer +beforetime="$(date +%s)" + +check_myth_jobcmds + +# check if using cutlist +if [ $USECUTLIST = Y ]; then +    MYTHCOMMFRAMES=`mythutil --getcutlist --chanid "$3" --starttime "$4" | grep 'Cutlist:' | cut -d \  -f 2` +    echo $MYTHCOMMFRAMES +    if [ -n "$MYTHCOMMFRAMES" ]; then +        echo "Extracting Cutlist..." >> $LOGFILE +        update_comment "Extracting Cutlist..." +        /usr/bin/nice -n19 /usr/bin/mythtranscode --chanid "$3" --starttime "$4" --outfile "$TMPFILE" --mpeg2 --honorcutlist +    else +        update_comment "Copying Recording..." +        cp "$MENINPUTFILE" "$TMPFILE" +    fi +elif [ $USECUTLIST = N ]; then +    update_comment "Copying Recording..." +    cp "$MENINPUTFILE" "$TMPFILE" +fi + +# make output filename unique +OUTPUTFILE=$OUT_DIR/$TITLE.mpg +i=1 +while [ -e "$OUTPUTFILE" ] +do +    OUTPUTFILE=$OUT_DIR/$TITLE-$i.mpg +    i=`expr $i + 1` +done + +# move temp file to output location +chown mythtv "$TMPFILE" && mv "$TMPFILE" "$OUTPUTFILE" + +# stop timer +aftertime="$(date +%s)" +seconds="$(expr $aftertime - $beforetime)" + +ERROR=$? +if [ $ERROR -eq 0 ]; then +    echo "File Encoded Successfully: $OUTPUTFILE" >> $LOGFILE +    hours=$((seconds / 3600)) +    seconds=$((seconds % 3600)) +    minutes=$((seconds / 60)) +    seconds=$((seconds % 60)) +    echo "Encoding took $hours hour(s) $minutes minute(s) $seconds second(s) @ $current_FPS fps." >> $LOGFILE +    update_status 272 +    update_comment "Encode Successful. Encoding Time: $hours hour(s) $minutes minute(s) $seconds second(s)" +else +    update_status 304 +    update_comment "Encode Failed.  Exit status: $ERROR" +    echo "ERROR: $ERROR" >> $LOGFILE +fi + +clean_up_files diff --git a/linhes/linhes-system/myth_mtc.py b/linhes/linhes-system/myth_mtc.py index 953fb96..3cfbfb1 100755 --- a/linhes/linhes-system/myth_mtc.py +++ b/linhes/linhes-system/myth_mtc.py @@ -81,7 +81,7 @@ def cleanup_inuseprograms():  def bail_if_another_is_running():      cmd = shlex.split("pgrep -u {} -f {}".format(os.getuid(), __file__)) -    pids = subprocess.check_output(cmd).strip().split('\n') +    pids = subprocess.check_output(cmd).decode('utf-8').strip().split('\n')      if len(pids) > 1:          pids.remove("{}".format(os.getpid()))          print("Exiting! Found {} is already running (pids): {}".format( @@ -100,7 +100,7 @@ def run_stuff():          print("No system idle check will be done.")          idle = 0      else: -        idle = subprocess.call(["/usr/bin/python2", "/usr/LH/bin/idle.py"]) +        idle = subprocess.call(["/usr/bin/python", "/usr/bin/idle.py"])      if not idle:          if ("--check_home" in sys.argv) or runall: | 
