MythSExx

From XBMC
Revision as of 19:16, 12 December 2009 by Outleradam (Talk)

Jump to: navigation, search

This page is under construction


MythSExx allows you to export your dynamic MythTV library into XBMC or Boxee while leaving MythTV in control of the files.


Key features:

  • MythTV recordings renamed to Show name.SxxExx (episode title).ext
  • Symlinks allow MythTV to maintain your library. Symlink from new file in place of old. Symlink to original.
  • TvDb recognition of Show Name and Episode Name
  • Fuzzy logic episode name matching allows for improperly named episodes
  • User defined show name translations for improper guide data
  • User is notified at the end of each operation
  • Dynamic mount support with alternate move dir
  • Failsafe Symlink mode
  • easy to troubleshoot permission errors and other problems in debug mode
  • Can be run as MythTV job.
/home/mythtv/MythSExx/MythSExx.sh  "%TITLE%" "%SUBTITLE%" "%DIR%/%FILE%"

in progress:

  • multiple shows in single recordings (currently handled by clipping second name)
  • optional movie support

Contents

1 MythSExx

The following instructions are meant as a guide to help you install MythSExx.

1.1 set up dependencies

The following packages are required 1. curl 2. agrep 3. optionally:libnotify-bin

  • Install the dependencies by opening a terminal and typing the following
apt-get install curl agrep 
  • optional for Ubuntu GNOME Desktop notification.
apt-get install libnotify-bin


1.2 set up MythSExx

The following are suggestions for the average user, installation can be performed in many ways according to your desired setup.

  • Create a working folder for MythSExx to place it's files
mkdir /home/mythtv/MythSExx
  • Create a Videos folder for MythTV to deposit it's recordings
mkdir /home/mythtv/Videos
  • Create a shared folder
mkdir /home/mythtv/Shared
  • Share your shared folder by right clicking on the folder then click properties, click share and then follow instructions given
  • Create the following file and set the user settings in the file.

Filename: /home/mythtv/MythSExx/MythSExx.sh

#!/bin/bash

#MythSExx by Adam Outler
#email: outleradam@hotmail.com
#Software the way it should be: Free and Open Source
#Please contact me with any bug reports

#Intention:
# This program was designed to be a user job in MythTV.  It can be called by creating a user job.
# The user job can be called as follows:
# /home/mythtv/MythSExx/MythSExx.sh  "%TITLE%" "%SUBTITLE%" "%DIR%/%FILE%"
#
#Usage:
# MythSExx.sh -v "show name" "episode name" "Target Folder"
# eg. MythSExx.sh "South Park" "Here Comes the Neighborhood" "/home/mythrecordings/2308320472023429837.mpg"
#  
#Output:
# If an error occurs and the file cannot be moved, then no change will occur to the original file. If the Movedir
# is full or not available, such as when running a NAS and the computer is disconnected from the network, the 
# AlternateMoveDir will be used. If both of these dirs fail, the show will be SymLinked in the FailSafeDir.
# You may elect to run the user job at a later time when the issue has been resolved.  Output dir will depend 
# on user settings. The file name however, is preset to the most acceptable standard:
#   Show Title - SxxExx (Episode Title).ext
#
#Symlinking:
# When Symlinking is enabled, MythSExx will follow it's normal mode of operation.  In MOVE mode, MythSExx will
# Create a symlink from the new file in the same name and location of the old file.  In LINK mode, MythSExx will 
# not move the file, LINK mode creates a new symlink to the original file. 
#
#Logging:
# Log file will show information for troubleshooting. You can find the log file in the working folder
# Log file default location: /home/$username/MythSExx
#
#Dependencies: depends on "Curl" and "agrep" and "libnotify-bin"
# install curl with "apt-get install curl"  
# install agrep with "apt-get install agrep"
# optional: install libnotify-bin with "apt-get install libnotify-bin" 
#
#Show Name Translation
# The user may elect to create a file in the MythSExx/ working folder which will then translate any recorded
# show name into the desired show name.  This is useful for adding a year to distinguish between a new series
# and an older series and/or typos in your guide data.  By default it should be called "showtranslations" and
# by default it will be in your home/username/MythSExx folder.  showtranslations is not needed by most users
# and the file should only be created if it is needed. Under most circumstances, the integrated fuzzy logic 
# will be sufficient to translate the guide name to the TvDb name, however showtranslations is available to 
# improve accuracy to 100%. The format of showtranslations is as follows:
#Filename: /$MythSExx/showtranslations
##############################################################
#My Guide Show Title = www.TheTvDb.com Show Title            #
#Battlestar Gallactica = Battlestar Gallactica (2003)        # 
#Millionaire = Who Wants To Be A Millionaire                 #
#Aqua teen Hungerforce = Aqua Teen Hunger Force              #
##############################################################


