summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBritney Fransen <brfransen@gmail.com>2023-02-12 04:53:27 (GMT)
committerBritney Fransen <brfransen@gmail.com>2023-02-12 04:53:27 (GMT)
commite09439b06ef0ad8e3784b1a698596a561838a75c (patch)
treef01055b420aa8f2319424c5f62d626cd75b8df37
parent7f2c55e380f909b1d551340e3f174672de507cc3 (diff)
downloadlinhes_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
-rwxr-xr-xlinhes/linhes-system/PKGBUILD16
-rwxr-xr-xlinhes/linhes-system/lh_myth_status.py271
-rwxr-xr-xlinhes/linhes-system/myth2mkv4
-rwxr-xr-xlinhes/linhes-system/myth2mp36
-rwxr-xr-xlinhes/linhes-system/myth2videos148
-rwxr-xr-xlinhes/linhes-system/myth_mtc.py4
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: