From 5867693b7dfeb7e87cd58303d9c26c92e75d1013 Mon Sep 17 00:00:00 2001
From: Martijn Vermaat <martijn@vermaat.name>
Date: Wed, 4 Nov 2015 14:57:46 +0100
Subject: [PATCH] Fix link in batch notification if submitted from webservice

---
 doc/config.rst                       |  8 ++++++++
 doc/deploy.rst                       |  1 +
 mutalyzer/Scheduler.py               | 23 ++++++++++-------------
 mutalyzer/config/default_settings.py |  4 ++++
 mutalyzer/website/__init__.py        | 20 ++++++++++++++++++++
 mutalyzer/website/views.py           | 11 ++---------
 6 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/doc/config.rst b/doc/config.rst
index 3f31f863..1df8eea5 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -184,6 +184,14 @@ REVERSE_PROXIED
 
   `Default value:` `False`
 
+.. _config-website-root-url:
+
+WEBSITE_ROOT_URL
+  URL to the website root (without trailing slash). Used for generating
+  download links in the batch scheduler.
+
+  `Default value:` `None`
+
 .. _config-soap-wsdl-url:
 
 SOAP_WSDL_URL
diff --git a/doc/deploy.rst b/doc/deploy.rst
index ab75f0e8..81026858 100644
--- a/doc/deploy.rst
+++ b/doc/deploy.rst
@@ -30,6 +30,7 @@ settings:
 - :ref:`EMAIL <config-email>`
 - :ref:`DEBUG <config-debug>`
 - :ref:`CACHE_DIR <config-cache-dir>`
+- :ref:`WEBSITE_ROOT_URL <config-website-root-url>`
 - :ref:`SOAP_WSDL_URL <config-soap-wsdl-url>`
 - :ref:`JSON_ROOT_URL <config-json-root-url>`
 - :ref:`REVERSE_PROXIED <config-reverse-proxied>`
diff --git a/mutalyzer/Scheduler.py b/mutalyzer/Scheduler.py
index f3ad60e6..e9fc35a9 100644
--- a/mutalyzer/Scheduler.py
+++ b/mutalyzer/Scheduler.py
@@ -33,6 +33,7 @@ from mutalyzer.grammar import Grammar
 from mutalyzer.output import Output
 from mutalyzer.mapping import Converter
 from mutalyzer import Retriever           # Retriever.Retriever
+from mutalyzer import website
 
 
 __all__ = ["Scheduler"]
@@ -83,7 +84,7 @@ class Scheduler() :
         return not self.__run
     #stopped
 
-    def __sendMail(self, mailTo, url) :
+    def __sendMail(self, mailTo, result_id):
         """
         Send an e-mail containing an url to a batch job submitter.
 
@@ -91,8 +92,8 @@ class Scheduler() :
 
         @arg mailTo: The batch job submitter
         @type mailTo: unicode
-        @arg url: The url containing the results
-        @type url: unicode
+        @arg result_id: Identifier for the job result.
+        @type result_id: unicode
         """
         if settings.TESTING:
             return
@@ -105,6 +106,9 @@ class Scheduler() :
         #TODO: Handle Connection errors in a try, except clause
         #Expected errors: socket.error
 
+        download_url = website.url_for('batch_job_result',
+                                       result_id=result_id)
+
         message = MIMEText("""Dear submitter,
 
 The batch operation you have submitted, has been processed successfully.
@@ -116,7 +120,7 @@ Thanks for using Mutalyzer.
 
 
 With kind regards,
-Mutalyzer batch scheduler""" % url)
+Mutalyzer batch scheduler""" % download_url)
 
         message["Subject"] = "Result of your Mutalyzer batch job"
         message["From"] = settings.EMAIL
@@ -403,7 +407,7 @@ Mutalyzer batch scheduler""" % url)
                 else:
                     print ('Job %s finished, email %s file %s'
                            % (batch_job.id, batch_job.email, batch_job.id))
-                    self.__sendMail(batch_job.email, batch_job.download_url)
+                    self.__sendMail(batch_job.email, batch_job.result_id)
                     session.delete(batch_job)
                     session.commit()
     #process
