##// END OF EJS Templates
Compatibility with python-magic of latest version (returts str, not bytes)
neko259 -
r1686:21e5d408 3.3.1 default
parent child Browse files
Show More
@@ -1,144 +1,145 b''
1 1 """
2 2 This module contains helper functions and helper classes.
3 3 """
4 4 import hashlib
5 5 from boards.abstracts.constants import FILE_DIRECTORY
6 6 from random import random
7 7 import time
8 8 import hmac
9 9
10 10 from django.core.cache import cache
11 11 from django.db.models import Model
12 12 from django import forms
13 13 from django.template.defaultfilters import filesizeformat
14 14 from django.utils import timezone
15 15 from django.utils.translation import ugettext_lazy as _
16 16 import magic
17 17 import os
18 18
19 19 import boards
20 20 from boards.settings import get_bool
21 21 from neboard import settings
22 22
23 23 CACHE_KEY_DELIMITER = '_'
24 24
25 25 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
26 26 META_REMOTE_ADDR = 'REMOTE_ADDR'
27 27
28 28 SETTING_MESSAGES = 'Messages'
29 29 SETTING_ANON_MODE = 'AnonymousMode'
30 30
31 31 ANON_IP = '127.0.0.1'
32 32
33 33 FILE_EXTENSION_DELIMITER = '.'
34 34
35 35
36 36 def is_anonymous_mode():
37 37 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
38 38
39 39
40 40 def get_client_ip(request):
41 41 if is_anonymous_mode():
42 42 ip = ANON_IP
43 43 else:
44 44 x_forwarded_for = request.META.get(HTTP_FORWARDED)
45 45 if x_forwarded_for:
46 46 ip = x_forwarded_for.split(',')[-1].strip()
47 47 else:
48 48 ip = request.META.get(META_REMOTE_ADDR)
49 49 return ip
50 50
51 51
52 52 # TODO The output format is not epoch because it includes microseconds
53 53 def datetime_to_epoch(datetime):
54 54 return int(time.mktime(timezone.localtime(
55 55 datetime,timezone.get_current_timezone()).timetuple())
56 56 * 1000000 + datetime.microsecond)
57 57
58 58
59 59 def get_websocket_token(user_id='', timestamp=''):
60 60 """
61 61 Create token to validate information provided by new connection.
62 62 """
63 63
64 64 sign = hmac.new(settings.CENTRIFUGE_PROJECT_SECRET.encode())
65 65 sign.update(settings.CENTRIFUGE_PROJECT_ID.encode())
66 66 sign.update(user_id.encode())
67 67 sign.update(timestamp.encode())
68 68 token = sign.hexdigest()
69 69
70 70 return token
71 71
72 72
73 73 # TODO Test this carefully
74 74 def cached_result(key_method=None):
75 75 """
76 76 Caches method result in the Django's cache system, persisted by object name,
77 77 object name, model id if object is a Django model, args and kwargs if any.
78 78 """
79 79 def _cached_result(function):
80 80 def inner_func(obj, *args, **kwargs):
81 81 cache_key_params = [obj.__class__.__name__, function.__name__]
82 82
83 83 cache_key_params += args
84 84 for key, value in kwargs:
85 85 cache_key_params.append(key + ':' + value)
86 86
87 87 if isinstance(obj, Model):
88 88 cache_key_params.append(str(obj.id))
89 89
90 90 if key_method is not None:
91 91 cache_key_params += [str(arg) for arg in key_method(obj)]
92 92
93 93 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
94 94
95 95 persisted_result = cache.get(cache_key)
96 96 if persisted_result is not None:
97 97 result = persisted_result
98 98 else:
99 99 result = function(obj, *args, **kwargs)
100 100 if result is not None:
101 101 cache.set(cache_key, result)
102 102
103 103 return result
104 104
105 105 return inner_func
106 106 return _cached_result
107 107
108 108
109 109 def get_file_hash(file) -> str:
110 110 md5 = hashlib.md5()
111 111 for chunk in file.chunks():
112 112 md5.update(chunk)
113 113 return md5.hexdigest()
114 114
115 115
116 116 def validate_file_size(size: int):
117 117 max_size = boards.settings.get_int('Forms', 'MaxFileSize')
118 118 if size > max_size:
119 119 raise forms.ValidationError(
120 120 _('File must be less than %s but is %s.')
121 121 % (filesizeformat(max_size), filesizeformat(size)))
122 122
123 123
124 124 def get_extension(filename):
125 125 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
126 126
127 127
128 128 def get_upload_filename(model_instance, old_filename):
129 129 # TODO Use something other than random number in file name
130 130 extension = get_extension(old_filename)
131 131 new_name = '{}{}.{}'.format(
132 132 str(int(time.mktime(time.gmtime()))),
133 133 str(int(random() * 1000)),
134 134 extension)
135 135
136 136 return os.path.join(FILE_DIRECTORY, new_name)
137 137
138 138
139 139 def get_file_mimetype(file) -> str:
140 type = magic.from_buffer(file.chunks().__next__(), mime=True)
141 if type is not None:
142 return type.decode()
143 else:
144 return 'application/octet-stream'
140 file_type = magic.from_buffer(file.chunks().__next__(), mime=True)
141 if file_type is None:
142 file_type = 'application/octet-stream'
143 else if type(file_type) == bytes:
144 file_type = file_type.decode()
145 return type
General Comments 0
You need to be logged in to leave comments. Login now