#######################USER SETTINGS##########################
#MoveDir is the folder which MythSExx will move the file.  No trailing / is accepted eg. "~/videos"
MoveDir="/home/mythtv/NAS/Video/shows"
#AlternateMoveDir will act as a seccondary MoveDir if the primary MoveDir fails.
AlternateMoveDir="/home/mythtv/Shared"
#Disable moving of files.  If UseOriginalDir is Enabled, original dir will override MoveDir.  This can be useful for multiple recording dirs   Enabled|Disabled
UseOriginalDir=Disabled
#When Enabled, MythSExx will move the file to a folder of the same name as the show. This is not affected by UseOriginalDir. Enabled|Disabled
UseShowNameAsDir=Enabled
#SYMLINK has 3 modes.  MOVE|LINK|Disabled
#Create symlink in original dir from file after MOVE, Create symlink in MoveDir LINK original(overrides moving), Simlinking Disabled 
SYMLINK=MOVE
#Internet access Timeout in seconds: Default Timeout=50 
Timeout=50 
#MythSExx working file dir: Default is "~/MythSExx" 
MythSExx=~/MythSExx
#FailSafe mode will enable symlinks to be formed in FailSafeDir if the move or symlink operation fails.
FailSafeMode=Enabled
#FailSafeDir is used when the file cannot be moved to the MoveDir. FailSafe will not create folders.
FailSafeDir=~/Shared
#The following line tells MythSExx to send a notification upon completion. Enabled|Disabled
Notify=Enabled
#If notifications are enabled, NotifyUserName should be the same as the user logged into the GNOME Session.
NotifyUserName="adam"
#the following line contains the API key from www.TheTvDb.Com. Default: 6DF511BB2A64E0E9
APIkey="6DF511BB2A64E0E9"
#Enables debug mode.  This is a verbose mode of logging which should be used for troubleshooting.  Enabled|Disabled
DEBUGMODE=Disabled
#MovieSort will make a determination if a show is a series or a movie.
MovieSort=Enabled
#If MovieSort is enabled, MovieDir will move the movie to a separate dir
MovieDir=~/Movies
#AlternateMovieDir is a backup for MovieDir. 
AlternateMovieDir=~/movies
#########################USER SETTINGS########################## 

###############################################################
################Do not modify below this line##################
###############################################################
echo "@@@@@@@@@@NEW SEARCH INITIATED AT `date`@@@@@@@@@@@@@">>$MythSExx/output.log 

#####DEFINE ENVIRONMENT AND VARIABLES#####
#make our working dir if it does not exist
if [ ! -d "$MythSExx" ]; then 
	mkdir $MythSExx
	echo "creating home/MythSExx and log file">>$MythSExx/output.log
fi

#Set episode name, dir, extension, and showname from the input parameters.
ShowName=$1
epn=`echo $2|sed 's/;.*//'|tr -d [:punct:]`
originalext=`echo "${3#*.}"`
originaldirname=`dirname "$3"`

#Check for show translations relating to the show in question.
if [ -f $MythSExx/showtranslations ]; then 
	showtranslation=`grep "$ShowName = " "$MythSExx/showtranslations"|replace "$ShowName = " ""|replace "$MythSExx/showtranslations" ""`		 
	if [ "$showtranslation" != "$null" ];then 
		ShowName=$showtranslation
		echo "USER TRANSLATION: $1 = $ShowName">>$MythSExx/output.log
	elif [ "$showtranslation" = "$null" ];then
		$showtranslation = "Inactive"
	fi
fi

if [ $UseOriginalDir = "Enabled" ]; then
	MoveDir=`echo "$originaldirname"`
fi

#####SEARCH FOR SHOW NAME#####
echo "SEARCHING: www.TheTvDb.com SHOW NAME: $ShowName EPISODE: $epn">>$MythSExx/output.log
echo "FILE NAME: $3">>$MythSExx/output.log
#download series info for show, parse into temporary text db- sid.txt shn.txt
tvdbshowname=`echo $ShowName|replace " " "%20"`

