#!/usr/bin/python
# -*- coding: utf-8 -*-

__version__ = '1.0'

import signal
import sys
import atexit
import os
import time
import base64
import stat
import pwd
import argparse

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Notify', '0.7')
gi.require_version('AppIndicator3', '0.1')

from gi.repository import Notify
from gi.repository import Gtk
from gi.repository import GLib

#import subprocess

################################################################################
#CONFIG
################################################################################
APP_NAME = "labsync-tray"
APP_YEAR = "2019"
APP_VERSION = __version__ + '-' + APP_YEAR
APP_DESCR = "Notifica lo stato di aggiornamento del software nella cartella /opt"
APP_AUTHORS = ['Sezione di Informatica, DiSIT, UPO']
APP_ID = "labsync-tray"

CURR_DIR = os.path.dirname(os.path.abspath(__file__))

TMP_DIR = "/var/tmp/" + pwd.getpwuid(os.getuid()).pw_name

# icons: could be PNG or SVG as well
APP_ICONS = {
    'APP_ICON_OFF': os.path.join(TMP_DIR, 'labsync-off.svg'),
    'APP_ICON_OK': os.path.join(TMP_DIR, 'labsync-ok.svg'),
    'APP_ICON_SYNC': os.path.join(TMP_DIR, 'labsync-syncing.svg')
}

# seconds between checks
CHECK_PERIOD = 30
# how long the notification stays on the screen (seconds, 0=until user clicks)
NOTIFY_TIME = 0
# messages
SYNC_RUN_TITLE = "labsync"
SYNC_RUN_MESSAGE = """Stiamo aggiornando il software nella cartella /opt; ci \
sarà un po' di attività sul disco.\
\r\rAlcuni dei programmi lì presenti (comprese le macchine virtuali) potrebbero \
non funzionare correttamente fino al termine degli aggiornamenti.\
\r\rIl termine della procedura di aggiornamento ti verrà notificato, ti \
preghiamo di attendere qualche minuto.\
\r\r<b>Se hai atteso più di mezz&apos;ora, non hai ricevuto la notifica e il \
software che vuoi usare continua a non funzionare, contatta i tecnici.</b>"""

SYNC_RUN_ICON="dialog-warning"
# 0 = normal, 1 = warning, 2 = critical
SYNC_RUN_URGENCY = 2

SYNC_END_TITLE = 'labsync'
SYNC_END_MESSAGE = "Il software nella cartella /opt è aggiornato."
SYNC_END_ICON="info"
# 0 = normal, 1 = warning, 2 = critical
SYNC_END_URGENCY = 1

# task names
SYNC_TASK = "sync"
END_TASK = "end"

# file to check for saying if we're syncing or not
FILE_TO_CHECK = "/opt/ver"

# force using StatusIcon over AppIndicator
FORCE_TRAY = True

################################################################################
################################################################################