@@ -729,8 +733,7 @@ Mutalyzer batch scheduler""" % url)
                      "Finished SNP converter batch rs%s" % cmd)
     #_processSNP
 
-    def addJob(self, email, queue, columns, job_type, argument=None,
-               create_download_url=None):
+    def addJob(self, email, queue, columns, job_type, argument=None):
         """
         Add a job to the Database and start the BatchChecker.
 
@@ -744,18 +747,12 @@ Mutalyzer batch scheduler""" % url)
         @type job_type:
         @arg argument:          Batch Arguments, for now only build info
         @type argument:
-        @arg create_download_url: Function accepting a result_id and returning
-                                  the URL for downloading the batch job
-                                  result. Can be None.
-        @type create_download_url: function
 
         @return: result_id
         @rtype:
         """
         # Add jobs to the database
         batch_job = BatchJob(job_type, email=email, argument=argument)
-        if create_download_url:
-            batch_job.download_url = create_download_url(batch_job.result_id)
         session.add(batch_job)
 
         for i, inputl in enumerate(queue):
diff --git a/mutalyzer/config/default_settings.py b/mutalyzer/config/default_settings.py
index 93d9d42b..4007fd0a 100644
--- a/mutalyzer/config/default_settings.py
+++ b/mutalyzer/config/default_settings.py
@@ -69,6 +69,10 @@ BATCH_JOBS_ERROR_THRESHOLD = 0.05
 # (in seconds).
 NEGATIVE_LINK_CACHE_EXPIRATION = 60 * 60 * 24 * 30
 
+# URL to the website root (without trailing slash). Used for generating
+# download links in the batch scheduler.
+WEBSITE_ROOT_URL = None
+
 # URL to the SOAP webservice WSDL document. Used to build the WSDL document
 # and for linking to it from the documentation page on the website.
 SOAP_WSDL_URL = None
diff --git a/mutalyzer/website/__init__.py b/mutalyzer/website/__init__.py
index 2ce0450b..285cdd03 100644
--- a/mutalyzer/website/__init__.py
+++ b/mutalyzer/website/__init__.py
@@ -8,6 +8,7 @@ from __future__ import unicode_literals
 import logging
 import os
 import pkg_resources
+import urlparse
 
 from flask import Flask
 
@@ -46,3 +47,22 @@ def create_app():
         session.remove()
 
     return app
+
+
+def url_for(endpoint, **values):
+    """
+    Generates a URL to the given website endpoint.
+
+    Like :func:`Flask.url_for`, but for when you don't have an application or
+    request context.
+
+    Note that the generated URL will be based on the `WEBSITE_ROOT_URL`
+    configuration setting or `http://localhost` if not set.
+
+    :arg str endpoint: The endpoint of the URL (name of the function).
+    :arg str values: The variable arguments of the URL rule.
+    """
+    root = urlparse.urlsplit(settings.WEBSITE_ROOT_URL or 'http://localhost')
+    url_map = create_app().url_map.bind(root.netloc, root.path or '/',
+                                        url_scheme=root.scheme)
+    return url_map.build('website.%s' % endpoint, values, force_external=True)
diff --git a/mutalyzer/website/views.py b/mutalyzer/website/views.py
index df1fa716..9fb3e4a3 100644
--- a/mutalyzer/website/views.py
+++ b/mutalyzer/website/views.py
@@ -937,15 +937,8 @@ def batch_jobs_submit():
             errors.append('Could not parse input file, please check your '
                           'file format.')
         else:
-            # Creates the result download URL from a job result_id.
-            def create_download_url(result_id):
-                return url_for('.batch_job_result',
-                               result_id=result_id,
-                               _external=True)
-
-            result_id = scheduler.addJob(
-                email, job, columns, job_type, argument=argument,
-                create_download_url=create_download_url)
+            result_id = scheduler.addJob(email, job, columns, job_type,
+                                         argument=argument)
 
             # Todo: We now assume that the job was not scheduled if there are
             #   messages, which is probably not correct.
-- 
GitLab