Skip to content

Commit a43aff4

Browse files
committed
Uploading files now works I think
1 parent cdc0c1c commit a43aff4

2 files changed

Lines changed: 59 additions & 62 deletions

File tree

files/exceptions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class SelectelUploadError(Exception):
2+
pass

files/views.py

Lines changed: 57 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import asyncio
2-
import json
3-
from datetime import time
4-
from asgiref.sync import sync_to_async
5-
from aiohttp import ClientSession
1+
import time
2+
3+
import requests
64
from django.db import transaction
7-
from django.utils.decorators import classonlymethod
85
from rest_framework import permissions, status
96
from rest_framework.response import Response
107
from rest_framework.views import APIView
118

9+
from files.exceptions import SelectelUploadError
1210
from files.models import UserFile
1311
from procollab.settings import (
1412
DEBUG,
@@ -22,77 +20,74 @@
2220
class FileUploadView(APIView):
2321
permission_classes = [permissions.AllowAny]
2422

25-
@classonlymethod
26-
def as_view(cls, **initkwargs):
27-
view = super().as_view(**initkwargs)
28-
view._is_coroutine = asyncio.coroutines._is_coroutine
29-
return view
30-
3123
@transaction.atomic
32-
async def post(self, request):
33-
file = request.FILES["file"]
24+
def post(self, request):
3425
if DEBUG is True:
3526
return Response(
3627
{"message": "Files doesn't save in development mode, sorry <3"},
3728
status=status.HTTP_406_NOT_ACCEPTABLE,
3829
)
3930

31+
file = request.FILES["file"]
4032
link = f"https://api.selcdn.ru/v1/SEL_{SELECTEL_ACCOUNT_ID}/{SELECTEL_CONTAINER_NAME}/"
41-
4233
user = request.user
34+
token = self._get_token()
4335

44-
# creates UserFile object in the database
45-
self._save_to_db(user, link)
46-
token = await self._get_token()
47-
async with ClientSession(headers={"X-Auth-Token": token}) as server:
48-
if len(file.split(".")) > 1:
49-
extension = file.filename.split(".")[1]
50-
else:
51-
extension = ""
52-
53-
# looks like /hashed_email/hashed_filename_hashed_time.extension
54-
url = (
55-
link + f"/{SELECTEL_CONTAINER_NAME}/{abs(hash(user.email))}/"
56-
f"{abs(hash(file.filename))}_{abs(hash(time.time()))}.{extension}"
57-
)
36+
if len(file.name.split(".")) > 1:
37+
extension = file.name.split(".")[1]
38+
else:
39+
extension = ""
5840

59-
async with server.put(
41+
# looks like /hashedEmail/hashedFilename_hashedTime.extension
42+
url = (
43+
link + f"{SELECTEL_CONTAINER_NAME}/{abs(hash(user.email))}/"
44+
f"{abs(hash(file.name))}_{abs(hash(time.time()))}{'.' + extension if extension else ''}"
45+
)
46+
with file.open(mode="rb") as file_object:
47+
r = requests.put(
6048
url,
61-
data=file.open(mode="rb").read(),
62-
) as response:
63-
if response.status != 201:
64-
return await Response(
65-
"Failed to upload file", status_code=status.HTTP_409_CONFLICT
66-
)
67-
return await Response({"url": url}, status=status.HTTP_201_CREATED)
49+
headers={
50+
"X-Auth-Token": token,
51+
"X-Object-Meta-Content-Type": file_object.content_type,
52+
},
53+
files={"file": (file.name, file_object, file.content_type)},
54+
)
55+
if r.status_code != 201:
56+
return Response("Failed to upload file", status=status.HTTP_409_CONFLICT)
57+
self._save_to_db(user, url)
58+
return Response({"url": url}, status=status.HTTP_201_CREATED)
6859

69-
@sync_to_async
70-
def _save_to_db(self, user, link):
60+
@classmethod
61+
def _save_to_db(cls, user, url):
7162
"""creates userfile object for file uploads"""
72-
return UserFile.objects.create(user=user, link=link)
63+
return UserFile.objects.create(user=user, link=url)
7364

74-
async def _get_token(self):
65+
@classmethod
66+
def _get_token(cls):
7567
"""returns auth token for sentry"""
76-
async with ClientSession() as server:
77-
data = {
78-
"auth": {
79-
"identity": {
80-
"methods": ["password"],
81-
"password": {
82-
"user": {
83-
"id": SELECTEL_CONTAINER_USERNAME,
84-
"password": SELECTEL_CONTAINER_PASSWORD,
85-
}
86-
},
87-
}
68+
data = {
69+
"auth": {
70+
"identity": {
71+
"methods": ["password"],
72+
"password": {
73+
"user": {
74+
"id": SELECTEL_CONTAINER_USERNAME,
75+
"password": SELECTEL_CONTAINER_PASSWORD,
76+
}
77+
},
8878
}
8979
}
90-
async with server.post(
91-
"https://api.selcdn.ru/v3/auth/tokens",
92-
data=json.dumps(data),
93-
) as response:
94-
if response.status != 201:
95-
return Response(
96-
"Failed to get token", status_code=status.HTTP_409_CONFLICT
97-
)
98-
return response.json()
80+
}
81+
r = requests.post("https://api.selcdn.ru/v3/auth/tokens", json=data)
82+
if r.status_code not in [200, 201]:
83+
raise SelectelUploadError("couldn't generate a token for selcdn")
84+
return r.headers["x-subject-token"]
85+
# async with server.post(
86+
# "https://api.selcdn.ru/v3/auth/tokens",
87+
# data=json.dumps(data),
88+
# ) as response:
89+
# if response.status != 201:
90+
# return Response(
91+
# "Failed to get token", status_code=status.HTTP_409_CONFLICT
92+
# )
93+
# return response.json()

0 commit comments

Comments
 (0)