APP_ICONS_DATA = {
    'APP_ICON_OFF': """\
    PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTkyIDE5MiIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCI+PGcgdHJhbnNmb3JtPSIiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIGZvbnQtZmFtaWx5PSJub25lIiBmb250LXdlaWdodD0ibm9uZSIgZm9udC1zaXplPSJub25lIiB0ZXh0LWFuY2hvcj0ibm9uZSIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0wLDE5MnYtMTkyaDE5MnYxOTJ6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTk2LDE5MmMtNTMuMDE5MzQsMCAtOTYsLTQyLjk4MDY2IC05NiwtOTZ2MGMwLC01My4wMTkzNCA0Mi45ODA2NiwtOTYgOTYsLTk2djBjNTMuMDE5MzQsMCA5Niw0Mi45ODA2NiA5Niw5NnYwYzAsNTMuMDE5MzQgLTQyLjk4MDY2LDk2IC05Niw5NnoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNOTYsMTg4LjE2Yy01MC44OTg1NiwwIC05Mi4xNiwtNDEuMjYxNDQgLTkyLjE2LC05Mi4xNnYwYzAsLTUwLjg5ODU2IDQxLjI2MTQ0LC05Mi4xNiA5Mi4xNiwtOTIuMTZ2MGM1MC44OTg1NiwwIDkyLjE2LDQxLjI2MTQ0IDkyLjE2LDkyLjE2djBjMCw1MC44OTg1NiAtNDEuMjYxNDQsOTIuMTYgLTkyLjE2LDkyLjE2eiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0wLDE5MnYtMTkyaDE5MnYxOTJ6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTMuODQsMTg4LjE2di0xODQuMzJoMTg0LjMydjE4NC4zMnoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiLz48ZyBpZD0iTGF5ZXJfMSI+PGc+PGc+PGcgZmlsbD0iIzk1YTVhNiI+PGc+PHBhdGggZD0iTTIuOTYyNSw5NmMwLC01MS4zNzUgNDEuNjYyNSwtOTMuMDM3NSA5My4wMzc1LC05My4wMzc1YzUxLjM3NSwwIDkzLjAzNzUsNDEuNjYyNSA5My4wMzc1LDkzLjAzNzVjMCw1MS4zNzUgLTQxLjY2MjUsOTMuMDM3NSAtOTMuMDM3NSw5My4wMzc1Yy01MS4zNzUsMCAtOTMuMDM3NSwtNDEuNjYyNSAtOTMuMDM3NSwtOTMuMDM3NXoiLz48L2c+PC9nPjxwYXRoIGQ9Ik0xNjMuNTc1LDY3LjUzNzVjLTMuODYyNSwwIC03Ljc2MjUsMC4wMzc1IC0xMS42MjUsMC4wMzc1Yy04LjczNzUsLTE5LjU3NSAtMjUuODc1LC0zMy43MTI1IC00Ny40NzUsLTM3LjA4NzVjLTI0LjE1LC0zLjc4NzUgLTQ3LjIxMjUsNy4zODc1IC02MC45NzUsMjcuMTEyNWMtNi4xMTI1LDguNzM3NSA4LjI1LDE2Ljk1IDE0LjMyNSw4LjI1YzE4Ljg2MjUsLTI3IDU5LjE3NSwtMjQuNTYyNSA3NS43MTI1LDEuNzYyNWMtMy42LDAgLTcuMTYyNSwwIC0xMC43NjI1LDAuMDM3NWMtMS4wMTI1LDAgLTEuNzI1LDAuNDUgLTIuMTM3NSwxLjA4NzVjLTAuNzEyNSwwLjc4NzUgLTEuMDEyNSwxLjkxMjUgLTAuMjI1LDMuMDc1YzYuODI1LDEwLjU3NSAxMy42NSwyMS4xODc1IDIwLjQ3NSwzMS43NjI1YzEuMTYyNSwxLjc2MjUgMy42Mzc1LDEuNzYyNSA0Ljc2MjUsMGM2Ljc4NzUsLTEwLjYxMjUgMTMuNTM3NSwtMjEuMjYyNSAyMC4zMjUsLTMxLjg3NWMxLjA4NzUsLTEuOCAtMC40MTI1LC00LjE2MjUgLTIuNCwtNC4xNjI1eiIgZmlsbD0iI2ZmZmZmZiIvPjwvZz48cGF0aCBkPSJNMTM0LjM2MjUsMTI1LjY2MjVjLTE4LjcxMjUsMjYuODEyNSAtNTguNTM3NSwyNC42IC03NS4zMzc1LC0xLjEyNWMzLjQ1LDAgNi44NjI1LDAgMTAuMzEyNSwtMC4wMzc1YzEuMDEyNSwwIDEuNzI1LC0wLjQ1IDIuMTM3NSwtMS4wODc1YzAuNzEyNSwtMC43ODc1IDEuMDEyNSwtMS45MTI1IDAuMjI1LC0zLjA3NWMtNi44MjUsLTEwLjU3NSAtMTMuNjUsLTIxLjE4NzUgLTIwLjQ3NSwtMzEuNzYyNWMtMS4xNjI1LC0xLjggLTMuNjM3NSwtMS43NjI1IC00Ljc2MjUsMGMtNi43ODc1LDEwLjYxMjUgLTEzLjUzNzUsMjEuMjYyNSAtMjAuMzI1LDMxLjg3NWMtMS4xMjUsMS43NjI1IDAuMzM3NSw0LjEyNSAyLjM2MjUsNC4xMjVjNC4wMTI1LDAgNy45ODc1LC0wLjAzNzUgMTIsLTAuMDM3NWM4LjgxMjUsMTkuMjM3NSAyNS44LDMzLjExMjUgNDcuMjEyNSwzNi40ODc1YzI0LjExMjUsMy43ODc1IDQ3LjE3NSwtNy40MjUgNjAuOTM3NSwtMjcuMTEyNWM2LjExMjUsLTguNzM3NSAtOC4yNSwtMTYuOTEyNSAtMTQuMjg3NSwtOC4yNXoiIGZpbGw9IiNmZmZmZmYiLz48L2c+PC9nPjxnPjxnIGlkPSJMYXllcl8xIj48cGF0aCBkPSJNMTg4LjgsMTUyLjU1NjhjMCwxOS44NzggLTE2LjEyMiwzNiAtMzYsMzZjLTE5Ljg3OCwwIC0zNiwtMTYuMTIyIC0zNiwtMzZjMCwtMTkuODc4IDE2LjEyMiwtMzYgMzYsLTM2YzE5Ljg3OCwwIDM2LDE2LjEyMiAzNiwzNiIgZmlsbD0iIzQwNDA0MSIvPjxwYXRoIGQ9Ik0xODIuOCwxNTIuNTU2OGMwLDE2LjU2NiAtMTMuNDM0LDMwIC0zMCwzMGMtMTYuNTY2LDAgLTMwLC0xMy40MzQgLTMwLC0zMGMwLC0xNi41NjYgMTMuNDM0LC0zMCAzMCwtMzBjMTYuNTY2LDAgMzAsMTMuNDM0IDMwLDMwIiBmaWxsPSIjZTg0ODQ5Ii8+PHBhdGggZD0iTTE0MC44LDE2Ny41NTY4Yy0wLjc2OCwwIC0xLjUzNiwtMC4yOTQgLTIuMTIxLC0wLjg3OWMtMS4xNzMsLTEuMTczIC0xLjE3MywtMy4wNjkgMCwtNC4yNDJsMjQsLTI0YzEuMTczLC0xLjE3MyAzLjA2OSwtMS4xNzMgNC4yNDIsMGMxLjE3MywxLjE3MyAxLjE3MywzLjA2OSAwLDQuMjQybC0yNCwyNGMtMC41ODUsMC41ODUgLTEuMzUzLDAuODc5IC0yLjEyMSwwLjg3OXoiIGZpbGw9IiNmZmZmZmYiLz48cGF0aCBkPSJNMTY0LjgsMTY3LjU1NjhjLTAuNzY4LDAgLTEuNTM2LC0wLjI5NCAtMi4xMjEsLTAuODc5bC0yNCwtMjRjLTEuMTczLC0xLjE3MyAtMS4xNzMsLTMuMDY5IDAsLTQuMjQyYzEuMTczLC0xLjE3MyAzLjA2OSwtMS4xNzMgNC4yNDIsMGwyNCwyNGMxLjE3MywxLjE3MyAxLjE3MywzLjA2OSAwLDQuMjQyYy0wLjU4NSwwLjU4NSAtMS4zNTMsMC44NzkgLTIuMTIxLDAuODc5eiIgZmlsbD0iI2ZmZmZmZiIvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4K""",

    'APP_ICON_OK': """\
    PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTkyIDE5MiIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCI+PGcgdHJhbnNmb3JtPSIiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIGZvbnQtZmFtaWx5PSJub25lIiBmb250LXdlaWdodD0ibm9uZSIgZm9udC1zaXplPSJub25lIiB0ZXh0LWFuY2hvcj0ibm9uZSIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0wLDE5MnYtMTkyaDE5MnYxOTJ6IiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iTTk2LDE5MmMtNTMuMDE5MzQsMCAtOTYsLTQyLjk4MDY2IC05NiwtOTZ2MGMwLC01My4wMTkzNCA0Mi45ODA2NiwtOTYgOTYsLTk2djBjNTMuMDE5MzQsMCA5Niw0Mi45ODA2NiA5Niw5NnYwYzAsNTMuMDE5MzQgLTQyLjk4MDY2LDk2IC05Niw5NnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9Ik05NiwxODguMTZjLTUwLjg5ODU2LDAgLTkyLjE2LC00MS4yNjE0NCAtOTIuMTYsLTkyLjE2djBjMCwtNTAuODk4NTYgNDEuMjYxNDQsLTkyLjE2IDkyLjE2LC05Mi4xNnYwYzUwLjg5ODU2LDAgOTIuMTYsNDEuMjYxNDQgOTIuMTYsOTIuMTZ2MGMwLDUwLjg5ODU2IC00MS4yNjE0NCw5Mi4xNiAtOTIuMTYsOTIuMTZ6IiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSJNMCwxOTJ2LTE5MmgxOTJ2MTkyeiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iTTMuODQsMTg4LjE2di0xODQuMzJoMTg0LjMydjE4NC4zMnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxnIGlkPSJMYXllcl8xIiBzdHJva2U9Im5vbmUiPjxnPjxnPjxnIGZpbGw9IiMzNDk4ZGIiPjxnPjxwYXRoIGQ9Ik0yLjk2MjUsOTZjMCwtNTEuMzc1IDQxLjY2MjUsLTkzLjAzNzUgOTMuMDM3NSwtOTMuMDM3NWM1MS4zNzUsMCA5My4wMzc1LDQxLjY2MjUgOTMuMDM3NSw5My4wMzc1YzAsNTEuMzc1IC00MS42NjI1LDkzLjAzNzUgLTkzLjAzNzUsOTMuMDM3NWMtNTEuMzc1LDAgLTkzLjAzNzUsLTQxLjY2MjUgLTkzLjAzNzUsLTkzLjAzNzV6Ii8+PC9nPjwvZz48cGF0aCBkPSJNMTYzLjU3NSw2Ny41Mzc1Yy0zLjg2MjUsMCAtNy43NjI1LDAuMDM3NSAtMTEuNjI1LDAuMDM3NWMtOC43Mzc1LC0xOS41NzUgLTI1Ljg3NSwtMzMuNzEyNSAtNDcuNDc1LC0zNy4wODc1Yy0yNC4xNSwtMy43ODc1IC00Ny4yMTI1LDcuMzg3NSAtNjAuOTc1LDI3LjExMjVjLTYuMTEyNSw4LjczNzUgOC4yNSwxNi45NSAxNC4zMjUsOC4yNWMxOC44NjI1LC0yNyA1OS4xNzUsLTI0LjU2MjUgNzUuNzEyNSwxLjc2MjVjLTMuNiwwIC03LjE2MjUsMCAtMTAuNzYyNSwwLjAzNzVjLTEuMDEyNSwwIC0xLjcyNSwwLjQ1IC0yLjEzNzUsMS4wODc1Yy0wLjcxMjUsMC43ODc1IC0xLjAxMjUsMS45MTI1IC0wLjIyNSwzLjA3NWM2LjgyNSwxMC41NzUgMTMuNjUsMjEuMTg3NSAyMC40NzUsMzEuNzYyNWMxLjE2MjUsMS43NjI1IDMuNjM3NSwxLjc2MjUgNC43NjI1LDBjNi43ODc1LC0xMC42MTI1IDEzLjUzNzUsLTIxLjI2MjUgMjAuMzI1LC0zMS44NzVjMS4wODc1LC0xLjggLTAuNDEyNSwtNC4xNjI1IC0yLjQsLTQuMTYyNXoiIGZpbGw9IiNmZmZmZmYiLz48L2c+PHBhdGggZD0iTTEzNC4zNjI1LDEyNS42NjI1Yy0xOC43MTI1LDI2LjgxMjUgLTU4LjUzNzUsMjQuNiAtNzUuMzM3NSwtMS4xMjVjMy40NSwwIDYuODYyNSwwIDEwLjMxMjUsLTAuMDM3NWMxLjAxMjUsMCAxLjcyNSwtMC40NSAyLjEzNzUsLTEuMDg3NWMwLjcxMjUsLTAuNzg3NSAxLjAxMjUsLTEuOTEyNSAwLjIyNSwtMy4wNzVjLTYuODI1LC0xMC41NzUgLTEzLjY1LC0yMS4xODc1IC0yMC40NzUsLTMxLjc2MjVjLTEuMTYyNSwtMS44IC0zLjYzNzUsLTEuNzYyNSAtNC43NjI1LDBjLTYuNzg3NSwxMC42MTI1IC0xMy41Mzc1LDIxLjI2MjUgLTIwLjMyNSwzMS44NzVjLTEuMTI1LDEuNzYyNSAwLjMzNzUsNC4xMjUgMi4zNjI1LDQuMTI1YzQuMDEyNSwwIDcuOTg3NSwtMC4wMzc1IDEyLC0wLjAzNzVjOC44MTI1LDE5LjIzNzUgMjUuOCwzMy4xMTI1IDQ3LjIxMjUsMzYuNDg3NWMyNC4xMTI1LDMuNzg3NSA0Ny4xNzUsLTcuNDI1IDYwLjkzNzUsLTI3LjExMjVjNi4xMTI1LC04LjczNzUgLTguMjUsLTE2LjkxMjUgLTE0LjI4NzUsLTguMjV6IiBmaWxsPSIjZmZmZmZmIi8+PC9nPjwvZz48ZyBzdHJva2U9Im5vbmUiPjxnIGlkPSJMYXllcl8xIj48cGF0aCBkPSJNMTg4LjgsMTUyLjU1NjhjMCwxOS44NzggLTE2LjEyMiwzNiAtMzYsMzZjLTE5Ljg3OCwwIC0zNiwtMTYuMTIyIC0zNiwtMzZjMCwtMTkuODc4IDE2LjEyMiwtMzYgMzYsLTM2YzE5Ljg3OCwwIDM2LDE2LjEyMiAzNiwzNiIgZmlsbD0iIzQwNDA0MSIvPjxwYXRoIGQ9Ik0xODIuOCwxNTIuNTU2OGMwLDE2LjU2NiAtMTMuNDM0LDMwIC0zMCwzMGMtMTYuNTY2LDAgLTMwLC0xMy40MzQgLTMwLC0zMGMwLC0xNi41NjYgMTMuNDM0LC0zMCAzMCwtMzBjMTYuNTY2LDAgMzAsMTMuNDM0IDMwLDMwIiBmaWxsPSIjMWZhODViIi8+PHBhdGggZD0iTTE0OS44LDE2Ny41NTY4Yy0wLjc2NzYyLDAgLTEuNTM1MjUsLTAuMjkyODcgLTIuMTIxLC0wLjg3OWwtMTIsLTEyYy0xLjE3MTg3LC0xLjE3MTg3IC0xLjE3MTg3LC0zLjA3MDUgMCwtNC4yNDIzOGMxLjE3MTg4LC0xLjE3MTg3IDMuMDcwNSwtMS4xNzE4NyA0LjI0MjM3LDBsOS44Nzg2Myw5Ljg3OTM4bDE4Ljg3OSwtMTguODc5YzEuMTcxODgsLTEuMTcxODcgMy4wNzA1LC0xLjE3MTg3IDQuMjQyMzcsMGMxLjE3MTg4LDEuMTcxODggMS4xNzE4OCwzLjA3MDUgMCw0LjI0MjM3bC0yMSwyMWMtMC41ODYxMiwwLjU4NTc1IC0xLjM1Mzc1LDAuODc4NjIgLTIuMTIxMzgsMC44Nzg2MnoiIGZpbGw9IiNmZmZmZmYiLz48L2c+PC9nPjxwYXRoIGQ9Ik0xMTYuOCwxODguNTU2OHYtNzJoNzJ2NzJ6IiBpZD0ib3ZlcmxheS1kcmFnIiBmaWxsPSIjZmYwMDAwIiBzdHJva2U9Im5vbmUiIG9wYWNpdHk9IjAiLz48L2c+PC9nPjwvc3ZnPgo=""",

    'APP_ICON_SYNC': """\
    PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTkyIDE5MiIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCI+PGcgdHJhbnNmb3JtPSIiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIGZvbnQtZmFtaWx5PSJub25lIiBmb250LXdlaWdodD0ibm9uZSIgZm9udC1zaXplPSJub25lIiB0ZXh0LWFuY2hvcj0ibm9uZSIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0wLDE5MnYtMTkyaDE5MnYxOTJ6IiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iTTk2LDE5MmMtNTMuMDE5MzQsMCAtOTYsLTQyLjk4MDY2IC05NiwtOTZ2MGMwLC01My4wMTkzNCA0Mi45ODA2NiwtOTYgOTYsLTk2djBjNTMuMDE5MzQsMCA5Niw0Mi45ODA2NiA5Niw5NnYwYzAsNTMuMDE5MzQgLTQyLjk4MDY2LDk2IC05Niw5NnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9Ik05NiwxODguMTZjLTUwLjg5ODU2LDAgLTkyLjE2LC00MS4yNjE0NCAtOTIuMTYsLTkyLjE2djBjMCwtNTAuODk4NTYgNDEuMjYxNDQsLTkyLjE2IDkyLjE2LC05Mi4xNnYwYzUwLjg5ODU2LDAgOTIuMTYsNDEuMjYxNDQgOTIuMTYsOTIuMTZ2MGMwLDUwLjg5ODU2IC00MS4yNjE0NCw5Mi4xNiAtOTIuMTYsOTIuMTZ6IiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSJNMCwxOTJ2LTE5MmgxOTJ2MTkyeiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iTTMuODQsMTg4LjE2di0xODQuMzJoMTg0LjMydjE4NC4zMnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9IiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSIiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIvPjxnIGlkPSJMYXllcl8xIiBzdHJva2U9Im5vbmUiPjxnPjxnPjxnIGZpbGw9IiNlNjdlMjIiPjxnPjxwYXRoIGQ9Ik0yLjk2MjUsOTZjMCwtNTEuMzc1IDQxLjY2MjUsLTkzLjAzNzUgOTMuMDM3NSwtOTMuMDM3NWM1MS4zNzUsMCA5My4wMzc1LDQxLjY2MjUgOTMuMDM3NSw5My4wMzc1YzAsNTEuMzc1IC00MS42NjI1LDkzLjAzNzUgLTkzLjAzNzUsOTMuMDM3NWMtNTEuMzc1LDAgLTkzLjAzNzUsLTQxLjY2MjUgLTkzLjAzNzUsLTkzLjAzNzV6Ii8+PC9nPjwvZz48cGF0aCBkPSJNMTYzLjU3NSw2Ny41Mzc1Yy0zLjg2MjUsMCAtNy43NjI1LDAuMDM3NSAtMTEuNjI1LDAuMDM3NWMtOC43Mzc1LC0xOS41NzUgLTI1Ljg3NSwtMzMuNzEyNSAtNDcuNDc1LC0zNy4wODc1Yy0yNC4xNSwtMy43ODc1IC00Ny4yMTI1LDcuMzg3NSAtNjAuOTc1LDI3LjExMjVjLTYuMTEyNSw4LjczNzUgOC4yNSwxNi45NSAxNC4zMjUsOC4yNWMxOC44NjI1LC0yNyA1OS4xNzUsLTI0LjU2MjUgNzUuNzEyNSwxLjc2MjVjLTMuNiwwIC03LjE2MjUsMCAtMTAuNzYyNSwwLjAzNzVjLTEuMDEyNSwwIC0xLjcyNSwwLjQ1IC0yLjEzNzUsMS4wODc1Yy0wLjcxMjUsMC43ODc1IC0xLjAxMjUsMS45MTI1IC0wLjIyNSwzLjA3NWM2LjgyNSwxMC41NzUgMTMuNjUsMjEuMTg3NSAyMC40NzUsMzEuNzYyNWMxLjE2MjUsMS43NjI1IDMuNjM3NSwxLjc2MjUgNC43NjI1LDBjNi43ODc1LC0xMC42MTI1IDEzLjUzNzUsLTIxLjI2MjUgMjAuMzI1LC0zMS44NzVjMS4wODc1LC0xLjggLTAuNDEyNSwtNC4xNjI1IC0yLjQsLTQuMTYyNXoiIGZpbGw9IiNmZmZmZmYiLz48L2c+PHBhdGggZD0iTTEzNC4zNjI1LDEyNS42NjI1Yy0xOC43MTI1LDI2LjgxMjUgLTU4LjUzNzUsMjQuNiAtNzUuMzM3NSwtMS4xMjVjMy40NSwwIDYuODYyNSwwIDEwLjMxMjUsLTAuMDM3NWMxLjAxMjUsMCAxLjcyNSwtMC40NSAyLjEzNzUsLTEuMDg3NWMwLjcxMjUsLTAuNzg3NSAxLjAxMjUsLTEuOTEyNSAwLjIyNSwtMy4wNzVjLTYuODI1LC0xMC41NzUgLTEzLjY1LC0yMS4xODc1IC0yMC40NzUsLTMxLjc2MjVjLTEuMTYyNSwtMS44IC0zLjYzNzUsLTEuNzYyNSAtNC43NjI1LDBjLTYuNzg3NSwxMC42MTI1IC0xMy41Mzc1LDIxLjI2MjUgLTIwLjMyNSwzMS44NzVjLTEuMTI1LDEuNzYyNSAwLjMzNzUsNC4xMjUgMi4zNjI1LDQuMTI1YzQuMDEyNSwwIDcuOTg3NSwtMC4wMzc1IDEyLC0wLjAzNzVjOC44MTI1LDE5LjIzNzUgMjUuOCwzMy4xMTI1IDQ3LjIxMjUsMzYuNDg3NWMyNC4xMTI1LDMuNzg3NSA0Ny4xNzUsLTcuNDI1IDYwLjkzNzUsLTI3LjExMjVjNi4xMTI1LC04LjczNzUgLTguMjUsLTE2LjkxMjUgLTE0LjI4NzUsLTguMjV6IiBmaWxsPSIjZmZmZmZmIi8+PC9nPjwvZz48ZyBzdHJva2U9Im5vbmUiPjxnIGlkPSJMYXllcl8xIj48cGF0aCBkPSJNMTg4LjgsMTUyLjU1NjhjMCwxOS44NzggLTE2LjEyMiwzNiAtMzYsMzZjLTE5Ljg3OCwwIC0zNiwtMTYuMTIyIC0zNiwtMzZjMCwtMTkuODc4IDE2LjEyMiwtMzYgMzYsLTM2YzE5Ljg3OCwwIDM2LDE2LjEyMiAzNiwzNiIgZmlsbD0iIzQwNDA0MSIvPjxwYXRoIGQ9Ik0xNTIuOCwxMjIuNTU2OGMxNi41NjYsMCAzMCwxMy40MzQgMzAsMzBjMCwxNi41NjYgLTEzLjQzNCwzMCAtMzAsMzBjLTE2LjU2NiwwIC0zMCwtMTMuNDM0IC0zMCwtMzBjMCwtMTYuNTY2IDEzLjQzNCwtMzAgMzAsLTMwIiBmaWxsPSIjZmZmZmZmIi8+PHBhdGggZD0iTTE2NC44LDE2Ny41NTY4Yy0wLjc2OCwwIC0xLjUzNiwtMC4yOTQgLTIuMTIxLC0wLjg3OWwtMTIsLTEyYy0wLjU2NCwtMC41NjEgLTAuODc5LC0xLjMyNiAtMC44NzksLTIuMTIxdi0yMWMwLC0xLjY1NiAxLjM0NCwtMyAzLC0zYzEuNjU2LDAgMywxLjM0NCAzLDN2MTkuNzU4bDExLjEyMSwxMS4xMjFjMS4xNzMsMS4xNzMgMS4xNzMsMy4wNjkgMCw0LjI0MmMtMC41ODUsMC41ODUgLTEuMzUzLDAuODc5IC0yLjEyMSwwLjg3OXoiIGZpbGw9IiMyNmE5ZTAiLz48Y2lyY2xlIGN4PSI0MDcuNDY2NjciIGN5PSI0MDYuODE4MTMiIHRyYW5zZm9ybT0ic2NhbGUoMC4zNzUsMC4zNzUpIiByPSIxMiIgZmlsbD0iIzI2YTllMCIvPjwvZz48L2c+PHBhdGggZD0iTTExNi44LDE4OC41NTY4di03Mmg3MnY3MnoiIGlkPSJvdmVybGF5LWRyYWciIGZpbGw9IiNmZjAwMDAiIHN0cm9rZT0ibm9uZSIgb3BhY2l0eT0iMCIvPjwvZz48L2c+PC9zdmc+Cg=="""
}

