#!/usr/bin/env python2.5
# Filename: indigoPluginUpdateChecker.py
#
# Originally written by berkinet
# Conversion to module and email features by Travis Cook
#
# About:
#   This method checks for a specially-formatted file on a web server to determine if
#   there's been a new release of the plugin.  If there has, an entry will be made in
#   the log, and the user will optionally be emailed about the release.  The email
#   subject and body are set in the file on the server.
#
#
# Usage:
#
#         At the top of your plugin.py:
#       import indigoPluginUpdateChecker
#
#   In your plugin's __Init__ method:
#       self.updater = indigoPluginUpdateChecker.updateChecker(self, versionFileUrl [,daysBetweenChecks])
#
#       where:
#           - serverUrl is the location of your update info file (see below).
#           The url must be formatted like "http://www.domain.com/folder/updateFile.html"
#           - daysBetweenChecks is optional and defaults to 1.  This controls how often the module
#           will check for updates automatically.  They can always be checked for manually by running
#           self.updater.checkVersionNow()
#
#
#   Then put the following in your startup method to see if a check is required at startup:
#       self.updater.checkVersionPoll()
#
#   And also in your runConcurrentThread so the module can see if it's time to check for an update:
#
#           def runConcurrentThread(self):
#               # While Indigo hasn't told us to shutdown
#               while self.shutdown is False:
#                   self.updater.checkVersionPoll()
#                   self.sleep(1)
#           def stopConcurrentThread(self):
#               self.shutdown = True
#
#
#   PluginConfig.xml:
#
#       The following field should exist in the plugin's config if you want to use the email feature.
#       If the field is blank then emails will of course be disabled.
#
#           <Field id="updaterEmail" type="textfield">
#               <Label>Email:</Label>
#           </Field>
#
#       Optionally a checkbox can also be used.
#
#           <Field id="updaterEmailsEnabled" type="checkbox" defaultValue="true">
#               <Label>Email Update Notifications:</Label>
#           </Field>
#
#       Some values are saved in the plugin's prefs for use by the updater:
#           'updaterLastCheck' = Last time an update check was performed (epoch time)
#           'updaterLastVersionEmailed' = The last version emailed to the user
#
#
#
#   Server File:
#
#       Sample VersionInfo.html file:
#
#            Version: 1.3.1
#            EmailSubject: DSC Alarm Indigo Plugin Update
#                        EmailBody: The DSC Alarm Plugin you are using with Indigo has been updated.
#
#                        The changes are:
#                        - Change 1
#                        - Change 2
#
#                        The update can be downloaded at the link below.
#                        http://www.frightideas.com/hobbies/dscAlarm/DSC_Alarm_Plugin.zip
#
#            This email was sent to you by Indigo at the request of the plugin.  You will
#            only be emailed once per release.  To disable these emails see the plugin's config.

import indigo
# import re
import socket
import time
from urllib2 import urlopen
import subprocess


class updateChecker(object):

        def __init__(self, plugin, file_url, days_between_checks=1):
                self.plugin = plugin
                self.fileUrl = file_url
                self.secondsBetweenAutoChecks = days_between_checks * 86400
                self.nextCheck = int(self.plugin.pluginPrefs.get('updaterLastCheck', '0')) + self.secondsBetweenAutoChecks

        def errorLog(self, log):
                indigo.server.log(log, isError=True)

        def checkVersionPoll(self):
                # Did we check if there was an update within the last
                time_now = time.time()

                # If the version wasn't checked within our time period then check
                if time_now > self.nextCheck:
                        self.checkVersionNow()

        def checkVersionNow(self):

                self.plugin.debugLog(u"versionCheck: Started")

                # Save the last check time (now) in the plugin's config and our global variable
                time_now = time.time()
                self.plugin.pluginPrefs[u'updaterLastCheck'] = time_now
                self.nextCheck = time_now + self.secondsBetweenAutoChecks

                # Get plugin version
                my_version = str(self.plugin.pluginVersion)
                self.plugin.debugLog(u'versionCheck: Version Server Url: {0}'.format(self.fileUrl))
                socket.setdefaulttimeout(3)

                # Try to grab the version file
                try:
                        # f = urlopen(self.fileUrl)
                        f = subprocess.Popen(["curl", "-k", self.fileUrl], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
                        out, err = f.communicate()

                except:
                        self.errorLog(u"versionCheck: Unable to reach the version server.")
                        return

                # Parse the file
                try:
                        # lines = f.read().split('\n')
                        lines = out.split('\n')
                        if lines[0].startswith('Version:'):
                                latest_version = lines[0][8:].strip()
                        else:
                                self.plugin.debugLog(u'versionCheck: The version file does not start with "Version:"')
                                self.errorLog(u"versionCheck: There was an error parsing the server's version file.")
                                return
                except:
                        self.errorLog(u"versionCheck: Error parsing the server's version file.")
                        return