curl -s -m"$Timeout" www.thetvdb.com/api/GetSeries.php?seriesname=$tvdbshowname>$MythSExx/working.xml
cat $MythSExx/working.xml | grep "<seriesid>"|replace "<seriesid>" ""|replace "</seriesid>" "">$MythSExx/sid.txt
cat $MythSExx/working.xml | grep "<SeriesName>"|replace "<SeriesName>" ""|replace "</SeriesName>" "">$MythSExx/shn.txt

#Use fuzzy logic to make the best match of the show name
serieslinenumber=`agrep -Byn "${showname:0:29}" $MythSExx/shn.txt|sed 's/:.*//'|grep -m1 ^`

#Get the seriesid based on the showname
seriesid=`sed -n $serieslinenumber'p' $MythSExx/sid.txt|grep -m1 ^`
NewShowName=`sed -n $serieslinenumber'p' $MythSExx/shn.txt|grep -m1 ^`

#Create folder for database if it does not exist
if [ ! -d "$MythSExx/$NewShowName" ]; then
	mkdir $MythSExx/"$NewShowName"
	echo "creating home MythSExx and log file">>MythSExx/output.log
fi
	echo "SEARCH FOUND:""$NewShowName" "ID#:" $seriesid >>/$MythSExx/output.log

#If series ID is obtained, then get show information.
if [ "$seriesid" != "" ]; then

#####GET SHOW INFORMATION#####
#Strip XML tags
	seriesid=`echo $seriesid|tr -d "<seriesid>"|tr -d "</seriesid>"`

#download series info for series id
	curl -s -m"$Timeout" "http://www.thetvdb.com/api/$APIkey/series/$seriesid/all/en.xml">$MythSExx"/$NewShowName/$NewShowName.xml"

#create a folder/file "database" Strip XML tags.  Series, Exx and Sxx are separated into different files
	if [ -f "$MythSExx/$NewShowName/$NewShowName.xml" ]; then 
		cat "$MythSExx/$NewShowName/$NewShowName.xml" | grep "<EpisodeName>"|replace "  <EpisodeName>" ""|replace "</EpisodeName>" ""|replace "/" "">$MythSExx/"$NewShowName"/"$NewShowName".Ename.txt
		cat $MythSExx/"$NewShowName"/"$NewShowName".xml | grep "<SeasonNumber>"|replace "<SeasonNumber>" ""|replace "</SeasonNumber>" ""|replace " " "">$MythSExx/"$NewShowName"/"$NewShowName".S.txt
		cat $MythSExx/"$NewShowName"/"$NewShowName".xml | grep "<EpisodeNumber>"|replace "<EpisodeNumber>" ""|replace "</EpisodeNumber>" ""|replace " " "">$MythSExx/"$NewShowName"/"$NewShowName".E.txt
	elif [ ! -f "$MythSExx/$NewShowName/$NewShowName.xml" ]; then
		echo "***FAILURE: curl -s -m$Timeout http://www.thetvdb.com/api/$APIkey/series/$seriesid/all/en.xml">>$MythSExx/output.log
	fi

#check if files were created and generate message
	if [ -f $MythSExx/"$NewShowName"/"$NewShowName".Ename.txt ]; then
		echo "LOCAL DATABASE UPDATED:$MythSExx/$NewShowName">>$MythSExx/output.log
	elif [ ! -f "$MythSExx/$NewShowName/$NewShowName.Ename.txt" ]; then
		echo "*** PERMISSION ERROR $MythSExx/$NewShowName/">>$MythSExx/output.log
	fi


#####PROCESS SHOW INFORMATION#####
#grep use fuzzy logic to find the closest show name from the locally created database and return absolute episode number
	absolouteEpisodeNumber=`agrep -Byn "${epn:0:29}" "$MythSExx""/""$NewShowName""/""$NewShowName"".Ename.txt"|grep -m1 ^|sed 's/:.*//'`
	echo DEFINED ABSOLOUTE EPISODE NUMBER: $absolouteEpisodeNumber>>$MythSExx/output.log

#if line match is obtained, then gather Sxx and Exx
	if [ "$absolouteEpisodeNumber" !=  ""  ]; then
		epn=`sed -n $absolouteEpisodeNumber'p' $MythSExx/"$NewShowName"/"$NewShowName".Ename.txt|sed 's/;.*//'`
		echo "Found Match: $epn $absolouteEpisodeNumber"