# detect AppIndicator support
APPIND_SUPPORT = 1
try:
    from gi.repository import AppIndicator3
except:
    APPIND_SUPPORT = 1

class TrayApp:

    def __init__(self, appid, icon=None, menu=None):
        self.task_changed = True
        self.task = END_TASK
        self.icon = icon
        self.current_notification = None

        if menu != None:
            self.menu = menu
        else:
            self.menu = self.build_menu()
        self.menu.show_all()

        self.create_icon_files()

        if APPIND_SUPPORT == 1 and FORCE_TRAY == False:
            self.tray = AppIndicator3.Indicator.new(
                appid, icon,
                AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
            self.tray.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            self.tray.set_menu(self.menu)
        else:
            self.tray = Gtk.StatusIcon()
            self.tray.set_visible(True);
            self.tray.connect('popup-menu', self.on_popup_menu)
            self.tray.connect("button-press-event", self.on_mouse_click)
            self.tray.set_tooltip_text(APP_NAME)
            self.tray.set_title(APP_NAME)
            if icon != None:
                self.tray.set_from_file(icon)
            else:
                self.tray.set_from_stock(Gtk.STOCK_INFO)
        # initialize task value
        self.update_task()
        if self.task_changed:
            self.send_notification()
        # then start updating every CHECK_PERIOD seconds
        # http://developer.gnome.org/pygobject/stable/glib-functions.html#function-glib--timeout-add-seconds
        GLib.timeout_add_seconds(CHECK_PERIOD, self.handler_timeout)
        # clean up on exit, both normal and ctrl-c
        atexit.register(self.handler_exit)
        signal.signal(signal.SIGINT, self.handler_signal)

    def handler_exit(self):
        self.delete_icon_files()

    def handler_signal(self, sig, frame):
        self.delete_icon_files()
        sys.exit(0)

    def on_mouse_click(self, data, event):
        # 1-left, 2-middle, 3-right
        if event.button == 1:
            self.update_task()
            self.send_notification()
        # time is required by the popup
        # time = Gtk.get_current_event_time()
        #self.menu.popup(None, None, Gtk.StatusIcon.position_menu, self.tray,
        #    event.button, time)

    def on_popup_menu(self, icon, button, time):
        self.menu.popup(None, None, Gtk.StatusIcon.position_menu, icon,
            button, time)

    def build_menu(self):
        menu = Gtk.Menu()
        item_status = Gtk.MenuItem('Status')
        item_status.connect("activate", self.handler_menu_status)
        menu.append(item_status)
        about = Gtk.MenuItem("About")
        about.connect("activate", self.handler_menu_about)
        menu.append(about)
        menu.append(Gtk.SeparatorMenuItem())
        item_quit = Gtk.MenuItem("Exit")
        item_quit.connect("activate", self.handler_menu_quit)
        menu.append(item_quit)
        return menu

    def handler_menu_quit(self, evt):
        Notify.uninit()
        Gtk.main_quit()

    def handler_menu_status(self, evt):
        self.update_task()
        self.send_notification()

    def send_notification(self):
        if self.task == SYNC_TASK:
            title = SYNC_RUN_TITLE
            msg = SYNC_RUN_MESSAGE
            icon = SYNC_RUN_ICON
            urgency = SYNC_RUN_URGENCY
        else:
            title = SYNC_END_TITLE
            msg = SYNC_END_MESSAGE
            icon = SYNC_END_ICON
            urgency = SYNC_END_URGENCY
        # close the current notification, if any
        if self.current_notification != None:
            self.current_notification.close()
            self.current_notification = None
        self.current_notification = Message(None, title, msg, icon, NOTIFY_TIME, urgency).notification
        self.current_notification.connect("closed", self.handler_current_notification_closed)

    def handler_current_notification_closed(self, evt):
        self.current_notification = None

    def handler_menu_about(self, evt):
        about_dialog = Gtk.AboutDialog()
        about_dialog.set_destroy_with_parent(True)
        about_dialog.set_icon_name("dialog-information")
        # no SVG?
        about_dialog.set_logo_icon_name("")
        about_dialog.set_program_name(APP_NAME)
        about_dialog.set_name(APP_NAME)
        about_dialog.set_version(APP_VERSION)
        about_dialog.set_license_type(Gtk.License.GPL_3_0)
        about_dialog.set_comments(APP_DESCR)
        about_dialog.set_authors(APP_AUTHORS)
        about_dialog.set_default_response(Gtk.ResponseType.CLOSE)
        about_dialog.run()
        about_dialog.destroy()

    def update_icon(self, icon):
        self.icon = icon
        if APPIND_SUPPORT == 1 and FORCE_TRAY == False:
            self.tray.set_icon(icon)
        else:
            self.tray.set_from_file(icon)

    def update_task(self):
        exists = os.path.isfile(FILE_TO_CHECK)
        if exists:
            task = END_TASK
            self.update_icon(APP_ICONS['APP_ICON_OK'])
        else:
            task = SYNC_TASK
            self.update_icon(APP_ICONS['APP_ICON_SYNC'])
        if self.task != task:
            self.task_changed = True
        else:
            self.task_changed = False
        self.task = task

    def handler_timeout(self):
        """This will be called every few seconds by the GLib.timeout.
        """
        self.update_task()
        if self.task_changed:
            self.send_notification()
        # return True so that we get called again
        # returning False will make the timeout stop
        return True

    def create_tmp_dir(self):
        if not os.path.exists(TMP_DIR):
            os.makedirs(TMP_DIR)

    def create_icon_files(self):
        self.create_tmp_dir()
        for key, value in APP_ICONS.items():
            with open(value, 'wb') as fp:
                fp.write(base64.b64decode(APP_ICONS_DATA[key]))
            # these 2 command will change file permissions
            #st = os.stat(APP_ICONS[key])
            #os.chmod(APP_ICONS[key], st.st_mode | stat.S_IWOTH)

    def delete_icon_files(self):
        for key, value in APP_ICONS.items():
            if os.path.isfile(value):
                os.remove(value)

    def main(self):
        Gtk.main()

class Message():
    def mess_callback():
        pass

    def __init__(self, parent, caption, msg, img=None, timeout=None,
        urgency=None):

        self.notification = None

        if timeout != None: pass
        else: timeout = 0 # message should not timeout

        if urgency: pass
        else: urgency = 0

        caps = Notify.get_server_caps()
        self.notification = Notify.Notification.new(caption, msg, img) # passing an image is optional
        self.notification.set_timeout(timeout) # milliseconds
        self.notification.set_urgency(urgency) # 0-Low, 1-Normal, 2-Critical
        # Without the following `add_action` option, no countdown to the timeout is shown
        if timeout != 0 and 'actions' in caps:
            self.notification.add_action("close", "Chiudi", self.mess_callback, None) # Show the countdown to close
            self.notification.show()
            # do whatever your application is doing
            time.sleep(timeout)
            self.notification.close()
        else:
            self.notification.show()


if __name__ == "__main__":
    # parse command line arguments
    parser = argparse.ArgumentParser(description=APP_NAME + ' ' + APP_VERSION)
    parser.add_argument('-p', '--period', type=int,
        help='checking period (seconds between checkings)')
    args = parser.parse_args()
    if args.period:
        CHECK_PERIOD = args.period
        print 'Checking period: ' + str(CHECK_PERIOD)

    Notify.init(APP_ID)
    app = TrayApp(APP_ID, APP_ICONS['APP_ICON_OFF'])
    app.main()