Diff of /qiita_pet/util.py [000000] .. [879b32]

Switch to unified view

a b/qiita_pet/util.py
1
r"""
2
Util functions (:mod: `qiita_pet.util`)
3
======================================
4
5
..currentmodule:: qiita_pet.util
6
7
This module provides different util functions for qiita_pet.
8
9
Methods
10
-------
11
12
..autosummary::
13
    :toctree: generated/
14
15
    clean_str
16
"""
17
# -----------------------------------------------------------------------------
18
# Copyright (c) 2014--, The Qiita Development Team.
19
#
20
# Distributed under the terms of the BSD 3-clause License.
21
#
22
# The full license is in the file LICENSE, distributed with this software.
23
# -----------------------------------------------------------------------------
24
from tornado.escape import linkify as tornado_linkify, xhtml_unescape
25
26
from qiita_core.util import execute_as_transaction
27
from qiita_db.reference import Reference
28
29
30
STATUS_STYLER = {
31
    'sandbox':
32
        ('glyphicon glyphicon-eye-close', 'glyphicon glyphicon-lock', 'gray'),
33
    'awaiting_approval':
34
        ('glyphicon glyphicon-eye-open', 'glyphicon glyphicon-lock', 'peru'),
35
    'private':
36
        ('glyphicon glyphicon-eye-open', 'glyphicon glyphicon-lock',
37
         '#3599FD'),
38
    'public':
39
        ('glyphicon glyphicon-eye-open', 'glyphicon glyphicon-globe', 'green')}
40
41
EBI_LINKIFIER = ('<a href="http://www.ebi.ac.uk/ena/data/view/{0}" '
42
                 'target="_blank">{0}</a>')
43
44
45
def linkify(link_template, item):
46
    """Formats a strings into a URL using string replacement
47
48
    Paramters
49
    ---------
50
    link_template : str
51
        The template for the URL.
52
    item : list or tuple of str
53
        The strings that will be inserted into the template
54
    """
55
    return link_template.format(*item)
56
57
58
def clean_str(item):
59
    """Converts input to string and replaces spaces with underscores
60
61
    Parameters
62
    ----------
63
    item : anything convertable to string
64
        item to convert and clean
65
66
    Returns
67
    -------
68
    str
69
        cleaned string
70
    """
71
    return str(item).replace(" ", "_").replace(":", "")
72
73
74
def convert_text_html(message):
75
    """Linkify URLs and turn newlines into <br/> for HTML"""
76
    html = xhtml_unescape(tornado_linkify(message))
77
    return html.replace('\n', '<br/>')
78
79
80
@execute_as_transaction
81
def generate_param_str(param):
82
    """Generate an html string with the parameter values
83
84
    Parameters
85
    ----------
86
    param : BaseParameters
87
        The parameter to generate the str
88
89
    Returns
90
    -------
91
    str
92
        The html string with the parameter set values
93
    """
94
    values = param.values
95
    ref = Reference(values['reference'])
96
    result = ["<b>Reference:</b> %s %s" % (ref.name, ref.version)]
97
    result.extend("<b>%s:</b> %s" % (name, value)
98
                  for name, value in values.items()
99
                  if name != 'reference')
100
    return "<br/>".join(result)
101
102
103
def is_localhost(host):
104
    """Verifies if the connection is local
105
106
    Parameters
107
    ----------
108
    host : str
109
        The requesting host, in general self.request.headers['host']
110
111
    Returns
112
    -------
113
    bool
114
        True if local request
115
    """
116
    localhost = ('localhost', '127.0.0.1')
117
    return host.startswith(localhost)
118
119
120
def get_artifact_processing_status(artifact):
121
    """Gets the processing status of the artifact
122
123
    Parameters
124
    ----------
125
    artifact : qiita_db.artifact.Artifact
126
        The artifact to get the processing status
127
128
    Returns
129
    -------
130
    str, str
131
        The processing status {'processing', 'failed', 'success',
132
            'Not processed'}
133
        A summary of the jobs attached to the artifact
134
    """
135
    preprocessing_status = 'Not processed'
136
    preprocessing_status_msg = []
137
    for job in artifact.jobs():
138
        job_status = job.status
139
        if job_status == 'error':
140
            if preprocessing_status != 'success':
141
                preprocessing_status = 'failed'
142
            preprocessing_status_msg.append(
143
                "<b>Job %s</b>: failed - %s"
144
                % (job.id, job.log.msg))
145
        elif job_status == 'success':
146
            preprocessing_status = 'success'
147
        else:
148
            if preprocessing_status != 'success':
149
                preprocessing_status = 'processing'
150
            preprocessing_status_msg.append(
151
                "<b>Job %s</b>: %s" % (job.id, job_status))
152
153
    if not preprocessing_status_msg:
154
        preprocessing_status_msg = 'Not processed'
155
    else:
156
        preprocessing_status_msg = convert_text_html(
157
            '<br/>'.join(preprocessing_status_msg))
158
159
    return preprocessing_status, preprocessing_status_msg
160
161
162
def get_network_nodes_edges(graph, full_access, nodes=None, edges=None):
163
    """Returns the JavaScript friendly representation of the graph
164
165
    Parameters
166
    ----------
167
    graph : networkx.DiGraph
168
        The artifact/jobs graph
169
    full_access : bool
170
        Whether the user has full access to the graph or not
171
    nodes : list, optional
172
        A pre-populated list of nodes. Useful for the analysis pipeline
173
    edges : list, optional
174
        A pre-populated list of edges. Useful for the analysis pipeline
175
176
    Returns
177
    -------
178
    (list, list, int)
179
        The list of nodes, the list of edges, and the worklfow id if there is
180
        any job on construction
181
    """
182
    nodes = nodes if nodes is not None else []
183
    edges = edges if edges is not None else []
184
    workflow_id = None
185
186
    # n[0] is the data type: job/artifact/type
187
    # n[1] is the object
188
    for n in graph.nodes():
189
        if n[0] == 'job':
190
            # ignoring internal Jobs
191
            if n[1].command.software.name == 'Qiita':
192
                continue
193
            atype = 'job'
194
            name = n[1].command.name
195
            status = n[1].status
196
            wkflow = n[1].processing_job_workflow
197
            if status == 'in_construction' and wkflow is not None:
198
                workflow_id = wkflow.id
199
        elif n[0] == 'artifact':
200
            atype = n[1].artifact_type
201
            status = 'artifact'
202
            pp = n[1].processing_parameters
203
            if pp is not None:
204
                cmd = pp.command
205
                if cmd.software.deprecated:
206
                    status = 'deprecated'
207
                elif not cmd.active:
208
                    status = 'outdated'
209
            if full_access or n[1].visibility == 'public':
210
                name = '%s\n(%s)' % (n[1].name, n[1].artifact_type)
211
            else:
212
                continue
213
        elif n[0] == 'type':
214
            atype = n[1].type
215
            name = '%s\n(%s)' % (n[1].name, n[1].type)
216
            status = 'type'
217
        else:
218
            # this should never happen but let's add it just in case
219
            raise ValueError('not valid node type: %s' % n[0])
220
        nodes.append((n[0], atype, n[1].id, name, status))
221
222
    edges.extend([(n[1].id, m[1].id) for n, m in graph.edges()])
223
224
    return nodes, edges, workflow_id