🔀 Merged ClassQuizController
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
import ormar.exceptions
|
||||
@@ -64,12 +65,15 @@ async def generate_spreadsheet(quiz_results: dict, quiz: Quiz, player_fields: di
|
||||
worksheet.write(i + 1, 1, question["time"])
|
||||
|
||||
try:
|
||||
async with ClientSession() as session, session.get(question["image"]) as response:
|
||||
img_data = BytesIO(await response.read())
|
||||
worksheet.insert_image(i + 1, 2, question["image"], {"image_data": img_data})
|
||||
image = Image.open(img_data)
|
||||
worksheet.set_row(i + 1, image.height)
|
||||
worksheet.set_column(2, 2, image.width)
|
||||
async with ClientSession() as session, session.get(
|
||||
f"{settings.root_address}/api/v1/storage/download/{question['image']}"
|
||||
) as response:
|
||||
if "image" in response.headers.get("Content-Type"):
|
||||
img_data = BytesIO(await response.read())
|
||||
worksheet.insert_image(i + 1, 2, question["image"], {"image_data": img_data})
|
||||
image = Image.open(img_data)
|
||||
worksheet.set_row(i + 1, image.height)
|
||||
worksheet.set_column(2, 2, image.width)
|
||||
except TypeError:
|
||||
pass
|
||||
answer_amount = len(answer_data)
|
||||
@@ -175,3 +179,36 @@ def check_hashcash(data: str, input_data: str, claim_in: Optional[str] = "19") -
|
||||
return False
|
||||
some_error = [version == "1", claim == claim_in, res == input_data, ext == ""]
|
||||
return all(el is True for el in some_error)
|
||||
|
||||
|
||||
def check_image_string(image: str) -> (bool, uuid.UUID | None):
|
||||
# Valid formats: {uuid} and {uuid}--{uuid}
|
||||
try:
|
||||
parsed_uuid = uuid.UUID(image)
|
||||
return True, parsed_uuid
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
split_image = image.split("--")
|
||||
if len(split_image) != 2:
|
||||
return False, None
|
||||
|
||||
try:
|
||||
uuid.UUID(split_image[0])
|
||||
uuid.UUID(split_image[1])
|
||||
return True, None
|
||||
except ValueError:
|
||||
return False, None
|
||||
|
||||
|
||||
def extract_image_ids_from_quiz(quiz: Quiz) -> list[str | uuid.UUID]:
|
||||
quiz_images = []
|
||||
if quiz.background_image is not None:
|
||||
quiz_images.append(quiz.background_image)
|
||||
if quiz.cover_image is not None:
|
||||
quiz_images.append(quiz.cover_image)
|
||||
for question in quiz.questions:
|
||||
if question["image"] is None:
|
||||
continue
|
||||
quiz_images.append(question["image"])
|
||||
return quiz_images
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
from classquiz.config import redis, storage
|
||||
from classquiz.storage.errors import DeletionFailedError
|
||||
|
||||
|
||||
async def clean_editor_images_up():
|
||||
print("Cleaning images up")
|
||||
edit_sessions = await redis.smembers("edit_sessions")
|
||||
for session_id in edit_sessions:
|
||||
session = await redis.get(f"edit_session:{session_id}")
|
||||
if session is None:
|
||||
images = await redis.lrange(f"edit_session:{session_id}:images", 0, 3000)
|
||||
if len(images) != 0:
|
||||
try:
|
||||
await storage.delete(images)
|
||||
except DeletionFailedError:
|
||||
print("Deletion Error", images)
|
||||
await redis.srem("edit_sessions", session_id)
|
||||
await redis.delete(f"edit_session:{session_id}:images")
|
||||
@@ -0,0 +1,136 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
import enum
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ImageType(str, enum.Enum):
|
||||
all = "all"
|
||||
photo = "photo"
|
||||
illustration = "illustration"
|
||||
vector = "vector"
|
||||
|
||||
|
||||
class Orientation(str, enum.Enum):
|
||||
all = ("all",)
|
||||
horizontal = "horizontal"
|
||||
vertical = "vertical"
|
||||
|
||||
|
||||
class Category(str, enum.Enum):
|
||||
background = "background"
|
||||
fashion = "fashion"
|
||||
nature = "nature"
|
||||
science = "science"
|
||||
education = "education"
|
||||
feelings = "feelings"
|
||||
health = "health"
|
||||
people = "people"
|
||||
religion = "religion"
|
||||
places = "places"
|
||||
animals = "animals"
|
||||
industry = "industry"
|
||||
computer = "computer"
|
||||
food = "food"
|
||||
sports = "sports"
|
||||
transportation = "transportation"
|
||||
travel = "travel"
|
||||
buildings = "buildings"
|
||||
business = "business"
|
||||
music = "music"
|
||||
|
||||
|
||||
class Colors(str, enum.Enum):
|
||||
grayscale = "grayscale"
|
||||
transparent = "transparent"
|
||||
red = "red"
|
||||
orange = "orange"
|
||||
yellow = "yellow"
|
||||
green = "green"
|
||||
turquoise = "turquoise"
|
||||
blue = "blue"
|
||||
lilac = "lilac"
|
||||
pink = "pink"
|
||||
white = "white"
|
||||
gray = "gray"
|
||||
black = "black"
|
||||
brown = "brown"
|
||||
|
||||
|
||||
class Order(str, enum.Enum):
|
||||
popular = "popular"
|
||||
latest = "latest"
|
||||
|
||||
|
||||
class BoolInput(str, enum.Enum):
|
||||
true = "true"
|
||||
false = "false"
|
||||
|
||||
|
||||
class GetImagesParams(BaseModel):
|
||||
q: str = ""
|
||||
lang: str = "en"
|
||||
id: str = ""
|
||||
image_type: ImageType = ImageType.all
|
||||
orientation: Orientation = Orientation.all
|
||||
category: Category | str = ""
|
||||
min_width: int = 0
|
||||
min_height: int = 0
|
||||
colors: Colors | str = ""
|
||||
editors_choice: BoolInput = BoolInput.false
|
||||
safesearch: BoolInput = BoolInput.false
|
||||
order: Order = Order.popular
|
||||
page: int = 1
|
||||
pretty: BoolInput = BoolInput.false
|
||||
|
||||
|
||||
class Hit(BaseModel):
|
||||
id: int
|
||||
pageURL: str
|
||||
type: str
|
||||
tags: str
|
||||
previewURL: str
|
||||
previewWidth: int
|
||||
previewHeight: int
|
||||
webformatURL: str
|
||||
webformatWidth: int
|
||||
webformatHeight: int
|
||||
largeImageURL: str
|
||||
imageWidth: int
|
||||
imageHeight: int
|
||||
imageSize: int
|
||||
views: int
|
||||
downloads: int
|
||||
collections: int
|
||||
likes: int
|
||||
comments: int
|
||||
user_id: int
|
||||
user: str
|
||||
userImageURL: str
|
||||
|
||||
|
||||
class GetImagesResponse(BaseModel):
|
||||
total: int
|
||||
totalHits: int
|
||||
hits: list[Hit]
|
||||
|
||||
|
||||
class NotFoundError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
async def get_images(api_key: str, params: GetImagesParams) -> GetImagesResponse:
|
||||
async with ClientSession() as session, session.get(
|
||||
"https://pixabay.com/api/", params={"key": api_key, **params.dict()}
|
||||
) as resp:
|
||||
if resp.status == 200:
|
||||
return GetImagesResponse.parse_obj(await resp.json())
|
||||
else:
|
||||
raise NotFoundError
|
||||
Reference in New Issue
Block a user