source: sasview/sansguiframe/src/sans/guiframe/version.py @ 4793734

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 4793734 was 6df04e43, checked in by Gervaise Alina <gervyh@…>, 13 years ago

put back the code for version_checking, replace subprocess with process

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[52070a1]1
[d955bf19]2################################################################################
3#This software was developed by the University of Tennessee as part of the
4#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
5#project funded by the US National Science Foundation.
6#
7#See the license text in license.txt
8#
9#copyright 2010, University of Tennessee
10################################################################################
[52070a1]11
12
[32c0841]13import sys
14import time
15import subprocess
[6df04e43]16import urllib
17import re
[32c0841]18import os
[52070a1]19import getopt
20from threading import Thread
21
22## Maximum number of seconds to wait for an answer from the server
23MAX_WAIT_TIME = 20
24## Local storage file name
25VERSION_FILE  = '.current_version'
26
[6df04e43]27DEFAULT_VERSION = '0.0.0'
28
[52070a1]29class VersionChecker(object):
30    """
[d955bf19]31    Class of objects used to obtain the current version of an application
32    from the deployment server.
33    A sub process is started to read the URL associated with the version number.
34    The version number is written on file locally before the reading process
35    ends, then read when the version number is requested.   
36   
37    The reading of the URL is put in a separate process so that it doesn't
38    affect the performance of the application and can be managed and stopped at any time.
[52070a1]39    """
40    ## Process used to obtain the current application version from the server
41    _process = None
42    ## Start time of the process of obtaining a version number
43    _t_0 = None
44   
45    def __init__(self, version_url):
46        """
[d955bf19]47        Start the sub-process used to read the version URL
[52070a1]48        """
[32c0841]49        self._process = subprocess.Popen([sys.executable, __file__,
50                                          '-g', '-u%s' % version_url])
[52070a1]51        self._t_0 = time.time()
52       
53    def is_complete(self):
54        """
[d955bf19]55        Method used to poll the reading process. The process will be killed
56        if the wait time is longer than a predefined maximum.
57        This method should always be called before get_version() to ensure
58        accuracy of the version number that is returned.
[52070a1]59        """
[32c0841]60        if(time.time() - self._t_0 < MAX_WAIT_TIME):
[52070a1]61            if self._process.poll() is not None:
62                return True
63            return False
64        else:
[c6d8eb1]65            return False
66            #self._process.kill()
[52070a1]67        return True
68   
69    def get_version(self):
70        """
[d955bf19]71        Returns the last version number that was read from the server.
[52070a1]72        """
73        try:
74            f = open(VERSION_FILE, 'r')
75            return f.read()
76        except:
[6df04e43]77            return DEFAULT_VERSION
[52070a1]78
79class VersionThread(Thread):
80    """
[d955bf19]81    Thread used to start the process of reading the current version of an
82    application from the deployment server.
83   
84    The VersionChecker is user in a Thread to allow the main application
85    to continue dealing with UI requests from the user. The main application
86    provides a call-back method for when the version number is obtained.
[52070a1]87    """
88    def __init__ (self, url, call_back=None, baggage=None):
89        Thread.__init__(self)
90        self._url = url
91        self._call_back = call_back
92        self._baggage = baggage
93     
94    def run(self):
95        """
[d955bf19]96        Execute the process of reading the current application version number.
[52070a1]97        """
98        checker = VersionChecker(self._url)
99        while(not checker.is_complete()):
100            time.sleep(1)
101        self._call_back(checker.get_version(), self._baggage)
[6df04e43]102       
103 
104def get_version(url, q=None):
105    """
106    """
107    h = urllib.urlopen(url)
108    for line in h.readlines():
109        version = line.strip()
110        if len(re.findall('\d+\.\d+\.\d+$', version)) > 0:
111            if q is not None:
112                q.put(version)
113            return version
114    if q is not None:
115        q.put(DEFAULT_VERSION)
116    return DEFAULT_VERSION
117     
118class VersionThread2(Thread):
119    """
120    Thread used to start the process of reading the current version of an
121    application from the deployment server.
122   
123    The VersionChecker is user in a Thread to allow the main application
124    to continue dealing with UI requests from the user. The main application
125    provides a call-back method for when the version number is obtained.
126    """
127    def __init__ (self, url, call_back=None, baggage=None):
128        Thread.__init__(self)
129        self._url = url
130        self._call_back = call_back
131        self._baggage = baggage
132        self._t_0 = time.time()
133     
134    def run(self):
135        """
136        Execute the process of reading the current application version number.
137        """
138        def is_complete(p):
139            """
140            """
141            if(time.time() - self._t_0 < MAX_WAIT_TIME):
142                if p.is_alive():
143                    return True
144                return False
145            else:
146                return False
147           
148        from multiprocessing import Process, Queue
149        q = Queue()
150        p = Process(target=get_version, args=(self._url, q,))
151        p.start()
152        while(not is_complete(p)):
153            time.sleep(1)
154        version = q.get()
155        p.join()
156        p.terminate()
157        self._call_back(version, self._baggage)
158   
[52070a1]159           
160def write_version(version, filename=VERSION_FILE):
161    """
[d955bf19]162    Store the version number
163    This could be put into a DB if the application has one.
[52070a1]164    """
165    f = open(filename, 'w')
166    f.write(version)
167    f.close()
168       
169def _get_version_from_server(url):
170    """
[d955bf19]171    Method executed in the independent process used to read the
172    current version number from the server.
173   
174    :param url: URL to read the version number from
175   
[52070a1]176    """
177    try: 
[6df04e43]178        version = _get_version(url)
179        write_version(version)
[52070a1]180    except:
[6df04e43]181        write_version(DEFAULT_VERSION)
182       
183       
[52070a1]184       
185if __name__ == "__main__": 
186    _get_version = False
187    _url = 'http://danse.chem.utk.edu/prview_version.php'
188   
189    opts, args = getopt.getopt(sys.argv[1:], "gu:", ["get", "url="])
190    for opt, arg in opts:
191        if opt in ("-u", "--url"):
192            _url = arg
193        elif opt in ("-g", "--get"):
194            _get_version = True
195           
196    if _get_version:
197        # Get the version number from the URL.
198        _get_version_from_server(_url)
199    else: 
200        # Test execution of the reading process
201        def _process(version, baggage=None):
202            print "Received:", version   
203        checker = VersionThread(_url, _process)
204        checker.start()
205       
Note: See TracBrowser for help on using the repository browser.