Passed
Pull Request — develop (#44)
by inkhey
03:32
created

tracim_backend.lib.utils.utils.clamp()   A

Complexity

Conditions 3

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 3
nop 3
1
# -*- coding: utf-8 -*-
2
import datetime
3
import random
4
import string
5
from colour import Color
6
import pytz
7
from redis import Redis
8
from rq import Queue
9
import typing
10
if typing.TYPE_CHECKING:
11
    from tracim_backend.config import CFG
12
13
DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
14
DEFAULT_WEBDAV_CONFIG_FILE = "wsgidav.conf"
15
DEFAULT_TRACIM_CONFIG_FILE = "development.ini"
16
CONTENT_FRONTEND_URL_SCHEMA = 'workspaces/{workspace_id}/contents/{content_type}/{content_id}'  # nopep8
17
WORKSPACE_FRONTEND_URL_SCHEMA = 'workspaces/{workspace_id}'  # nopep8
18
19
20
def get_root_frontend_url(config: 'CFG') -> str:
21
    """
22
    Return website base url with always '/' at the end
23
    """
24
    base_url = ''
25
    if config.WEBSITE_BASE_URL[-1] == '/':
26
        base_url = config.WEBSITE_BASE_URL
27
    else:
28
        base_url = config.WEBSITE_BASE_URL + '/'
29
    return base_url
30
31
32
def get_login_frontend_url(config: 'CFG'):
33
    """
34
    Return login page url
35
    """
36
    return get_root_frontend_url(config) + 'login'
37
38
39
def get_email_logo_frontend_url(config: 'CFG'):
40
    # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for email_logo_frontend_url  # nopep8
41
    return 'data:image/png;base64,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'  # nopep8'
42
43
44
def get_redis_connection(config: 'CFG') -> Redis:
45
    """
46
    :param config: current app_config
47
    :return: redis connection
48
    """
49
    return Redis(
50
        host=config.EMAIL_SENDER_REDIS_HOST,
51
        port=config.EMAIL_SENDER_REDIS_PORT,
52
        db=config.EMAIL_SENDER_REDIS_DB,
53
    )
54
55
56
def get_rq_queue(redis_connection: Redis, queue_name: str ='default') -> Queue:
57
    """
58
    :param queue_name: name of queue
59
    :return: wanted queue
60
    """
61
62
    return Queue(name=queue_name, connection=redis_connection)
63
64
65
def cmp_to_key(mycmp):
66
    """
67
    List sort related function
68
69
    Convert a cmp= function into a key= function
70
    """
71
    class K(object):
72
        def __init__(self, obj, *args):
73
            self.obj = obj
74
75
        def __lt__(self, other):
76
            return mycmp(self.obj, other.obj) < 0
77
78
        def __gt__(self, other):
79
            return mycmp(self.obj, other.obj) > 0
80
81
        def __eq__(self, other):
82
            return mycmp(self.obj, other.obj) == 0
83
84
        def __le__(self, other):
85
            return mycmp(self.obj, other.obj) <= 0
86
87
        def __ge__(self, other):
88
            return mycmp(self.obj, other.obj) >= 0
89
90
        def __ne__(self, other):
91
            return mycmp(self.obj, other.obj) != 0
92
93
    return K
94
95
96
def current_date_for_filename() -> str:
97
    """
98
    ISO8601 current date, adapted to be used in filename (for
99
    webdav feature for example), with trouble-free characters.
100
    :return: current date as string like "2018-03-19T15.49.27.246592"
101
    """
102
    # INFO - G.M - 19-03-2018 - As ':' is in transform_to_bdd method in
103
    # webdav utils, it may cause trouble. So, it should be replaced to
104
    # a character which will not change in bdd.
105
    return datetime.datetime.now().isoformat().replace(':', '.')
106
107
108
class Timezone(object):
109
    def __init__(self, name):
110
        self.name = name
111
112
113
def get_timezones_list() -> typing.List[Timezone]:
114
    tz_list = []
115
    for tz_name in pytz.common_timezones:
116
        tz_list.append(Timezone(tz_name))
117
    return tz_list
118
119
# INFO - G.M - 2018-08-02 - Simple password generator, inspired by
120
# https://gist.github.com/23maverick23/4131896
121
122
123
ALLOWED_AUTOGEN_PASSWORD_CHAR = string.ascii_letters + \
124
                                string.digits + \
125
                                string.punctuation
126
127
DEFAULT_PASSWORD_GEN_CHAR_LENGTH = 12
128
129
130
def password_generator(
131
        length: int=DEFAULT_PASSWORD_GEN_CHAR_LENGTH,
132
        chars: str=ALLOWED_AUTOGEN_PASSWORD_CHAR
133
) -> str:
134
    """
135
    :param length: length of the new password
136
    :param chars: characters allowed
137
    :return: password as string
138
    """
139
    return ''.join(random.choice(chars) for char_number in range(length))
140
141
142
COLOR_DARKEN_SCALE_FACTOR = 0.85
143
COLOR_LIGHTEN_SCALE_FACTOR = 1.15
144
145
146
class ExtendedColor(Color):
147
148
    @property
149
    def darken(self):
150
        new_color = Color(self)
151
        new_color.luminance = COLOR_DARKEN_SCALE_FACTOR*self.luminance
152
        return new_color
153
154
    @property
155
    def lighten(self):
156
        new_color = Color(self)
157
        new_color.luminance = COLOR_LIGHTEN_SCALE_FACTOR*self.luminance
158
        return new_color
159