' Gambas class file PUBLIC sPathInfo AS String = "/var/tmp/update-watch-info." & System.User.Id PRIVATE sPathRpm AS String = "/var/lib/rpm/Packages" PRIVATE sPathApt AS String = "/var/lib/update-watch/run-apt-update" PRIVATE dtInfo AS Date ' hold last modified date of sPathInfo PRIVATE dtRpm AS Date ' hold last modified date of sPathRpm PRIVATE dtApt AS Date ' hold last modified date of sPathApt PRIVATE dtInfoPrev AS Date ' hold previous date of dtInfo to reduce info file access PRIVATE sTip AS String ' hold tray icon's tooltip. *Note: not set temporary (warnig or error) text here PRIVATE bReboot AS Boolean = FALSE ' set TRUE if deciede that reboot is required PRIVATE bNotify AS Boolean = FALSE ' set TRUE if notification pop up is required PRIVATE iNew AS Integer ' hold num of packages by status PRIVATE iUpgrade AS Integer ' PRIVATE iRemove AS Integer ' PRIVATE iHold AS Integer ' PRIVATE iDuplicate AS Integer ' PUBLIC SUB tmTimer_Timer() DIM hUpdateInfo AS File ' handler to read update-watch-info file DIM sLine AS String ' stop timer wihle processing to avoid error tmTimer.Stop ' get lastmodified date or set oldest(0) date if sPathInfo file is not exist. ' (and also it will be created later) IF Exist(sPathInfo) = TRUE THEN dtInfo = Stat(sPathInfo).LastModified ELSE dtInfo = 0 ENDIF IF Exist("/var/run/reboot-required") = TRUE THEN SetNotification("REBOOT") ELSE IF IsSynAptRunning() = FALSE THEN ' avoid nuisance duplicate messae while long running transaction IF CheckModified() = TRUE THEN SHELL "apt-get script --simulate /usr/lib/update-watch/check-upgrades.lua > /dev/null 2>&1" WAIT dtInfo = Stat(sPathInfo).LastModified ENDIF ENDIF IF Stat(sPathInfo).Size > 0 THEN IF dtInfo <> dtInfoPrev THEN ' read update-watch-info file if any updates exist and the file is updated iNew = 0 iUpgrade = 0 iRemove = 0 iHold = 0 iDuplicate = 0 hUpdateInfo = OPEN sPathInfo FOR READ WHILE NOT Eof(hUpdateInfo) LINE INPUT #hUpdateInfo, sLine SELECT CASE Split(sLine, ":")[0] CASE "new" iNew += 1 CASE "upgrade" iUpgrade += 1 CASE "remove" iRemove += 1 CASE "hold" iHold += 1 CASE "duplicate" iDuplicate += 1 END SELECT WEND ' show notification popup bNotify = TRUE dtInfoPrev = dtInfo ENDIF IF iDuplicate > 0 THEN SetNotification("DUPLICATE") ELSE SetNotification("UPDATE") ENDIF ELSE SetNotification("NOUPDATE") ENDIF ENDIF IsSynAptRunning() tmTimer.Start END PUBLIC SUB tiTrayIcon_Menu() ' show context menu when tray icon is right clicked ' and disable menu items if apt-get or synaptic is running IsSynAptRunning() hMenu.Popup() END PUBLIC SUB hMenuApply_Click() ' run synaptic to exec dist-upgrade only if apt-get or synaptic is not running IF IsSynAptRunning() = FALSE THEN SHELL "gksu -D synaptic \"synaptic --upgrade-mode --non-interactive --hide-main-window\" > /dev/null 2>&1" END PUBLIC SUB hMenuCheck_Click() ' run synaptic to exec apt-get update only if apt-get or synaptic is not running. ' also execute update-watch.lua script to update run-apt-update file ' because synaptic does not handle Script::AptGet::Update::Post script slot. IF IsSynAptRunning() = FALSE THEN ' should use external shell script when executing multiple commands via gusu. ' (gksu accepts only one command when running under root or using sudo for authentification.) ' and SHELL "gksu -D synaptic /usr/lib/update-watch/apt-update.sh > /dev/null 2>&1" ENDIF END PUBLIC SUB hMenuShow_Click() ' show list of updates FList.Show() END PUBLIC SUB hMenuRun_Click() ' run synaptic only if apt-get or synaptic is not running IF IsSynAptRunning() = FALSE THEN IF iDuplicate >= 1 THEN SHELL "gksu -D synaptic \"synaptic -i=\"" & ("Multiple Versions") & "\"\" > /dev/null 2>&1" ELSE SHELL "gksu synaptic > /dev/null 2>&1" ENDIF ENDIF END PUBLIC SUB hMenuHelp_Click() ' show html help EXEC ["xdg-open", "/usr/share/doc/update-watch-" & Application.Version & "/help/index.html"] END PUBLIC SUB hMenuQuit_Click() ' should stop timer wihle processing to avoid error tmTimer.Stop ME.Close() END PUBLIC SUB tiTrayIcon_DblClick() ' show list of updates hMenuShow_Click() END PRIVATE FUNCTION CheckModified() AS Boolean ' check necessary files are existing and get last modfiled date IF Exist(sPathRpm) = TRUE AND IF Exist(sPathApt) = TRUE THEN dtRpm = Stat(sPathRpm).LastModified dtApt = Stat(sPathApt).LastModified ' check rpm DB or apt cache is updated IF dtInfo <= dtApt OR IF dtInfo <= dtRpm THEN RETURN TRUE ELSE RETURN FALSE ENDIF ELSE Message.Error(("ERROR: any of essential files are missing\n\nPlease confirm following filees are exist\n\n ") & sPathRpm & "\n " & sPathApt) ME.Close() ENDIF END PRIVATE FUNCTION IsSynAptRunning() AS Boolean ' check apt-get or synaptic is already running or not using pgrep ' if others are running, disable menu items and change tray icon DIM sOutSyn AS String DIM sOutApt AS String SHELL "pgrep synaptic" TO sOutSyn SHELL "pgrep apt-get" TO sOutApt IF Split(Trim$(sOutSyn), "\n").Count >= 1 OR IF Split(Trim$(sOutApt), "\n").Count >= 1 THEN SetNotification("DEACTIVATE") RETURN TRUE ELSE SetNotification("ACTIVATE") RETURN FALSE END IF END PUBLIC SUB SetNotification(sStat AS String) SELECT CASE sStat CASE "REBOOT" sTip = ("To complete the update of your system, restart your system") tiTrayIcon.Tooltip = sTip tiTrayIcon.Picture = Stock["24/error"] IF bReboot = FALSE THEN ' should show reboot notification only once EXEC ["notify-send", "-u", "critical", "-t", "0", "-i", "error", ("Restart required"), ("To complete the update of your system, restart your system")] bReboot = TRUE ENDIF CASE "DUPLICATE" sTip = ("Multiple version packages found\n") stip = sTip & ("run synaptic and resolve this problem") tiTrayIcon.Tooltip = sTip tiTrayicon.Picture = Picture["orange.png"] hMenuApply.Enabled = FALSE hMenuShow.Enabled = TRUE IF bNotify = TRUE THEN ' show notification panel to notify updates EXEC ["notify-send", "-u", "critical", "-i", "/usr/share/pixmaps/update-watch-orange.png", ("Duplicated version warning"), sTIp] bNotify = FALSE ENDIF CASE "UPDATE" IF iUpgrade + inew + iRemove >= 1 THEN sTip = CStr(iUpgrade + inew + iRemove) & (" updates found") IF iHold >= 1 THEN sTip = sTip & "\n" ELSE ' need to clear tooltip text in the case of only hold pacakges exist sTip = "" ENDIF IF iHold >= 1 THEN sTip = sTip & ("Also not upgraded ") & iHold & (" packages are found\nPlease run package manager to update it") ENDIF tiTrayIcon.Tooltip = sTip tiTrayicon.Picture = Picture["red.png"] hMenuApply.Enabled = TRUE hMenuShow.Enabled = TRUE IF bNotify = TRUE THEN ' show notification panel to notify updates EXEC ["notify-send", "-u", "normal", "-i", "/usr/share/pixmaps/update-watch-red.png", ("Updates notification"), sTIp] bNotify = FALSE ENDIF CASE "NOUPDATE" sTip = ("No updates found") tiTrayIcon.Tooltip = sTip tiTrayicon.Picture = Picture["blue.png"] hMenuApply.Enabled = FALSE hMenuShow.Enabled = FALSE CASE "DEACTIVATE" tiTrayIcon.Tooltip = ("Synaptic package manager or \napt-get command is running") tiTrayIcon.Picture = Picture["gray.png"] hMenuApply.Enabled = FALSE hMenuCheck.Enabled = FALSE hMenuRun.Enabled = FALSE CASE "ACTIVATE" tiTrayIcon.Tooltip = sTip hMenuCheck.Enabled = TRUE hMenuRun.Enabled = TRUE END SELECT END