#gather series and episode names from files created earlier.
		exx=`sed -n $absolouteEpisodeNumber'p' $MythSExx/"$NewShowName"/"$NewShowName".E.txt`
		sxx=`sed -n $absolouteEpisodeNumber'p' $MythSExx/"$NewShowName"/"$NewShowName".S.txt`

# Single digit episode and show names are not allowed Ex and Sx replaced with Exx Sxx
		if [ "$exx" -lt 10 ]; then 
			exx=`echo E0$exx`
		elif [ "$exx" -gt 9 ]; then 
			exx=`echo E$exx`
		fi
		if [ "$sxx" -lt 10 ]; then 
			sxx=`echo S0$sxx`
		elif [ "$sxx" -gt 9 ]; then 
			sxx=`echo S$sxx`
		fi
	fi

#if series id is not obtained
	elif [ "$seriesid" == "" ]; then 
 	echo "series was not found the tvdb may be down try renaming $1">>$MythSExx/output.log
fi
#####OUTPUT#####
if [ $DEBUGMODE = "Enabled" ]; then
	echo "#########################################################">>$MythSExx/output.log
	echo "###################DEBUG MODE ENABLED####################">>$MythSExx/output.log
	echo "#########################################################">>$MythSExx/output.log
	echo "LISTING INTERNAL VARIABLES USED BY MythSExx. VERIFY THESE ARE NOT EFFECTED BY GLOBAL VARIABLES">>$MythSExx/output.log
	echo "INTERNET TIMEOUT:$Timeout- TvDb API KEY:$APIkey- MythSExx WORKING DIR:$MythSExx-">>$MythSExx/output.log
	echo "MOVE DIR:$MoveDir- USING SHOWNAME AS FOLDER:UseShowNameAsDir-">>$MythSExx/output.log
	echo "FAILSAFE MODE:$FailSafe- FAILSAFE DIR:$FailSafeDir- ALTERNATE MOVE DIR:$AlternateMoveDir-"
	echo "USE ORIGINAL DIR:$UseOriginalDir NOTIFICATIONS:$Notify DEBUG MODE:$DEBUGMODE-">>$MythSExx/output.log
	echo "INPUT SHOW NAME:$1- LOCAL SHOW NAME TRANSLATION:$showtranslation- SENT TVDB SHOW NAME:$tvdbshowname-">>$MythSExx/output.log
	echo "RESOLVED SERIES ID:$seriesid- RESOVED SHOW NAME:$ShowName-">>$MythSExx/output.log
	echo "INPUT EPISODE NAME:$2- ABSOLOUTE EPISODE NUMBER:$absolouteEpisodeNumber- RESOLVED EPISODE NAME:$epn-">>$MythSExx/output.log
	echo "SEASON:$sxx- EPISODE:$exx-">>$MythSExx/output.log
	echo "##############LISTING FOLDER PERMISSIONS#################">>$MythSExx/output.log
	echo "ORIGIONAL FILE>ls -l $3">>$MythSExx/output.log
	ls -l "$3">>$MythSExx/output.log
	echo "MythSExx WORKING DIR>lsmod -l $MythSExx/$NewShowName/">>$MythSExx/output.log
	ls -l "$MythSExx/$NewShowName/">>$MythSExx/output.log
	echo "MOVE DIR>lsmod -l $MoveDir/">>$MythSExx/output.log
	ls -l $MoveDir>>$MythSExx/output.log
	echo "ALTERNATE MOVE DIR> ls -l $AlternateMoveDir">>$MythSExx/output.log
	ls -l "$AlternateMoveDir/">>$MythSExx/output.log
	echo "#########################################################">>$MythSExx/output.log
	echo "####################END OF DEBUG LOG#####################">>$MythSExx/output.log
	echo "#########################################################">>$MythSExx/output.log
fi


#output format  showname=show name sxx=season number exx=episode number epn=episode name
ShowFileName=`echo "$NewShowName.$sxx$exx ($epn)"`

#check to see if episode information was obtained
if [ "$exx" != "" ]; then
#check to see if output folder exists
	if [ -d $MoveDir ]; then
		echo RESOLVED EPISODE INFORMATION: "$NewShowName: $epn = $sxx$exx">>$MythSExx/output.log
