1111from gridfs import GridFSBucket , NoFile
1212from pymodm import connect
1313from pymodm .connection import _get_db
14- from pymodm .errors import ValidationError
14+ from pymodm .errors import ValidationError , DoesNotExist
1515from pymodm .files import GridFSStorage
1616from pymongo import ReturnDocument
1717from pymongo .errors import CollectionInvalid
2323 RecognizedAudioToProcess ,
2424 RecognizedPresentationsToProcess , Sessions ,
2525 TaskAttempts , TaskAttemptsToPassBack , Tasks ,
26- Trainings , TrainingsToProcess )
26+ Trainings , TrainingsToProcess , StorageMeta )
2727from app .status import (AudioStatus , PassBackStatus , PresentationStatus ,
2828 TrainingStatus )
2929from app .utils import remove_blank_and_none
3030
3131logger = get_root_logger ()
3232
33-
33+ BYTES_PER_MB = 1024 * 1024
3434
3535class DBManager :
3636 def __new__ (cls ):
3737 if not hasattr (cls , 'init_done' ):
3838 cls .instance = super (DBManager , cls ).__new__ (cls )
3939 connect (Config .c .mongodb .url + Config .c .mongodb .database_name )
4040 cls .instance .storage = GridFSStorage (GridFSBucket (_get_db ()))
41+ cls .instance .max_size = float (Config .c .constants .storage_max_size_mbytes ) * BYTES_PER_MB
4142 cls .init_done = True
4243 return cls .instance
4344
4445 def add_file (self , file , filename = uuid .uuid4 ()):
45- return self .storage .save (name = filename , content = file )
46+ try :
47+ file .seek (0 , os .SEEK_END )
48+ size = file .tell ()
49+ file .seek (0 )
50+ except :
51+ size = len (file )
52+ _id = self .storage .save (name = filename , content = file )
53+ self .update_storage_size (size )
54+ return _id
4655
4756 def read_and_add_file (self , path , filename = None ):
4857 if filename is None :
@@ -67,7 +76,50 @@ def get_file(self, file_id):
6776 except (NoFile , ValidationError , InvalidId ) as e :
6877 logger .warning ('file_id = {}, {}.' .format (file_id , e ))
6978 return None
70-
79+
80+ def _get_or_create_storage_meta (self ):
81+ try :
82+ return StorageMeta .objects .get ({})
83+ except DoesNotExist :
84+ meta = StorageMeta (used_size = 0 ).save ()
85+ return meta
86+
87+ def get_used_storage_size (self ):
88+ return self ._get_or_create_storage_meta ().used_size
89+
90+ def set_used_storage_size (self , size ):
91+ meta = self ._get_or_create_storage_meta ()
92+ meta .used_size = size
93+ meta .save ()
94+
95+ def update_storage_size (self , deltasize ):
96+ meta = self ._get_or_create_storage_meta ()
97+ meta .used_size += deltasize
98+ meta .save ()
99+
100+ def get_max_size (self ):
101+ return self .max_size
102+
103+ # returns Bool variable - True if file can be stored else False
104+ def check_storage_limit (self , new_file_size ):
105+ current_size = self .get_used_storage_size ()
106+ inf_msg = (
107+ f"Check for ability to add file: "
108+ f"Current: { current_size / BYTES_PER_MB :.2f} MB, "
109+ f"New file: { new_file_size / BYTES_PER_MB :.2f} MB, "
110+ f"Storage size: { self .max_size / BYTES_PER_MB } MB"
111+ )
112+ logger .info (inf_msg )
113+ return False if current_size + new_file_size > self .max_size else True
114+
115+ def recalculate_used_storage_data (self ):
116+ total_size = 0
117+ db = _get_db ()
118+ for file_doc in db .fs .files .find ():
119+ total_size += file_doc ['length' ]
120+ self .set_used_storage_size (total_size )
121+ logger .info (f"Storage size recalculated: { total_size / BYTES_PER_MB :.2f} MB" )
122+
71123
72124class TrainingsDBManager :
73125 def __new__ (cls ):
0 commit comments