thumbor-libs-blackhand 0.2.0__py3-none-any.whl → 0.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,7 +47,7 @@ class Storage(BaseStorage):
47
47
 
48
48
  db_name = self.context.config.MONGO_RESULT_STORAGE_SERVER_DB
49
49
  col_name = self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
50
-
50
+
51
51
  try:
52
52
  uri = self.context.config.MONGO_RESULT_STORAGE_URI
53
53
  except AttributeError:
@@ -111,13 +111,13 @@ class Storage(BaseStorage):
111
111
  #max_age = self.get_max_age()
112
112
  #result_ttl = self.get_max_age()
113
113
  try:
114
- CACHE_PATH = self.context.config.CACHE_PATH
114
+ CACHE_PATH = self.context.config.CACHE_PATH
115
115
  except AttributeError:
116
116
  raise
117
-
118
- mkpath = (CACHE_PATH + '/' + datetime.now().strftime('%Y') + '/'
119
- + datetime.now().strftime('%m') + '/' + datetime.now().strftime('%d')
117
+ imgpath = ( datetime.now().strftime('%Y') + '/'
118
+ + datetime.now().strftime('%m') + '/' + datetime.now().strftime('%d')
120
119
  + '/' + datetime.now().strftime('%H'))
120
+ mkpath = (CACHE_PATH + '/' + imgpath)
121
121
  self.ensure_dir(mkpath)
122
122
 
123
123
  #os.makedirs(mkpath)
@@ -144,7 +144,7 @@ class Storage(BaseStorage):
144
144
  'content_type': BaseEngine.get_mimetype(image_bytes),
145
145
  'ref_id': ref_img2,
146
146
  'content_length' : len(image_bytes),
147
- 'cache_path': mkpath,
147
+ 'cache_path': imgpath,
148
148
  'cache_id' : cache_id
149
149
  }
150
150
  doc_cpm = dict(doc)
@@ -165,7 +165,10 @@ class Storage(BaseStorage):
165
165
 
166
166
  key = self.get_key_from_request()
167
167
  logger.debug("[RESULT_STORAGE] image not found at %s", key)
168
-
168
+ try:
169
+ CACHE_PATH = self.context.config.CACHE_PATH
170
+ except AttributeError:
171
+ raise
169
172
  age = datetime.utcnow() - timedelta(
170
173
  seconds=self.get_max_age()
171
174
  )
@@ -195,8 +198,8 @@ class Storage(BaseStorage):
195
198
  metadata['Cache-Control'] = "max-age=60,public"
196
199
  metadata['ContentLength'] = stored['content_length']
197
200
  metadata['ContentType'] = stored['content_type']
198
- cachefile = stored['cache_path'] + "/" + stored['cache_id']
199
-
201
+ cachefile = CACHE_PATH + '/' + stored['cache_path'] + "/" + stored['cache_id']
202
+
200
203
  fichier = open(cachefile, "rb")
201
204
  try:
202
205
  tosend = fichier.read()
@@ -158,6 +158,29 @@ class Storage(BaseStorage):
158
158
 
159
159
  if not stored:
160
160
  return None
161
+
162
+ try:
163
+ #self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
164
+ dedup = self.context.config.MONGO_RESULT_STORAGE_DEDUP
165
+ except:
166
+ dedup = False
167
+
168
+ if not dedup:
169
+ logger.debug("Deduplication OFF")
170
+ else:
171
+ filter={
172
+ 'path': key
173
+ }
174
+ sort=list({
175
+ 'created_at': -1
176
+ }.items())
177
+ skip=1
178
+ obj = self.storage.find(filter=filter, skip=skip)
179
+ async for doc in obj:
180
+ logger.info("Deduplication %s", key)
181
+ self.storage.delete_one({"_id": doc["_id"]})
182
+
183
+
161
184
  metadata = stored['metadata']