#If specified, make $movedir = $movedir/show name
		if [ "$UseShowNameAsDir" = "Enabled" ]; then
			MoveDir=`echo "$MoveDir"/"$NewShowName"`
#Make the folder if it does not exist
			if [ -d "$MoveDir" ]; then
				echo "VERIFIED FOLDER: $MoveDir">>$MythSExx/output.log
			elif [ ! -d "$MoveDir" ]; then
				echo "CREATING FOLDER: $MoveDir">>$MythSExx/output.log
				mkdir "$MoveDir"
#Error message if folder was not created
				if [ ! -d "$MoveDir" ];then
					echo "******PERMISSION ERROR COULD NOT CREATE $MoveDir/$NewShowName">>$MythSExx/output.log
			fi
		fi		
	fi
fi

#If file to be moved does not exist, then explain why	
if [ ! -f "$3" ]; then
	echo "****** INPUT FILE NAME NON EXISTANT CHECK INPUT FORMAT">>$MythSExx/output.log
fi

#If File exists, loop and add -$MythSExxCounter to the end of the file name
if [ -f "$MoveDir/$ShowFileName.$originalext" ]; then
	MythSExxCounter=0
	NameCheck="0"
	while [ $NameCheck = "0" ]; do
		let MythSExxCounter=$MythSExxCounter+1			

		if [ ! -f "$MoveDir/$ShowFileName-$MythSExxCounter.$originalext" ];then
			NameCheck="1"
			ShowFileName=`echo "$ShowFileName-$MythSExxCounter"`
		fi
	done
fi

#If symlink is not in LINK mode, Move and rename the file.
if [ $SYMLINK != "LINK" ]; then
	mv "$3" "$MoveDir/$ShowFileName.$originalext"

#Alternate Move dir used if original move dir does not work
	if [ ! -f "$MoveDir/$ShowFileName.$originalext" ]; then
		MoveDir=$AlternateMoveDir
		echo "COULD NOT CREATE FILE. USING ALTERNATE MOVE DIR: $AlternateMoveDir"
		mv "$3" "$MoveDir/$ShowFileName.$originalext"
	fi		
#If symlink is in LINK mode then create symlink
elif [ $SYMLINK = "LINK" ]; then
	ln -s "$3" "$MoveDir/$ShowFileName.$originalext"
fi 

#Check and report if file was moved
if [ -f "$MoveDir/$ShowFileName.$originalext" ]; then
	echo "@@@@@@@@@@@@@OPERATION COMPLETE" `date` "@@@@@@@@@@@@@@@">>$MythSExx/output.log
	if [ $SYMLINK = "MOVE" ]; then
		ln -s "$MoveDir/$ShowFileName.$originalext" "$3"
	fi
#send notification if enabled
 	if [ $Notify = "Enabled" ]; then
	sudo -u "$NotifyUserName" /usr/local/bin/alt-notify-send "MythSExx Sucess" "$ShowFileName moved to $MoveDir" info
	fi
	exit 0
#Failsafe mode. Failsafe will create a symlink.  Failsafe is always a operation failure.
elif [ ! -f "$MoveDir/$ShowFileName.$originalext" ]; then
	echo "ATTEMPTED MOVE:$3">>$MythSExx/output.log
	echo "TO:$MoveDir/$ShowFileName.$originalext">>$MythSExx/output.log
	echo "PERMISSION ERROR OR DRIVE FULL">>$MythSExx/output.log	
	if [ FailSafeMode = "Enabled" ]; then
		echo "ATTEMPTING SYMLINK TO FAILSAFE DIR: $FailSafeDir">>$MythSExx/output.log
		ln -s "$3" "$FailSafeDir/$ShowFileName.$originalext"
		if [ -f "$FailSafeDir/$ShowFileName.$originalext" ]; then
			echo "FAILSAFE MODE COMPLETE: SYMLINK CREATED">>$MythSExx/output.log
		fi
		if [ ! -f "$FailSafeDir/$ShowFileName.$originalext" ]; then
			echo "FAILSAFE MODE FAILURE CHECK PERMISSIONS IN $FailSafeDir">>$MythSExx/output.log
		fi
	fi
	echo "%%%%%%%%%%%%%OPERATION FAILURE" `date` "%%%%%%%%%%%%%%%%%">>$MythSExx/output.log
