2
2
# License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
5
- import datetime
6
5
import json
7
6
import logging
8
7
12
11
CrashStorageBase ,
13
12
CrashIDNotFound ,
14
13
MemoryDumpsMapping ,
14
+ get_datestamp ,
15
+ dict_to_str ,
16
+ list_to_str ,
17
+ str_to_list ,
15
18
)
16
19
from socorro .external .boto .connection_context import S3Connection
17
20
from socorro .lib .libjsonschema import JsonSchemaReducer
21
24
SocorroDataReducer ,
22
25
transform_schema ,
23
26
)
24
- from socorro .lib .libooid import date_from_ooid
25
27
from socorro .schemas import TELEMETRY_SOCORRO_CRASH_SCHEMA
26
28
27
29
@@ -32,25 +34,6 @@ def wait_time_generator():
32
34
yield from [1 , 1 , 1 , 1 , 1 ]
33
35
34
36
35
- class CrashIDMissingDatestamp (Exception ):
36
- """Indicates the crash id is invalid and missing a datestamp."""
37
-
38
-
39
- def get_datestamp (crashid ):
40
- """Parses out datestamp from a crashid.
41
-
42
- :returns: datetime
43
-
44
- :raises CrashIDMissingDatestamp: if the crash id has no datestamp at the end
45
-
46
- """
47
- datestamp = date_from_ooid (crashid )
48
- if datestamp is None :
49
- # We should never hit this situation unless the crashid is not valid
50
- raise CrashIDMissingDatestamp (f"{ crashid } is missing datestamp" )
51
- return datestamp
52
-
53
-
54
37
def build_keys (name_of_thing , crashid ):
55
38
"""Builds a list of s3 pseudo-filenames
56
39
@@ -81,25 +64,6 @@ def build_keys(name_of_thing, crashid):
81
64
return [f"v1/{ name_of_thing } /{ crashid } " ]
82
65
83
66
84
- class JSONISOEncoder (json .JSONEncoder ):
85
- def default (self , obj ):
86
- if isinstance (obj , datetime .date ):
87
- return obj .isoformat ()
88
- raise NotImplementedError (f"Don't know about { obj !r} " )
89
-
90
-
91
- def dict_to_str (a_mapping ):
92
- return json .dumps (a_mapping , cls = JSONISOEncoder )
93
-
94
-
95
- def list_to_str (a_list ):
96
- return json .dumps (list (a_list ))
97
-
98
-
99
- def str_to_list (a_string ):
100
- return json .loads (a_string )
101
-
102
-
103
67
class BotoS3CrashStorage (CrashStorageBase ):
104
68
"""Saves and loads crash data to S3"""
105
69
@@ -195,15 +159,18 @@ def save_processed_crash(self, raw_crash, processed_crash):
195
159
path = build_keys ("processed_crash" , crash_id )[0 ]
196
160
self .save_file (path , data )
197
161
198
- def list_objects_paginator (self , prefix ):
199
- """Return generator of objects in the bucket that have a specified key prefix
162
+ def list_objects_paginator (self , prefix , page_size = None ):
163
+ """Yield pages of object keys in the bucket that have a specified key prefix
200
164
201
165
:arg prefix: the prefix to look at
166
+ :arg page_size: the number of results to return per page
202
167
203
- :returns: generator of keys
204
-
168
+ :returns: generator of pages (lists) of object keys
205
169
"""
206
- return self .connection .list (bucket = self .bucket , prefix = prefix )
170
+ for page in self .connection .list_objects_paginator (
171
+ bucket = self .bucket , prefix = prefix , page_size = page_size
172
+ ):
173
+ yield [item ["Key" ] for item in page .get ("Contents" , [])]
207
174
208
175
def exists_object (self , key ):
209
176
"""Returns whether the object exists in the bucket
0 commit comments