162
185
  metadata['LastModified'] = stored['created_at'].replace(
163
186
  tzinfo=pytz.utc
@@ -0,0 +1,209 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Blackhand library for Thumbor
3
+ # Licensed under the MIT license:
4
+ # http://www.opensource.org/licenses/mit-license
5
+
6
+ from urllib import parse #, request; error
7
+ #from motor.motor_tornado import MotorGridFSBucket
8
+ #from pymongo.errors import PyMongoError
9
+ from thumbor_libs_blackhand.mongodb.pool_result_storage import MongoConnector
10
+ from datetime import datetime, timedelta
11
+ from thumbor.result_storages import BaseStorage, ResultStorageResult
12
+ from thumbor.engines import BaseEngine
13
+ from thumbor.utils import logger
14
+ from bson.binary import Binary
15
+ import pytz
16
+ import re
17
+
18
+
19
+ class Storage(BaseStorage):
20
+
21
+ def __init__(self, context):
22
+ BaseStorage.__init__(self, context)
23
+ self.database, self.storage = self.__conn__()
24
+ super(Storage, self).__init__(context)
25
+
26
+
27
+
28
+ def __conn__(self):
29
+ '''Return the MongoDB params.
30
+ :returns: MongoDB DB and Collection
31
+ :rtype: pymongo.database.Database, pymongo.database.Collection
32
+ '''
33
+
34
+ password = parse.quote_plus(self.context.config.MONGO_RESULT_STORAGE_SERVER_PASSWORD)
35
+ user = parse.quote_plus(self.context.config.MONGO_RESULT_STORAGE_SERVER_USER)
36
+ if not self.context.config.MONGO_RESULT_STORAGE_SERVER_REPLICASET:
37
+ uric = ('mongodb://'+ user +':' + password + '@' + self.context.config.MONGO_RESULT_STORAGE_SERVER_HOSTS
38
+ + '/?authSource=' + self.context.config.MONGO_RESULT_STORAGE_SERVER_DB)
39
+ else:
40
+ uric = ('mongodb://'+ user +':' + password + '@' + self.context.config.MONGO_RESULT_STORAGE_SERVER_HOSTS
41
+ + '/?authSource=' + self.context.config.MONGO_RESULT_STORAGE_SERVER_DB
42
+ + "&replicaSet=" + self.context.config.MONGO_RESULT_STORAGE_SERVER_REPLICASET
43
+ + "&readPreference=" + self.context.config.MONGO_RESULT_STORAGE_SERVER_READ_PREFERENCE)
44
+
45
+ db_name = self.context.config.MONGO_RESULT_STORAGE_SERVER_DB
46
+ col_name = self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
47
+ host = None
48
+ port = None
49
+
50
+ try:
51
+ uri = self.context.config.MONGO_RESULT_STORAGE_URI
52
+ except AttributeError:
53
+ uri=uric
54
+
55
+ try:
56
+ host = self.context.config.MONGO_RESULT_STORAGE_SERVER_HOST
57
+ port = self.context.config.MONGO_RESULT_STORAGE_SERVER_PORT
58
+ except AttributeError:
59
+ host=None
60
+ port=None
61
+
62
+ mongo_conn = MongoConnector(
63
+ db_name=db_name,
64
+ col_name=col_name,
65
+ uri=uri,
66
+ host=host,
67
+ port=port,
68
+ )
69
+
70
+ database = mongo_conn.db_conn
71
+ storage = mongo_conn.col_conn
72
+
73
+ return database, storage
74
+
75
+ @property
76
+ def is_auto_webp(self):
77
+ '''Return if webp.
78
+ :return: If the file is a webp
79
+ :rettype: boolean
80
+ '''
81
+
82
+ return self.context.config.AUTO_WEBP \
83
+ and self.context.request.accepts_webp
84
+
85
+ def get_key_from_request(self):
86
+ '''Return a path key for the current request url.
87
+ :return: The storage key for the current url
88
+ :rettype: string
89
+ '''
90
+
91
+ path = f"result:{self.context.request.url}"
92
+
93
+ if self.is_auto_webp:
94
+ return f'{path}/webp'
95
+
96
+ return path
97
+
98
+
99
+ def get_max_age(self):
100
+
101
+ return self.context.config.RESULT_STORAGE_EXPIRATION_SECONDS
102
+
103
+
104
+ async def put(self, image_bytes):
105
+ key = self.get_key_from_request()
106
+ #max_age = self.get_max_age()
107
+ #result_ttl = self.get_max_age()
108
+ ref_img = ''
109
+ ref_img = re.findall(r'/[a-zA-Z0-9]{24}(?:$|/)', key)
110
+ if ref_img:
111
+ ref_img2 = ref_img[0].replace('/','')
112
+ else:
113
+ ref_img2 = 'undef'
114
+
115
+
116
+ if self.context.config.get("MONGO_STORE_METADATA", False):
117
+ metadata = dict(self.context.headers)
118
+ else:
119
+ metadata = {}
120
+
121
+ try:
122
+ listeProduit = self.context.config.PRODUIT
123
+ produit=''
124
+ for s in listeProduit:
125
+ if key.find(s) >= 1:
126
+ produit=s.replace('/', '')
127
+ break
128
+ else:
129
+ produit="info"
130
+ except AttributeError:
131
+ produit = 'undef'
132
+
133
+ doc = {
134
+ 'path': key,
135
+ 'created_at': datetime.utcnow(),
136
+ 'data': Binary(image_bytes),
137
+ 'metadata': metadata,
138
+ 'content_type': BaseEngine.get_mimetype(image_bytes),
139
+ 'ref_id': ref_img2,
140
+ 'content_length' : len(image_bytes),
141
+ 'produit': produit
142
+ }
143
+ doc_cpm = dict(doc)
144
+
145
+ await self.storage.insert_one(doc_cpm)
146
+ #return self.context.request.url
147
+ return key
148
+
149
+ async def get(self):
150
+ key = self.get_key_from_request()
151
+ logger.debug("[RESULT_STORAGE] image not found at %s", key)
152
+
153
+
154
+ age = datetime.utcnow() - timedelta(
155
+ seconds=self.get_max_age()
156
+ )
157
+ stored = await self.storage.find_one({
158
+ 'path': key,
159
+ 'created_at': {
160
+ '$gte': age
161
+ },
162
+ }, {
163
+ 'ref_id': True,
164
+ 'created_at': True,
165
+ 'metadata': True,
166
+ 'content_type': True,
167
+ 'data' : True,
168
+ 'content_length': True,
169
+ })
170
+
171
+
172
+ if not stored:
173
+ return None
174
+
175
+ try:
176
+ #self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
177
+ dedup = self.context.config.MONGO_RESULT_STORAGE_DEDUP
178
+ except:
179
+ dedup = False
180
+
181
+ if not dedup:
182
+ logger.debug("Deduplication OFF")
183
+ else:
184
+ filter={
185
+ 'path': key
186
+ }
187
+ sort=list({
188
+ 'created_at': -1
189
+ }.items())
190
+ skip=1
191
+ obj = self.storage.find(filter=filter, skip=skip)
192
+ async for doc in obj:
193
+ logger.info("Deduplication %s", key)
194
+ self.storage.delete_one({"_id": doc["_id"]})
195
+
196
+
197
+ metadata = stored['metadata']
198
+ metadata['LastModified'] = stored['created_at'].replace(
199
+ tzinfo=pytz.utc
200
+ )
201
+ metadata['Cache-Control'] = "max-age=60,public"
202
+ metadata['ContentLength'] = stored['content_length']
203
+ metadata['ContentType'] = stored['content_type']
204
+
205
+ return ResultStorageResult(
206
+ buffer=stored['data'],
207
+ metadata=metadata,
208
+ successful=True
209
+ )
@@ -0,0 +1,178 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Blackhand library for Thumbor
3
+ # Licensed under the MIT license:
4
+ # http://www.opensource.org/licenses/mit-license
5
+
6
+ from urllib import parse #, request; error
7
+ from thumbor_libs_blackhand.mongodb.pool_result_storage import MongoConnector
8
+ from datetime import datetime, timedelta
9
+ from thumbor.result_storages import BaseStorage, ResultStorageResult
10
+ from thumbor.engines import BaseEngine
11
+ from thumbor.utils import logger
12
+ from bson.binary import Binary
13
+ import pytz
14
+ import re
15
+
16
+
17
+ class Storage(BaseStorage):
18
+
19
+ def __init__(self, context):
20
+ BaseStorage.__init__(self, context)
21
+ self.database, self.storage = self.__conn__()
22
+ super(Storage, self).__init__(context)
23
+
24
+ def __conn__(self):
25
+ try:
26
+ uri = self.context.config.MONGO_RESULT_STORAGE_SERVER_URI
27
+ db_name=self.context.config.MONGO_RESULT_STORAGE_SERVER_DB
28
+ col_name=self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
29
+ except AttributeError:
30
+ logger.error("[RESULT_STORAGE] Parametres databases incomplet")
31
+
32
+ mongo_conn = MongoConnector(
33
+ db_name=db_name,
34
+ col_name=col_name,
35
+ uri=uri,
36
+ )
37
+
38
+ database = mongo_conn.db_conn
39
+ storage = mongo_conn.col_conn
40
+
41
+ return database, storage
42
+
43
+
44
+ @property
45
+ def is_auto_webp(self):
46
+ '''Return if webp.
47
+ :return: If the file is a webp
48
+ :rettype: boolean
49
+ '''
50
+
51
+ return self.context.config.AUTO_WEBP \
52
+ and self.context.request.accepts_webp
53
+
54
+ def get_key_from_request(self):
55
+ '''Return a path key for the current request url.
56
+ :return: The storage key for the current url
57
+ :rettype: string
58
+ '''
59
+
60
+ path = f"result:{self.context.request.url}"
61
+
62
+ if self.is_auto_webp:
63
+ return f'{path}/webp'
64
+
65
+ return path
66
+
67
+
68
+ def get_max_age(self):
69
+
70
+ return self.context.config.RESULT_STORAGE_EXPIRATION_SECONDS
71
+
72
+
73
+ async def put(self, image_bytes):
74
+ key = self.get_key_from_request()
75
+ #max_age = self.get_max_age()
76
+ #result_ttl = self.get_max_age()
77
+ ref_img = ''
78
+ ref_img = re.findall(r'/[a-zA-Z0-9]{24}(?:$|/)', key)
79
+ if ref_img:
80
+ ref_img2 = ref_img[0].replace('/','')
81
+ else:
82
+ ref_img2 = 'undef'
83
+
84
+
85
+ if self.context.config.get("MONGO_STORE_METADATA", False):
86
+ metadata = dict(self.context.headers)
87
+ else:
88
+ metadata = {}
89
+
90
+ try:
91
+ listeProduit = self.context.config.PRODUIT
92
+ produit=''
93
+ for s in listeProduit:
94
+ if key.find(s) >= 1:
95
+ produit=s.replace('/', '')
96
+ break
97
+ else:
98
+ produit="info"
99
+ except AttributeError:
100
+ produit = 'undef'
101
+
102
+ doc = {
103
+ 'path': key,
104
+ 'created_at': datetime.utcnow(),
105
+ 'data': Binary(image_bytes),
106
+ 'metadata': metadata,
107
+ 'content_type': BaseEngine.get_mimetype(image_bytes),
108
+ 'ref_id': ref_img2,
109
+ 'content_length' : len(image_bytes),
110
+ 'produit': produit
111
+ }
112
+ doc_cpm = dict(doc)
113
+
114
+ await self.storage.insert_one(doc_cpm)
115
+ #return self.context.request.url
116
+ return key
117
+
118
+ async def get(self):
119
+ key = self.get_key_from_request()
120
+ logger.debug("[RESULT_STORAGE] image not found at %s", key)
121
+
122
+ print(key)
123
+ age = datetime.utcnow() - timedelta(
124
+ seconds=self.get_max_age()
125
+ )
126
+ stored = await self.storage.find_one({
127
+ 'path': key,
128
+ 'created_at': {
129
+ '$gte': age
130
+ },
131
+ }, {
132
+ 'ref_id': True,
133
+ 'created_at': True,
134
+ 'metadata': True,
135
+ 'content_type': True,
136
+ 'data' : True,
137
+ 'content_length': True,
138
+ })
139
+
140
+
141
+ if not stored:
142
+ return None
143
+
144
+ try:
145
+ #self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
146
+ dedup = self.context.config.MONGO_RESULT_STORAGE_DEDUP
147
+ except:
148
+ dedup = False
149
+
150
+ if not dedup:
151
+ logger.debug("Deduplication OFF")
152
+ else:
153
+ filter={
154
+ 'path': key
155
+ }
156
+ sort=list({
157
+ 'created_at': -1
158
+ }.items())
159
+ skip=1
160
+ obj = self.storage.find(filter=filter, skip=skip)
161
+ async for doc in obj:
162
+ logger.info("Deduplication %s", key)
163
+ self.storage.delete_one({"_id": doc["_id"]})
164
+
165
+
166
+ metadata = stored['metadata']
167
+ metadata['LastModified'] = stored['created_at'].replace(
168
+ tzinfo=pytz.utc
169
+ )
170
+ metadata['Cache-Control'] = "max-age=60,public"
171
+ metadata['ContentLength'] = stored['content_length']
172
+ metadata['ContentType'] = stored['content_type']
173
+
174
+ return ResultStorageResult(
175
+ buffer=stored['data'],
176
+ metadata=metadata,
177
+ successful=True
178
+ )
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
2
- Name: thumbor-libs-blackhand
3
- Version: 0.2.0
1
+ Metadata-Version: 2.4
2
+ Name: thumbor_libs_blackhand
3
+ Version: 0.5.1
4
4
  Summary: libs thumbor
5
5
  Home-page: https://github.com/Bkhand/thumbor_libs_blackhand
6
6
  Author: Bertrand Thill
@@ -12,11 +12,21 @@ Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Natural Language :: French
14
14
  Classifier: Operating System :: POSIX :: Linux
15
- Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
17
17
  Classifier: Topic :: Multimedia :: Graphics :: Presentation
18
18
  License-File: LICENSE
19
- Requires-Dist: thumbor (>=7.1.0)
20
- Requires-Dist: pymongo (>=4.2.0)
19
+ Requires-Dist: thumbor>=7.7.0
20
+ Requires-Dist: pymongo>=4.2.0
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: home-page
26
+ Dynamic: keywords
27
+ Dynamic: license
28
+ Dynamic: license-file
29
+ Dynamic: requires-dist
30
+ Dynamic: summary
21
31
 
22
32
  This module enable mongodb support and fallback for thumbor.
@@ -5,16 +5,16 @@ thumbor_libs_blackhand/loaders/specb_file_fallback_file_loader.py,sha256=842cYNb
5
5
  thumbor_libs_blackhand/metrics/__init__.py,sha256=5izS_bmGrlIsSPAU1JYYvHuAaq2qHHanGXr_dPPtyuo,138
6
6
  thumbor_libs_blackhand/mongodb/pool_result_storage.py,sha256=ZHARWEFGacLXjtxqVxVmwFGOS94w0SkhkwC96VM00LE,1781
7
7
  thumbor_libs_blackhand/result_storages/__init__.py,sha256=5izS_bmGrlIsSPAU1JYYvHuAaq2qHHanGXr_dPPtyuo,138
8
- thumbor_libs_blackhand/result_storages/hybrid_result_storage.py,sha256=0KeJLIOV8yON-eB3LdC4Ba5VkurdV1rxuOpjr9iyRYM,6534
9
- thumbor_libs_blackhand/result_storages/mongodb_legacy_result_storage.py,sha256=7Lpj4GLC5fDNw-B15gmfCs9jOGXbzwiOcGRFVOC98_8,3893
10
- thumbor_libs_blackhand/result_storages/mongodb_result_storage.py,sha256=uEDpzbKzj20MFvxn4Ny6B6piJnZKLxEY1ZgXyBYwKhs,5442
11
- thumbor_libs_blackhand/result_storages/mongodb_webp_result_storage.py,sha256=auKnLB_tFwMcKd4nSKaJ8JP6FaYs6E-9dDzn0VrqGTw,3889
8
+ thumbor_libs_blackhand/result_storages/hybrid_result_storage.py,sha256=wFUzMeZxPzU_BvFjNJWZPh7bCla0x-s7Iwj6TiFOgDE,6672
9
+ thumbor_libs_blackhand/result_storages/mongodb_result_storage_v3.py,sha256=e1wIBcLx6lN_gDDPaJTelQdKyB3zyxPQPjCMLugx-uY,6075
10
+ thumbor_libs_blackhand/result_storages/mongodb_result_storage_v4.py,sha256=rTGtpfVZamErPfCA-z3-3vgf5uP_HDH3f3Sq8WOg19w,6462
11
+ thumbor_libs_blackhand/result_storages/mongodb_result_storage_v5.py,sha256=_wElwxgrF-QYLc5VyKMdUxsknc403QihGwP1AFaVQ4U,5068
12
12
  thumbor_libs_blackhand/storages/__init__.py,sha256=5izS_bmGrlIsSPAU1JYYvHuAaq2qHHanGXr_dPPtyuo,138
13
13
  thumbor_libs_blackhand/storages/mongodb_webp_storage.py,sha256=QSLAkoiqXRQXDq-2HUWGUTsz9hNyatKQg7_LB6ikN6o,4401
14
14
  thumbor_libs_blackhand/url_signers/__init__.py,sha256=5izS_bmGrlIsSPAU1JYYvHuAaq2qHHanGXr_dPPtyuo,138
15
15
  thumbor_libs_blackhand/url_signers/base64_hmac_sha1_trim.py,sha256=4TNCfNqBRRQgTo90N3Ej2SDo2jYzzDm31hOFrk0BsVc,583
16
- thumbor_libs_blackhand-0.2.0.dist-info/LICENSE,sha256=H3K2DdEDDUNhtBvyWkPh8SodWqMuiOefZWwdDxA98VE,1079
17
- thumbor_libs_blackhand-0.2.0.dist-info/METADATA,sha256=NcBITbvhIWy6vOUyZ0VRWYGnTmoTuSui7FITh7h7e4E,810
18
- thumbor_libs_blackhand-0.2.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
19
- thumbor_libs_blackhand-0.2.0.dist-info/top_level.txt,sha256=qs2ZPZFH1pQYGF-qqZzRbRbPHdtBugtefP7mUslef90,23
20
- thumbor_libs_blackhand-0.2.0.dist-info/RECORD,,
16
+ thumbor_libs_blackhand-0.5.1.dist-info/licenses/LICENSE,sha256=H3K2DdEDDUNhtBvyWkPh8SodWqMuiOefZWwdDxA98VE,1079
17
+ thumbor_libs_blackhand-0.5.1.dist-info/METADATA,sha256=qJbvyEWDjSTNU778oxHCu5DQMaCiJWALgzfPhDMAvck,1000
18
+ thumbor_libs_blackhand-0.5.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
19
+ thumbor_libs_blackhand-0.5.1.dist-info/top_level.txt,sha256=qs2ZPZFH1pQYGF-qqZzRbRbPHdtBugtefP7mUslef90,23
20
+ thumbor_libs_blackhand-0.5.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.37.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,105 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Blackhand library for Thumbor
3
- # Licensed under the MIT license:
4
- # http://www.opensource.org/licenses/mit-license
5
- import urllib.request, urllib.parse, urllib.error
6
- import re
7
- from datetime import datetime, timedelta
8
- #from io import StringIO
9
- from thumbor.result_storages import BaseStorage
10
- from thumbor.utils import logger
11
- from bson.binary import Binary
12
- from pymongo.mongo_client import MongoClient
13
- from sys import getsizeof
14
-
15
-
16
- class Storage(BaseStorage):
17
- @property
18
- def is_auto_webp(self):
19
- return self.context.config.AUTO_WEBP and self.context.request.accepts_webp
20
-
21
-
22
- def __conn__(self):
23
- #server_api = ServerApi('1', strict=True)
24
- #client = MongoClient(self.context.config.MONGO_RESULT_STORAGE_URI) #, server_api=server_api)
25
- #db = client[self.context.config.MONGO_RESULT_STORAGE_SERVER_DB]
26
- #storage = self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
27
- #return db, storage
28
-
29
- password = urllib.parse.quote_plus(self.context.config.MONGO_RESULT_STORAGE_SERVER_PASSWORD)
30
- user = urllib.parse.quote_plus(self.context.config.MONGO_RESULT_STORAGE_SERVER_USER)
31
- if not self.context.config.MONGO_RESULT_STORAGE_SERVER_REPLICASET:
32
- uri = 'mongodb://'+ user +':' + password + '@' + self.context.config.MONGO_RESULT_STORAGE_SERVER_HOST + '/?authSource=' + self.context.config.MONGO_RESULT_STORAGE_SERVER_DB
33
- else:
34
- uri = 'mongodb://'+ user +':' + password + '@' + self.context.config.MONGO_RESULT_STORAGE_SERVER_HOST + '/?authSource=' + self.context.config.MONGO_RESULT_STORAGE_SERVER_DB + "&replicaSet=" + self.context.config.MONGO_RESULT_STORAGE_SERVER_REPLICASET + "&readPreference=" + self.context.config.MONGO_RESULT_STORAGE_SERVER_READ_PREFERENCE
35
- client = MongoClient(uri)
36
- db = client[self.context.config.MONGO_RESULT_STORAGE_SERVER_DB]
37
- storage = self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
38
- return db, storage
39
-
40
-
41
- def get_max_age(self):
42
- default_ttl = self.context.config.RESULT_STORAGE_EXPIRATION_SECONDS
43
- if self.context.request.max_age == 0:
44
- return self.context.request.max_age
45
- return default_ttl
46
-
47
-
48
- def get_key_from_request(self):
49
- path = "result:%s" % self.context.request.url
50
- return path
51
-
52
-
53
- async def put(self, image_bytes):
54
- db, storage = self.__conn__()
55
- key = self.get_key_from_request()
56
- #max_age = self.get_max_age()
57
- #result_ttl = self.get_max_age()
58
- ref_img = ''
59
- ref_img = re.findall(r'/[a-zA-Z0-9]{24}(?:$|/)', key)
60
- if ref_img:
61
- ref_img2 = ref_img[0].replace('/','')
62
- else:
63
- ref_img2 = 'undef'
64
-
65
- if self.is_auto_webp:
66
- content_t = 'webp'
67
- else:
68
- content_t = 'default'
69
- doc = {
70
- 'path': key,
71
- 'created_at': datetime.utcnow(),
72
- 'data': Binary(image_bytes),
73
- 'content-type': content_t,
74
- 'ref_id': ref_img2
75
- }
76
- doc_cpm = dict(doc)
77
-
78
- try:
79
- #self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
80
- maxs = self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
81
- except:
82
- maxs = 16000000
83
-
84
- amd = getsizeof(bytes)
85
- if amd > maxs:
86
- logger.warning(u"OVERSIZE %s: %s > %s pas de mise en cache possible", key, amd, maxs)
87
- return None
88
- else:
89
- db[storage].insert_one(doc_cpm)
90
- return key
91
-
92
-
93
-
94
-
95
- async def get(self):
96
- db, storage = self.__conn__()
97
- key = self.get_key_from_request()
98
- logger.debug("[RESULT_STORAGE] image not found at %s", key)
99
-
100
- result = db[storage].find_one({'path': key }) #, 'content-type': "default"})
101
-
102
- if not result:
103
- return None
104
- tosend = result['data']
105
- return tosend
@@ -1,103 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Blackhand library for Thumbor
3
- # Licensed under the MIT license:
4
- # http://www.opensource.org/licenses/mit-license
5
- import urllib.request, urllib.parse, urllib.error
6
- import re
7
- from datetime import datetime, timedelta
8
- #from io import StringIO
9
- from thumbor.result_storages import BaseStorage
10
- from thumbor.utils import logger
11
- from bson.binary import Binary
12
- from pymongo.mongo_client import MongoClient
13
- from sys import getsizeof
14
-
15
-
16
- class Storage(BaseStorage):
17
- @property
18
- def is_auto_webp(self):
19
- return self.context.config.AUTO_WEBP and self.context.request.accepts_webp
20
-
21
-
22
- def __conn__(self):
23
- #server_api = ServerApi('1', strict=True)
24
- #client = MongoClient(self.context.config.MONGO_RESULT_STORAGE_URI) #, server_api=server_api)
25
- #db = client[self.context.config.MONGO_RESULT_STORAGE_SERVER_DB]
26
- #storage = self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
27
- #return db, storage
28
-
29
- password = urllib.parse.quote_plus(self.context.config.MONGO_RESULT_STORAGE_SERVER_PASSWORD)
30
- user = urllib.parse.quote_plus(self.context.config.MONGO_RESULT_STORAGE_SERVER_USER)
31
- if not self.context.config.MONGO_RESULT_STORAGE_SERVER_REPLICASET:
32
- uri = 'mongodb://'+ user +':' + password + '@' + self.context.config.MONGO_RESULT_STORAGE_SERVER_HOST + '/?authSource=' + self.context.config.MONGO_RESULT_STORAGE_SERVER_DB
33
- else:
34
- uri = 'mongodb://'+ user +':' + password + '@' + self.context.config.MONGO_RESULT_STORAGE_SERVER_HOST + '/?authSource=' + self.context.config.MONGO_RESULT_STORAGE_SERVER_DB + "&replicaSet=" + self.context.config.MONGO_RESULT_STORAGE_SERVER_REPLICASET + "&readPreference=" + self.context.config.MONGO_RESULT_STORAGE_SERVER_READ_PREFERENCE
35
- client = MongoClient(uri)
36
- db = client[self.context.config.MONGO_RESULT_STORAGE_SERVER_DB]
37
- storage = self.context.config.MONGO_RESULT_STORAGE_SERVER_COLLECTION
38
- return db, storage
39
-
40
-
41
- def get_max_age(self):
42
- default_ttl = self.context.config.RESULT_STORAGE_EXPIRATION_SECONDS
43
- if self.context.request.max_age == 0:
44
- return self.context.request.max_age
45
- return default_ttl
46
-
47
-
48
- def get_key_from_request(self):
49
- path = "result:%s" % self.context.request.url
50
- return path
51
-
52
-
53
- async def put(self, image_bytes):
54
- db, storage = self.__conn__()
55
- key = self.get_key_from_request()
56
- #max_age = self.get_max_age()
57
- #result_ttl = self.get_max_age()
58
- ref_img = ''
59
- ref_img = re.findall(r'/[a-zA-Z0-9]{24}(?:$|/)', key)
60
- if ref_img:
61
- ref_img2 = ref_img[0].replace('/','')
62
- else:
63
- ref_img2 = 'undef'
64
-
65
- if self.is_auto_webp:
66
- content_t = 'webp'
67
- else:
68
- content_t = 'default'
69
- doc = {
70
- 'path': key,
71
- 'created_at': datetime.utcnow(),
72
- 'data': Binary(image_bytes),
73
- 'content-type': content_t,
74
- 'ref_id': ref_img2
75
- }
76
- doc_cpm = dict(doc)
77
-
78
- try:
79
- #self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
80
- maxs = self.context.config.MONGO_RESULT_STORAGE_MAXCACHESIZE
81
- except:
82
- maxs = 16000000
83
-
84
- amd = getsizeof(bytes)
85
- if amd > maxs:
86
- logger.warning(u"OVERSIZE %s: %s > %s pas de mise en cache possible", key, amd, maxs)
87
- return None
88
- else:
89
- db[storage].insert_one(doc_cpm)
90
- return key
91
-
92
-
93
- async def get(self):
94
- db, storage = self.__conn__()
95
- key = self.get_key_from_request()
96
- logger.debug("[RESULT_STORAGE] image not found at %s", key)
97
-
98
- result = db[storage].find_one({'path': key }) #, 'content-type': "default"})
99
-
100
- if not result:
101
- return None
102
- tosend = result['data']
103
- return tosend