##// END OF EJS Templates
Use generic django sessions, not specifically neboard ones
neko259 -
r2068:24da88f2 default
parent child Browse files
Show More
@@ -1,159 +1,159 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 django.conf 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, SECTION_FORMS
20 from boards.settings import get_bool, SECTION_FORMS
21
21
22 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
22 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
23 META_REMOTE_ADDR = 'REMOTE_ADDR'
23 META_REMOTE_ADDR = 'REMOTE_ADDR'
24
24
25 SETTING_MESSAGES = 'Messages'
25 SETTING_MESSAGES = 'Messages'
26 SETTING_ANON_MODE = 'AnonymousMode'
26 SETTING_ANON_MODE = 'AnonymousMode'
27
27
28 ANON_IP = '127.0.0.1'
28 ANON_IP = '127.0.0.1'
29
29
30 FILE_EXTENSION_DELIMITER = '.'
30 FILE_EXTENSION_DELIMITER = '.'
31 URL_DELIMITER = '/'
31 URL_DELIMITER = '/'
32
32
33 CACHE_PARAMS = '{}:{}'
33 CACHE_PARAMS = '{}:{}'
34 CACHE_KEY_DELIMITER = '_'
34 CACHE_KEY_DELIMITER = '_'
35
35
36 DEFAULT_MIMETYPE = 'application/octet-stream'
36 DEFAULT_MIMETYPE = 'application/octet-stream'
37
37
38
38
39 def is_anonymous_mode():
39 def is_anonymous_mode():
40 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
40 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
41
41
42
42
43 def get_client_ip(request):
43 def get_client_ip(request):
44 if is_anonymous_mode():
44 if is_anonymous_mode():
45 ip = ANON_IP
45 ip = ANON_IP
46 else:
46 else:
47 x_forwarded_for = request.META.get(HTTP_FORWARDED)
47 x_forwarded_for = request.META.get(HTTP_FORWARDED)
48 if x_forwarded_for:
48 if x_forwarded_for:
49 ip = x_forwarded_for.split(',')[-1].strip()
49 ip = x_forwarded_for.split(',')[-1].strip()
50 else:
50 else:
51 ip = request.META.get(META_REMOTE_ADDR)
51 ip = request.META.get(META_REMOTE_ADDR)
52 return ip
52 return ip
53
53
54
54
55 # TODO The output format is not epoch because it includes microseconds
55 # TODO The output format is not epoch because it includes microseconds
56 def datetime_to_epoch(datetime):
56 def datetime_to_epoch(datetime):
57 return int(time.mktime(timezone.localtime(
57 return int(time.mktime(timezone.localtime(
58 datetime,timezone.get_current_timezone()).timetuple())
58 datetime,timezone.get_current_timezone()).timetuple())
59 * 1000000 + datetime.microsecond)
59 * 1000000 + datetime.microsecond)
60
60
61
61
62 # TODO Test this carefully
62 # TODO Test this carefully
63 def cached_result(key_method=None):
63 def cached_result(key_method=None):
64 """
64 """
65 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,
66 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.
67 """
67 """
68 def _cached_result(function):
68 def _cached_result(function):
69 def inner_func(obj, *args, **kwargs):
69 def inner_func(obj, *args, **kwargs):
70 cache_key_params = [obj.__class__.__name__, function.__name__]
70 cache_key_params = [obj.__class__.__name__, function.__name__]
71
71
72 cache_key_params += args
72 cache_key_params += args
73 for key, value in kwargs:
73 for key, value in kwargs:
74 cache_key_params.append(CACHE_PARAMS.format(key, value))
74 cache_key_params.append(CACHE_PARAMS.format(key, value))
75
75
76 if isinstance(obj, Model):
76 if isinstance(obj, Model):
77 cache_key_params.append(str(obj.id))
77 cache_key_params.append(str(obj.id))
78
78
79 if key_method is not None:
79 if key_method is not None:
80 cache_key_params += [str(arg) for arg in key_method(obj)]
80 cache_key_params += [str(arg) for arg in key_method(obj)]
81
81
82 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
82 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
83
83
84 result = cache.get(cache_key)
84 result = cache.get(cache_key)
85 if result is None:
85 if result is None:
86 result = function(obj, *args, **kwargs)
86 result = function(obj, *args, **kwargs)
87 if result is not None:
87 if result is not None:
88 cache.set(cache_key, result)
88 cache.set(cache_key, result)
89
89
90 return result
90 return result
91
91
92 return inner_func
92 return inner_func
93 return _cached_result
93 return _cached_result
94
94
95
95
96 def get_file_hash(file) -> str:
96 def get_file_hash(file) -> str:
97 md5 = hashlib.md5()
97 md5 = hashlib.md5()
98 for chunk in file.chunks():
98 for chunk in file.chunks():
99 md5.update(chunk)
99 md5.update(chunk)
100 return md5.hexdigest()
100 return md5.hexdigest()
101
101
102
102
103 def validate_file_size(size: int):
103 def validate_file_size(size: int):
104 max_size = boards.settings.get_int(SECTION_FORMS, 'MaxFileSize')
104 max_size = boards.settings.get_int(SECTION_FORMS, 'MaxFileSize')
105 if 0 < max_size < size:
105 if 0 < max_size < size:
106 raise forms.ValidationError(
106 raise forms.ValidationError(
107 _('Total file size must be less than %s but is %s.')
107 _('Total file size must be less than %s but is %s.')
108 % (filesizeformat(max_size), filesizeformat(size)))
108 % (filesizeformat(max_size), filesizeformat(size)))
109
109
110
110
111 def get_extension(filename):
111 def get_extension(filename):
112 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
112 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
113
113
114
114
115 def get_upload_filename(model_instance, old_filename):
115 def get_upload_filename(model_instance, old_filename):
116 extension = get_extension(old_filename)
116 extension = get_extension(old_filename)
117 new_name = '{}.{}'.format(uuid.uuid4(), extension)
117 new_name = '{}.{}'.format(uuid.uuid4(), extension)
118
118
119 # Create 2 directories to split the files because holding many files in
119 # Create 2 directories to split the files because holding many files in
120 # one directory may impact performance
120 # one directory may impact performance
121 dir1 = new_name[0]
121 dir1 = new_name[0]
122 dir2 = new_name[1]
122 dir2 = new_name[1]
123
123
124 return os.path.join(FILE_DIRECTORY, dir1, dir2, new_name)
124 return os.path.join(FILE_DIRECTORY, dir1, dir2, new_name)
125
125
126
126
127 def get_file_mimetype(file) -> str:
127 def get_file_mimetype(file) -> str:
128 buf = b''
128 buf = b''
129 for chunk in file.chunks():
129 for chunk in file.chunks():
130 buf += chunk
130 buf += chunk
131
131
132 file_type = magic.from_buffer(buf, mime=True)
132 file_type = magic.from_buffer(buf, mime=True)
133 if file_type is None:
133 if file_type is None:
134 file_type = DEFAULT_MIMETYPE
134 file_type = DEFAULT_MIMETYPE
135 elif type(file_type) == bytes:
135 elif type(file_type) == bytes:
136 file_type = file_type.decode()
136 file_type = file_type.decode()
137 return file_type
137 return file_type
138
138
139
139
140 def get_domain(url: str) -> str:
140 def get_domain(url: str) -> str:
141 """
141 """
142 Gets domain from an URL with random number of domain levels.
142 Gets domain from an URL with random number of domain levels.
143 """
143 """
144 domain_parts = url.split(URL_DELIMITER)
144 domain_parts = url.split(URL_DELIMITER)
145 if len(domain_parts) >= 2:
145 if len(domain_parts) >= 2:
146 full_domain = domain_parts[2]
146 full_domain = domain_parts[2]
147 else:
147 else:
148 full_domain = ''
148 full_domain = ''
149
149
150 return full_domain
150 return full_domain
151
151
152
152
153 def get_tripcode_from_text(text: str) -> str:
153 def get_tripcode_from_text(text: str) -> str:
154 tripcode = ''
154 tripcode = ''
155 if text:
155 if text:
156 code = text + settings.SECRET_KEY
156 code = text + settings.SECRET_KEY
157 tripcode = hashlib.md5(code.encode()).hexdigest()
157 tripcode = hashlib.md5(code.encode()).hexdigest()
158 return tripcode
158 return tripcode
159
159
@@ -1,24 +1,24 b''
1 from django.conf.urls import include, url
1 from django.conf.urls import include, url
2
2
3 # Uncomment the next two lines to enable the admin:
3 # Uncomment the next two lines to enable the admin:
4 from django.conf.urls.static import static
4 from django.conf.urls.static import static
5 from django.contrib import admin
5 from django.contrib import admin
6 from neboard import settings
6 from django.conf import settings
7
7
8 from boards.views.not_found import NotFoundView
8 from boards.views.not_found import NotFoundView
9
9
10 admin.autodiscover()
10 admin.autodiscover()
11
11
12 urlpatterns = [
12 urlpatterns = [
13 # Uncomment the admin/doc line below to enable admin documentation:
13 # Uncomment the admin/doc line below to enable admin documentation:
14 # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
14 # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
15
15
16 url(r'^admin/', admin.site.urls, name='admin'),
16 url(r'^admin/', admin.site.urls, name='admin'),
17 url(r'^', include('boards.urls')),
17 url(r'^', include('boards.urls')),
18 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
18 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
19
19
20 if settings.DEBUG:
20 if settings.DEBUG:
21 import debug_toolbar
21 import debug_toolbar
22 urlpatterns.append(url(r'^__debug__/', include(debug_toolbar.urls)))
22 urlpatterns.append(url(r'^__debug__/', include(debug_toolbar.urls)))
23
23
24 handler404 = NotFoundView.as_view()
24 handler404 = NotFoundView.as_view()
General Comments 0
You need to be logged in to leave comments. Login now