Completed
Push — master ( 5c6346...98373c )
by Dieter
24:14 queued 24:14
created

buildtimetrend.get_repo_data_detail()   B

Complexity

Conditions 2

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
dl 0
loc 24
rs 8.9713
1
# vim: set expandtab sw=4 ts=4:
2
"""
3
Service related methods.
4
5
Copyright (C) 2014-2016 Dieter Adriaenssens <[email protected]>
6
7
This file is part of buildtimetrend/python-lib
8
<https://github.com/buildtimetrend/python-lib/>
9
10
This program is free software: you can redistribute it and/or modify
11
it under the terms of the GNU Affero General Public License as published by
12
the Free Software Foundation, either version 3 of the License, or
13
any later version.
14
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU Affero General Public License for more details.
19
20
You should have received a copy of the GNU Affero General Public License
21
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
"""
23
24
from __future__ import division
25
import cgi
26
from buildtimetrend import logger
27
from buildtimetrend.settings import Settings
28
from buildtimetrend.keenio import has_build_id
29
from buildtimetrend.keenio import keen_is_writable
30
31
32
def is_repo_allowed(repo):
33
    """
34
    Check if repo is allowed.
35
36
    A repository name is checked against a list of denied and allowed repos.
37
    The 'denied_repo' check takes precendence over 'allowed_repo' check.
38
    The list of denied/allowed repos is defined with settings 'denied_repo'
39
    and 'allowed_repo'.
40
    If the settings are not defined,
41
    the repo is not checked against the denied/allowed lists.
42
    Both 'denied_repo' and 'allowed_repo' can have multiple values,
43
    if any of them matches a substring of the repo, the repo is denied/allowed.
44
45
    Parameters:
46
    -repo : repository name
47
    """
48
    if repo is None:
49
        logger.warning("Repo is not defined")
50
        return False
51
52
    denied_message = "Project '%s' is not allowed."
53
    denied_repo = Settings().get_setting("denied_repo")
54
    allowed_repo = Settings().get_setting("allowed_repo")
55
56
    if denied_repo is not None and \
57
            any(x in repo for x in denied_repo) or \
58
            allowed_repo is not None and \
59
            not any(x in repo for x in allowed_repo):
60
        logger.warning(denied_message, repo)
61
        return False
62
63
    return True
64
65
66
def get_repo_data_detail(repo):
67
    """
68
    Get level of data detail storage of a repo.
69
70
    A repository name is checked against a list of repository names.
71
    If a match is found, the corresponding data detail level is used.
72
    Else, the default global setting is returned.
73
74
    Parameters:
75
    -repo : repository name
76
    """
77
    if repo is None:
78
        logger.warning("Repo is not defined")
79
80
81
    #repo_list = Settings().get_setting("repo_data_detail")
82
    #if denied_repo is not None and \
83
    #        any(x in repo for x in denied_repo) or \
84
    #        allowed_repo is not None and \
85
    #        not any(x in repo for x in allowed_repo):
86
    #    return False
87
88
    # return default global data_detail setting
89
    return Settings().get_setting("data_detail")
90
91
92
def format_duration(duration):
93
    """
94
    Format duration from seconds to hours, minutes and seconds.
95
96
    Parameters:
97
    - duration : duration in seconds
98
    """
99
    if not isinstance(duration, (float, int)) or duration < 0:
100
        return "unknown"
101
102
    # round duration
103
    duration = round(duration)
104
105
    seconds = int(duration % 60)
106
    duration = duration / 60
107
    format_string = "{:d}s".format(seconds)
108
109
    if duration >= 1:
110
        minutes = int(duration % 60)
111
        duration = duration / 60
112
        format_string = "{:d}m {:s}".format(minutes, format_string)
113
114
        if duration >= 1:
115
            hours = int(duration % 60)
116
            format_string = "{:d}h {:s}".format(hours, format_string)
117
118
    return format_string
119
120
121
def check_process_parameters(repo=None, build=None):
122
    """
123
    Process setup parameters.
124
125
    Deprecated : functionality is split into
126
    validate_travis_request() and validate_task_parameters()
127
128
    Check parameters (repo and build)
129
    Returns error message, None when all parameters are fine
130
    """
131
    ret_val = validate_travis_request(repo, build)
132
    if ret_val is not None:
133
        return ret_val
134
    return validate_task_parameters(repo, build)
135
136
137
def validate_travis_request(repo=None, build=None):
138
    """
139
    Validate repo and build parameters of travis web request.
140
141
    Check parameters (repo and build)
142
    Returns error message, None when all parameters are fine.
143
    """
144
    if repo is None or build is None:
145
        logger.warning("Repo or build number are not set")
146
        return "Repo or build are not set, format : " \
147
            "/travis/<repo_owner>/<repo_name>/<build>"
148
149
    # check if repo is allowed
150
    if not is_repo_allowed(repo):
151
        return "Project '{}' is not allowed.".format(cgi.escape(repo))
152
153
    return None
154
155
156
def validate_task_parameters(repo=None, build=None):
157
    """
158
    Validate repo and build parameters of process_travis_buildlog().
159
160
    Check parameters (repo and build)
161
    Returns error message, None when all parameters are fine.
162
    """
163
    if not keen_is_writable():
164
        return "Keen IO write key not set, no data was sent"
165
166
    try:
167
        if has_build_id(repo, build):
168
            template = "Build #{build} of project {repo} " \
169
                "already exists in database"
170
            return template.format(
171
                build=cgi.escape(str(build)), repo=cgi.escape(str(repo))
172
            )
173
    except Exception as msg:
174
        # Raise last exception again
175
        logger.error("Error checking if build exists : %s", msg)
176
        raise SystemError("Error checking if build exists.")
177
178
    return None
179