##// END OF EJS Templates
Extracted some magic strings
neko259 -
r2002:a3d63355 default
parent child Browse files
Show More
@@ -1,33 +1,41 b''
1 import configparser
1 import configparser
2
2
3
3
4 CONFIG_DEFAULT_SETTINGS = 'boards/config/default_settings.ini'
4 CONFIG_DEFAULT_SETTINGS = 'boards/config/default_settings.ini'
5 CONFIG_SETTINGS = 'boards/config/settings.ini'
5 CONFIG_SETTINGS = 'boards/config/settings.ini'
6
6
7
7
8 SECTION_FORMS = 'Forms'
9
10 VALUE_TRUE = 'true'
11
12 LIST_DELIMITER = ','
13 DICT_DELIMITER = ':'
14
15
8 config = configparser.ConfigParser()
16 config = configparser.ConfigParser()
9 config.read(CONFIG_DEFAULT_SETTINGS)
17 config.read(CONFIG_DEFAULT_SETTINGS)
10 config.read(CONFIG_SETTINGS)
18 config.read(CONFIG_SETTINGS)
11
19
12
20
13 def get(section, name):
21 def get(section, name):
14 return config[section][name]
22 return config[section][name]
15
23
16
24
17 def get_int(section, name):
25 def get_int(section, name):
18 return int(get(section, name))
26 return int(get(section, name))
19
27
20
28
21 def get_bool(section, name):
29 def get_bool(section, name):
22 return get(section, name) == 'true'
30 return get(section, name) == VALUE_TRUE
23
31
24
32
25 def get_list_dict(section, name):
33 def get_list_dict(section, name):
26 str_dict = get(section, name)
34 str_dict = get(section, name)
27 return [item.split(':') for item in str_dict.split(',')]
35 return [item.split(DICT_DELIMITER) for item in str_dict.split(LIST_DELIMITER)]
28
36
29
37
30 def get_list(section, name):
38 def get_list(section, name):
31 str_list = get(section, name)
39 str_list = get(section, name)
32 return str_list.split(',')
40 return str_list.split(LIST_DELIMITER)
33
41
@@ -1,157 +1,161 b''
1 """
1 """
2 This module contains helper functions and helper classes.
2 This module contains helper functions and helper classes.
3 """
3 """
4 import time
4 import time
5 import uuid
5 import uuid
6
6
7 import hashlib
7 import hashlib
8 import magic
8 import magic
9 import os
9 import os
10 from django import forms
10 from django import forms
11 from django.core.cache import cache
11 from django.core.cache import cache
12 from django.db.models import Model
12 from django.db.models import Model
13 from django.template.defaultfilters import filesizeformat
13 from django.template.defaultfilters import filesizeformat
14 from django.utils import timezone
14 from django.utils import timezone
15 from django.utils.translation import ugettext_lazy as _
15 from django.utils.translation import ugettext_lazy as _
16
16
17 import boards
17 import boards
18 from neboard import settings
18 from neboard import settings
19 from boards.abstracts.constants import FILE_DIRECTORY
19 from boards.abstracts.constants import FILE_DIRECTORY
20 from boards.settings import get_bool
20 from boards.settings import get_bool
21
21
22 CACHE_KEY_DELIMITER = '_'
22 CACHE_KEY_DELIMITER = '_'
23
23
24 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
24 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
25 META_REMOTE_ADDR = 'REMOTE_ADDR'
25 META_REMOTE_ADDR = 'REMOTE_ADDR'
26
26
27 SETTING_MESSAGES = 'Messages'
27 SETTING_MESSAGES = 'Messages'
28 SETTING_ANON_MODE = 'AnonymousMode'
28 SETTING_ANON_MODE = 'AnonymousMode'
29
29
30 ANON_IP = '127.0.0.1'
30 ANON_IP = '127.0.0.1'
31
31
32 FILE_EXTENSION_DELIMITER = '.'
32 FILE_EXTENSION_DELIMITER = '.'
33 URL_DELIMITER = '/'
34 CACHE_KEY_DELIMITER = ':'
35
36 DEFAULT_MIMETYPE = 'application/octet-stream'
33
37
34
38
35 def is_anonymous_mode():
39 def is_anonymous_mode():
36 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
40 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
37
41
38
42
39 def get_client_ip(request):
43 def get_client_ip(request):
40 if is_anonymous_mode():
44 if is_anonymous_mode():
41 ip = ANON_IP
45 ip = ANON_IP
42 else:
46 else:
43 x_forwarded_for = request.META.get(HTTP_FORWARDED)
47 x_forwarded_for = request.META.get(HTTP_FORWARDED)
44 if x_forwarded_for:
48 if x_forwarded_for:
45 ip = x_forwarded_for.split(',')[-1].strip()
49 ip = x_forwarded_for.split(',')[-1].strip()
46 else:
50 else:
47 ip = request.META.get(META_REMOTE_ADDR)
51 ip = request.META.get(META_REMOTE_ADDR)
48 return ip
52 return ip
49
53
50
54
51 # TODO The output format is not epoch because it includes microseconds
55 # TODO The output format is not epoch because it includes microseconds
52 def datetime_to_epoch(datetime):
56 def datetime_to_epoch(datetime):
53 return int(time.mktime(timezone.localtime(
57 return int(time.mktime(timezone.localtime(
54 datetime,timezone.get_current_timezone()).timetuple())
58 datetime,timezone.get_current_timezone()).timetuple())
55 * 1000000 + datetime.microsecond)
59 * 1000000 + datetime.microsecond)
56
60
57
61
58 # TODO Test this carefully
62 # TODO Test this carefully
59 def cached_result(key_method=None):
63 def cached_result(key_method=None):
60 """
64 """
61 Caches method result in the Django's cache system, persisted by object name,
65 Caches method result in the Django's cache system, persisted by object name,
62 object name, model id if object is a Django model, args and kwargs if any.
66 object name, model id if object is a Django model, args and kwargs if any.
63 """
67 """
64 def _cached_result(function):
68 def _cached_result(function):
65 def inner_func(obj, *args, **kwargs):
69 def inner_func(obj, *args, **kwargs):
66 cache_key_params = [obj.__class__.__name__, function.__name__]
70 cache_key_params = [obj.__class__.__name__, function.__name__]
67
71
68 cache_key_params += args
72 cache_key_params += args
69 for key, value in kwargs:
73 for key, value in kwargs:
70 cache_key_params.append(key + ':' + value)
74 cache_key_params.append(key + CACHE_KEY_DELIMITER + value)
71
75
72 if isinstance(obj, Model):
76 if isinstance(obj, Model):
73 cache_key_params.append(str(obj.id))
77 cache_key_params.append(str(obj.id))
74
78
75 if key_method is not None:
79 if key_method is not None:
76 cache_key_params += [str(arg) for arg in key_method(obj)]
80 cache_key_params += [str(arg) for arg in key_method(obj)]
77
81
78 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
82 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
79
83
80 persisted_result = cache.get(cache_key)
84 persisted_result = cache.get(cache_key)
81 if persisted_result is not None:
85 if persisted_result is not None:
82 result = persisted_result
86 result = persisted_result
83 else:
87 else:
84 result = function(obj, *args, **kwargs)
88 result = function(obj, *args, **kwargs)
85 if result is not None:
89 if result is not None:
86 cache.set(cache_key, result)
90 cache.set(cache_key, result)
87
91
88 return result
92 return result
89
93
90 return inner_func
94 return inner_func
91 return _cached_result
95 return _cached_result
92
96
93
97
94 def get_file_hash(file) -> str:
98 def get_file_hash(file) -> str:
95 md5 = hashlib.md5()
99 md5 = hashlib.md5()
96 for chunk in file.chunks():
100 for chunk in file.chunks():
97 md5.update(chunk)
101 md5.update(chunk)
98 return md5.hexdigest()
102 return md5.hexdigest()
99
103
100
104
101 def validate_file_size(size: int):
105 def validate_file_size(size: int):
102 max_size = boards.settings.get_int('Forms', 'MaxFileSize')
106 max_size = boards.settings.get_int('Forms', 'MaxFileSize')
103 if 0 < max_size < size:
107 if 0 < max_size < size:
104 raise forms.ValidationError(
108 raise forms.ValidationError(
105 _('Total file size must be less than %s but is %s.')
109 _('Total file size must be less than %s but is %s.')
106 % (filesizeformat(max_size), filesizeformat(size)))
110 % (filesizeformat(max_size), filesizeformat(size)))
107
111
108
112
109 def get_extension(filename):
113 def get_extension(filename):
110 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
114 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
111
115
112
116
113 def get_upload_filename(model_instance, old_filename):
117 def get_upload_filename(model_instance, old_filename):
114 extension = get_extension(old_filename)
118 extension = get_extension(old_filename)
115 new_name = '{}.{}'.format(uuid.uuid4(), extension)
119 new_name = '{}.{}'.format(uuid.uuid4(), extension)
116
120
117 # Create 2 directories to split the files because holding many files in
121 # Create 2 directories to split the files because holding many files in
118 # one directory may impact performance
122 # one directory may impact performance
119 dir1 = new_name[0]
123 dir1 = new_name[0]
120 dir2 = new_name[1]
124 dir2 = new_name[1]
121
125
122 return os.path.join(FILE_DIRECTORY, dir1, dir2, new_name)
126 return os.path.join(FILE_DIRECTORY, dir1, dir2, new_name)
123
127
124
128
125 def get_file_mimetype(file) -> str:
129 def get_file_mimetype(file) -> str:
126 buf = b''
130 buf = b''
127 for chunk in file.chunks():
131 for chunk in file.chunks():
128 buf += chunk
132 buf += chunk
129
133
130 file_type = magic.from_buffer(buf, mime=True)
134 file_type = magic.from_buffer(buf, mime=True)
131 if file_type is None:
135 if file_type is None:
132 file_type = 'application/octet-stream'
136 file_type = DEFAULT_MIMETYPE
133 elif type(file_type) == bytes:
137 elif type(file_type) == bytes:
134 file_type = file_type.decode()
138 file_type = file_type.decode()
135 return file_type
139 return file_type
136
140
137
141
138 def get_domain(url: str) -> str:
142 def get_domain(url: str) -> str:
139 """
143 """
140 Gets domain from an URL with random number of domain levels.
144 Gets domain from an URL with random number of domain levels.
141 """
145 """
142 domain_parts = url.split('/')
146 domain_parts = url.split(URL_DELIMITER)
143 if len(domain_parts) >= 2:
147 if len(domain_parts) >= 2:
144 full_domain = domain_parts[2]
148 full_domain = domain_parts[2]
145 else:
149 else:
146 full_domain = ''
150 full_domain = ''
147
151
148 return full_domain
152 return full_domain
149
153
150
154
151 def get_tripcode_from_text(text: str) -> str:
155 def get_tripcode_from_text(text: str) -> str:
152 tripcode = ''
156 tripcode = ''
153 if text:
157 if text:
154 code = text + settings.SECRET_KEY
158 code = text + settings.SECRET_KEY
155 tripcode = hashlib.md5(code.encode()).hexdigest()
159 tripcode = hashlib.md5(code.encode()).hexdigest()
156 return tripcode
160 return tripcode
157
161
General Comments 0
You need to be logged in to leave comments. Login now