#send notification if enabled
  	if [ $Notify = "Enabled" ]; then
	sudo -u "$NotifyUserName" /usr/local/bin/alt-notify-send "MythSExx Error" "Error moving $3 to $MoveDir/$ShowFileName" error
	exit 1
	fi
fi

#If move dir dosn't exist, then outpt it in the log
	elif [ ! -d $MoveDir ]; then
		echo "OUTPUT FOLDER $MoveDir DOES NOT EXIST">>$MythSExx/output.log
		echo "failure" `date`

#Log error if problem exists
echo mv "$3" "$MoveDir/$ShowFileName"
elif [ "$exx" = "" ]; then
	echo "NO MATCH FOUND.  TROUBLESHOOTING: Check www.TheTvDb TO SEE IF $1 EXISTS. ">>$MythSExx/output.log
	echo "CHECK $2. CHECK INTERNET CONNECTION. CHECK API KEY.">>$MythSExx/output.log
	echo "CHECK www.TheTvDb.com  RUN MythSExx LINK COMMAND PROMPT. FOR MORE INFORMATION SEE http://wiki.xbmc.org/index.php?title=MythSExx">>$MythSExx/output.log
	echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
#send notification if enabled
  	if [ $Notify = Enabled ]; then
	sudo -u "$NotifyUserName" /usr/local/bin/alt-notify-send "MythSExx error" "MythSExx Move operation failed See $MythSExx/output.log for more information" error
	fi
	exit 1 
fi


  • Make MythSExx Executable
sudo chmod +x /home/mythtv/MythSExx/MythSExx.sh

2 creating a rotating MythSExx library

The following is instructions for setting a dynamic library for XBMC

2.1 MythTV Settings

  • Click System/Administration MythTV Baclend setup
  • Select "1. General" then select next until you get to screen 3
  • Check "Follow symbolic links when deleting files".
  • Select next until you get to screen 8
  • Check "Allow user job #1 Jobs"
  • Select next until you get to screen 10
UserJob #1 Description: MythSExx
User Job #1 Command: /home/mythtv/MythSExx/MythSExx.sh  "%TITLE%" "%SUBTITLE%" "%DIR%/%FILE%"
  • Select Finish to exit
  • Select 6. Storage Directories
  • Select Default
  • Add a recording folder to which MythTV has access ie. /home/mythtv/Videos
  • Add additional folders if required.
  • Remove folders to which MythTV cannot run move jobs such as /lib or /var

2.2 XBMC Settings =

XBMC can update itself on start up.

  • Check the option to update your library under Settings-Video you will find a option to scan the library on startup.


3 Enabling Notifications

Notifications will occour at the end of every operation conducted by MythSExx. Notifications will let you know when it is time to update your XBMC Library.

3.1 Installing notify-send

Libnotify-bin contains the file which allows the terminal to send commands to the GNOME desktop.

  • open a terminal
apt-get install libnotify-bin


3.2 Setting permissions

The following procedure is a security risk. Unless a better way is found, this is the only way to enable permissions to be set for mythtv to send a user notification. The user mythtv will have access to the sudo command without password.

  • type the following
gedit /etc/group
  • add the following line to the end of /etc/group
mythtvall:x:9389:mythtv
  • type the following
visudo
  • add the following line to visudo
%mythtvall ALL=(ALL) NOPASSWD:ALL
  • write out and quit

3.3 Enable Send to GNOME

To enable notifications to be sent to the desktop from a different user, you will need to use the alt-notify-send script.

  • place the following script in /usr/local/bin/

filename: alt-notify-send

#!/bin/bash
user=`whoami`
pids=`pgrep -u $user gnome-session`
title=$1
text=$2
timeout=$3

if [ -z "$title" ]; then
        echo You need to give me a title >&2
        exit 1
fi
if [ -z "$text" ]; then
         text=$title
fi
if [ -z "$timeout" ]; then
        timeout=60000
fi 

for pid in $pids; do
        # find DBUS session bus for this session
        DBUS_SESSION_BUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS \
                /proc/$pid/environ | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//'`
        # use it
        DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \
        notify-send -u low -i $4 $timeout "$title" "$text"
done
  • Make it executable
sudo chmod +x /usr/local/bin/alt-notify-send
Personal tools
Namespaces

Variants
Actions
Navigation
Wiki help
Toolbox