Completed
Push — develop ( 37a460...7c833f )
by
unknown
17s queued 14s
created

as_url_folder()   A

Complexity

Conditions 2

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
# -*- coding: utf-8 -*-
2
import datetime
3
import random
4
import string
5
from urllib.parse import urljoin
6
from urllib.parse import urlencode
7
8
from colour import Color
9
import pytz
10
from redis import Redis
11
from rq import Queue
12
import typing
13
14
if typing.TYPE_CHECKING:
15
    from tracim_backend.config import CFG
16
17
DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
18
DEFAULT_WEBDAV_CONFIG_FILE = "wsgidav.conf"
19
DEFAULT_TRACIM_CONFIG_FILE = "development.ini"
20
CONTENT_FRONTEND_URL_SCHEMA = 'workspaces/{workspace_id}/contents/{content_type}/{content_id}'  # nopep8
21
WORKSPACE_FRONTEND_URL_SCHEMA = 'workspaces/{workspace_id}'  # nopep8
22
FRONTEND_UI_SUBPATH = 'ui'
23
LOGIN_SUBPATH = 'login'
24
RESET_PASSWORD_SUBPATH = 'reset-password'
25
26
def generate_documentation_swagger_tag(*sections: str) -> str:
27
    """
28
    Generate documentation swagger tag according to section in order
29
    """
30
    return ' > '.join(sections)
31
32
33
def preview_manager_page_format(page_number: int) -> int:
34
    """
35
    Convert page real number of page(begin at 1) to preview_manager page
36
    format(begin at 0)
37
    """
38
    return page_number-1
39
40
41
def get_root_frontend_url(config: 'CFG') -> str:
42
    """
43
    Return website base url with always '/' at the end
44
    """
45
    return as_url_folder(config.WEBSITE_BASE_URL)
46
47
48
def get_frontend_ui_base_url(config: 'CFG') -> str:
49
    """
50
    Return ui base url
51
    """
52
    return as_url_folder(
53
        urljoin(get_root_frontend_url(config), FRONTEND_UI_SUBPATH)
54
    )
55
56
57
def get_login_frontend_url(config: 'CFG'):
58
    """
59
    Return login page url
60
    """
61
    return urljoin(get_frontend_ui_base_url(config), LOGIN_SUBPATH)
62
63
64
def get_reset_password_frontend_url(
65
    config: 'CFG',
66
    token: str,
67
    email: str,
68
) -> str:
69
    """
70
    Return reset password url
71
    """
72
    path = urljoin(get_frontend_ui_base_url(config), RESET_PASSWORD_SUBPATH)
73
    params = {
74
        'token': token,
75
        'email': email,
76
    }
77
78
    return '{path}?{params}'.format(path=path, params=urlencode(params))
79
80
81
def as_url_folder(url: str) -> str:
82
    if url[-1] != '/':
83
        url = '{}/'.format(url)
84
    return url
85
86
87
def get_email_logo_frontend_url(config: 'CFG'):
88
    # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for email_logo_frontend_url  # nopep8
89
    return 'data:image/png;base64,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'  # nopep8'
90
91
92
def get_redis_connection(config: 'CFG') -> Redis:
93
    """
94
    :param config: current app_config
95
    :return: redis connection
96
    """
97
    return Redis(
98
        host=config.EMAIL_SENDER_REDIS_HOST,
99
        port=config.EMAIL_SENDER_REDIS_PORT,
100
        db=config.EMAIL_SENDER_REDIS_DB,
101
    )
102
103
104
def get_rq_queue(redis_connection: Redis, queue_name: str ='default') -> Queue:
105
    """
106
    :param queue_name: name of queue
107
    :return: wanted queue
108
    """
109
110
    return Queue(name=queue_name, connection=redis_connection)
111
112
113
def cmp_to_key(mycmp):
114
    """
115
    List sort related function
116
117
    Convert a cmp= function into a key= function
118
    """
119
    class K(object):
120
        def __init__(self, obj, *args):
121
            self.obj = obj
122
123
        def __lt__(self, other):
124
            return mycmp(self.obj, other.obj) < 0
125
126
        def __gt__(self, other):
127
            return mycmp(self.obj, other.obj) > 0
128
129
        def __eq__(self, other):
130
            return mycmp(self.obj, other.obj) == 0
131
132
        def __le__(self, other):
133
            return mycmp(self.obj, other.obj) <= 0
134
135
        def __ge__(self, other):
136
            return mycmp(self.obj, other.obj) >= 0
137
138
        def __ne__(self, other):
139
            return mycmp(self.obj, other.obj) != 0
140
141
    return K
142
143
144
def current_date_for_filename() -> str:
145
    """
146
    ISO8601 current date, adapted to be used in filename (for
147
    webdav feature for example), with trouble-free characters.
148
    :return: current date as string like "2018-03-19T15.49.27.246592"
149
    """
150
    # INFO - G.M - 19-03-2018 - As ':' is in transform_to_bdd method in
151
    # webdav utils, it may cause trouble. So, it should be replaced to
152
    # a character which will not change in bdd.
153
    return datetime.datetime.now().isoformat().replace(':', '.')
154
155
156
class Timezone(object):
157
    def __init__(self, name):
158
        self.name = name
159
160
161
def get_timezones_list() -> typing.List[Timezone]:
162
    tz_list = []
163
    for tz_name in pytz.common_timezones:
164
        tz_list.append(Timezone(tz_name))
165
    return tz_list
166
167
# INFO - G.M - 2018-08-02 - Simple password generator, inspired by
168
# https://gist.github.com/23maverick23/4131896
169
170
171
ALLOWED_AUTOGEN_PASSWORD_CHAR = string.ascii_letters + \
172
                                string.digits + \
173
                                string.punctuation
174
175
DEFAULT_PASSWORD_GEN_CHAR_LENGTH = 12
176
177
178
def password_generator(
179
        length: int=DEFAULT_PASSWORD_GEN_CHAR_LENGTH,
180
        chars: str=ALLOWED_AUTOGEN_PASSWORD_CHAR
181
) -> str:
182
    """
183
    :param length: length of the new password
184
    :param chars: characters allowed
185
    :return: password as string
186
    """
187
    return ''.join(random.choice(chars) for char_number in range(length))
188
189
190
COLOR_DARKEN_SCALE_FACTOR = 0.85
191
COLOR_LIGHTEN_SCALE_FACTOR = 1.15
192
193
194
def clamp(val: float, minimum: float = 0.0, maximum: float=1.0) -> float:
195
    """ Fix value between min an max"""
196
    if val < minimum:
197
        return minimum
198
    if val > maximum:
199
        return maximum
200
    return val
201
202
203
class ExtendedColor(Color):
204
205
    @property
206
    def darken(self):
207
        new_color = ExtendedColor(self)
208
        new_color.luminance = clamp(COLOR_DARKEN_SCALE_FACTOR*self.luminance)
209
        return new_color
210
211
    @property
212
    def lighten(self):
213
        new_color = ExtendedColor(self)
214
        new_color.luminance = clamp(COLOR_LIGHTEN_SCALE_FACTOR*self.luminance)
215
        return new_color
216