215c24040415417ffb95e6b823a54b248147a5e8
max
  Fri Oct 27 01:42:11 2023 -0700
#Preview2 week - bugs introduced now will need a build patch to fix
trying bugfix for hubPublicMail script for QA, email from Lou and Gera

diff --git src/utils/qa/hubPublicMail src/utils/qa/hubPublicMail
index 3c71740..1daf7c4 100755
--- src/utils/qa/hubPublicMail
+++ src/utils/qa/hubPublicMail
@@ -8,31 +8,31 @@
 # makes sure that only one instance of the program runs at the same time
 lockFname = None
 
 # switch off insecure SSL warnings
 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 
 fromEmail="genome-www@soe.ucsc.edu"
 
 emailTemplate = """Dear UCSC Public Hub author,
 
 This is an automated email sent by the UCSC Genome Browser Group's hubPublicMail system to alert you
 that your public track hub at the address:
 
 %s
 
-Has been inaccessible for at least 48 hours. If it continues to be offline, we may need to remove it
+Has been inaccessible for at least 48 consecutive hours. If it continues to be offline, we may have to remove it
 from our public hubs list at https://genome.ucsc.edu/cgi-bin/hgHubConnect
 
 Do not hesitate to let us know if we can help you resolve this situation, e.g. by updating the URL
 where the hub is hosted or possibly hosting the files on our servers.
 
 You can reach us at genome-www@soe.ucsc.edu.
 
 Thank you for your interest and contributions,
 The UCSC Genome Browser Group
 """
 # ==== functions =====
     
 def parseArgs():
     " setup logging, parse command line arguments and options. -h shows auto-generated help page "
     parser = optparse.OptionParser("""usage: %prog [options] hgcentralname statusFile - send email if public hub is down
@@ -85,31 +85,31 @@
     if " or " in s:
         return s.split(" or ")[1]
     return s
 
 def downloadUrls(urls, emails):
     " try to read all hub.txt in URLs, return list of failed URLs, and dict hub -> email"
     didFail = list()
     emails = dict()
 
     for url in urls:
         logging.debug("Checking %s" % url)
 
         reqFailed = False
         if url.startswith("http"):
             try:
-                f = requests.get(url, verify=False)
+                f = requests.get(url, verify=False, timeout=5)
             except KeyboardInterrupt: # handle ctrl-c for debugging
                 sys.exit(1)
             except:
                 reqFailed = True
             text = f.text
         else:
             # FTP
             try:
                 f = urllib.request.urlopen(url, timeout=10)
                 text = f.read().decode("utf8")
             except:
                 reqFailed = True
 
         if reqFailed:
             logging.debug("URL %s failed." % url)
@@ -174,30 +174,32 @@
         if oldInfo is None:
             oldEmail = urlEmails.get(url)
             if oldEmail is None:
                 print("URL %s is broken and there is no email in the status file. Skipping it." % url)
                 continue
             oldInfo = [oldEmail, 0]
 
         email = urlEmails.get(url) # prefer most current email address
         if email is None:
             email = oldInfo[0]
 
         failCount = oldInfo[1]
 
         if url in failedUrls:
             failCount += 1
+        else:
+            failCount = 0
 
         urlInfo[url] = (email, failCount)
 
     return urlInfo
 
 def sendEmails(urlInfo):
     " given dict url -> (email, failCount), send email if failCount > 24 and set failCount = -48 "
     for url, (destEmail, failCount) in urlInfo.items():
         if failCount>24:
             logging.info("HUB %s BROKEN - sending email to %s" % (url, destEmail))
             emailText = emailTemplate % url
             sendEmail(destEmail, emailText)
             urlInfo[url] = (destEmail, -48)
     return urlInfo
 
@@ -215,44 +217,46 @@
 
 def createLockFile(statusFname):
     """ when downloading files, weird things can happen. even wget sometimes gets stuck. So make
     sure that this program can't run multiple times """
     global lockFname
     lockFname = statusFname+".lock"
 
     if isfile(lockFname):
         logging.error("lockfile %s already exists. Check if this program is already running." % lockFname)
         sys.exit(1)
 
     open(lockFname, "w") # create file
     atexit.register(removeLock)
 
 def removeLock():
+    if isfile(lockFname):
         os.remove(lockFname)
 
 def hubPublicMail(centralName, statusFname):
     " send email if a hub fails more than 24 times "
     createLockFile(statusFname)
 
     urls = getHubUrls(centralName)
 
     oldUrlInfo = readStatus(statusFname)
 
     failedUrls, urlEmails = downloadUrls(urls, oldUrlInfo)
 
     if len(failedUrls) > 10:
         logging.error("More than 10 broken hubs? Something is weird. Please check the network setup.")
         sys.exit(1)
 
     newUrlInfo = mergeInfo(urls, oldUrlInfo, failedUrls, urlEmails)
     newUrlInfo = sendEmails(newUrlInfo)
 
     writeStatus(newUrlInfo, statusFname)
+    removeLock()
 
 def main():
     args, options = parseArgs()
 
     centralName, statusFname = args
     hubPublicMail(centralName, statusFname)
 
 
 main()