11import requests
22import time
3+ import magic
4+ from django .core .files .uploadedfile import TemporaryUploadedFile
5+
36from files .exceptions import SelectelUploadError
7+ from files .models import UserFile
48
59from procollab .settings import (
610 DEBUG ,
1216
1317
1418class FileAPI :
15- def __init__ (self , file , user ) -> None :
16- self .file = file
19+ def __init__ (self , file : TemporaryUploadedFile , user ) -> None :
20+ self .file = file # it's TemporaryUploadedFile, and it will be
21+ # removed after first .close() call, so we must read this file only once
1722 self .user = user
23+ self .file_object = self .file .open (mode = "rb" )
1824
1925 @staticmethod
2026 def delete (url : str ) -> int :
@@ -23,21 +29,34 @@ def delete(url: str) -> int:
2329 response = requests .delete (url , headers = {"X-Auth-Token" : token })
2430 return response .status_code
2531
26- def upload (self ):
27- return self ._upload_via_selectel_swift ()
32+ def upload (self ) -> str :
33+ url = self ._upload_via_selectel_swift ()
34+ info = get_file_info (self .file )
35+ UserFile .objects .create (
36+ user = self .user ,
37+ link = url ,
38+ name = info ["name" ],
39+ size = info ["size" ],
40+ extension = info ["extension" ],
41+ mime_type = info ["mime_type" ],
42+ )
43+ self .file_object .close ()
44+ return url
2845
29- def _upload_via_selectel_swift (self ) -> tuple [ int , str ] :
46+ def _upload_via_selectel_swift (self ) -> str :
3047 token = self ._get_selectel_swift_token ()
3148 url = self ._generate_selectel_swift_file_url ()
3249
33- with self .file .open (mode = "rb" ) as file_object :
34- response = requests .put (
35- url ,
36- headers = {"X-Auth-Token" : token , "Content-Type" : file_object .content_type },
37- data = file_object .read (),
38- )
50+ requests .put (
51+ url ,
52+ headers = {
53+ "X-Auth-Token" : token ,
54+ "Content-Type" : self .file_object .content_type ,
55+ },
56+ data = self .file_object .read (),
57+ )
3958
40- return response . status_code , url
59+ return url
4160
4261 def _generate_selectel_swift_link (sefl ):
4362 link = f"https://api.selcdn.ru/v1/SEL_{ SELECTEL_ACCOUNT_ID } /{ SELECTEL_CONTAINER_NAME } /"
@@ -61,10 +80,10 @@ def _get_selectel_swift_token():
6180 }
6281 }
6382 }
64- r = requests .post ("https://api.selcdn.ru/v3/auth/tokens" , json = data )
65- if r .status_code not in [200 , 201 ]:
83+ response = requests .post ("https://api.selcdn.ru/v3/auth/tokens" , json = data )
84+ if response .status_code not in [200 , 201 ]:
6685 raise SelectelUploadError ("Couldn't generate a token for selcdn" )
67- return r .headers ["x-subject-token" ]
86+ return response .headers ["x-subject-token" ]
6887
6988 def _get_file_extension (self ) -> str :
7089 if len (self .file .name .split ("." )) > 1 :
@@ -85,11 +104,16 @@ def _generate_selectel_swift_file_url(self) -> str:
85104 )
86105
87106
88- def get_file_info (request ) :
89- name , ext = request .name .split ("." )
107+ def get_file_info (file : TemporaryUploadedFile ) -> dict :
108+ name , ext = file .name .split ("." )
90109
91110 return {
92- "size" : request .size ,
111+ "size" : file .size ,
93112 "name" : name ,
94113 "extension" : ext ,
114+ "mime_type" : get_file_mime_type (file ),
95115 }
116+
117+
118+ def get_file_mime_type (file : TemporaryUploadedFile ):
119+ return magic .from_file (file .temporary_file_path (), mime = True )
0 commit comments