Skip to content

Commit

Permalink
Broke out add screenshot and swapped out cli commands
Browse files Browse the repository at this point in the history
  • Loading branch information
dsimmons87 committed Sep 4, 2023
1 parent 8d03788 commit 7e9219f
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 11 deletions.
3 changes: 2 additions & 1 deletion openra/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ def ready(self):
".management.commands.import_latest_engines",
".facades",
'.services.engine_file_repository',
'.services.map_file_repository'
'.services.map_file_repository',
'.services.screenshot_repository',
])
3 changes: 3 additions & 0 deletions openra/classes/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ def get_full_details(self):

def print_full_details(self):
print(self.get_full_details())

def __str__(self):
return self.get_full_details()
68 changes: 67 additions & 1 deletion openra/classes/file_location.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations
import io
from django.conf import os
from fs.base import FS, copy
from fs.tempfs import TempFS
Expand All @@ -17,7 +19,7 @@ def __init__(self, fs: FS, path: str, file: str):
self.file = file

def get_fs_path(self):
return os.path.join(self.path + self.file)
return os.path.join(self.path, self.file)

def get_os_dir(self):
try:
Expand All @@ -37,6 +39,30 @@ def get_os_path(self):
except Exception as exception:
raise ExceptionFileLocationGetOSPath(exception, self.fs, self.path, self.file)

def ensure_file_exists(self):
if not self.fs.exists(self.get_fs_path()):
if self.path:
self.fs.makedirs(self.path)
self.fs.create(self.get_fs_path())

def copy_to_file_location(self, location: FileLocation):
try:
location.ensure_file_exists()
copy.copy_file(
self.fs,
os.path.join(
self.path,
self.file
),
location.fs,
location.get_fs_path()
)

return location

except Exception as exception:
raise ExceptionFileLocationCopyToFileLocation(exception, self.fs, self.path, self.file, location)

def copy_to_tempfs(self, filename: str):
try:
temp_fs = TempFS()
Expand All @@ -58,6 +84,23 @@ def copy_to_tempfs(self, filename: str):
except Exception as exception:
raise ExceptionFileLocationCopyToTempFS(exception, self.fs, self.path, self.file, filename)

def get_file_clone(self):
try:

file = io.BytesIO()

self.fs.download(
self.get_fs_path(),
file
)

file.seek(0)

return file

except Exception as exception:
raise ExceptionFileLocationGetFileClone(exception, self.fs, self.path, self.file)


class ExceptionFileLocationGetOSDir(ExceptionBase):
def __init__(self, exception, fs: FS, path: str, file: str):
Expand All @@ -75,6 +118,19 @@ def __init__(self, exception, fs: FS, path: str, file: str):
self.message = "An exception occured while trying to get the os path"


class ExceptionFileLocationCopyToFileLocation(ExceptionBase):
def __init__(self, exception, fs: FS, path: str, file: str, target: FileLocation):
super().__init__()
self.message = "An exception occured while trying to copy a file to a TempFS"
self.detail.append('from fs type: ' + str(type(fs)))
self.detail.append('from path: ' + path)
self.detail.append('from file: ' + file)
self.detail.append('to fs type: ' + str(type(target.fs)))
self.detail.append('to path: ' + target.path)
self.detail.append('to file: ' + target.file)
self.detail.append('message: ' + str(exception))


class ExceptionFileLocationCopyToTempFS(ExceptionBase):
def __init__(self, exception, fs: FS, path: str, file: str, target: str):
super().__init__()
Expand All @@ -84,3 +140,13 @@ def __init__(self, exception, fs: FS, path: str, file: str, target: str):
self.detail.append('file: ' + file)
self.detail.append('target: ' + target)
self.detail.append('message: ' + str(exception))


class ExceptionFileLocationGetFileClone(ExceptionBase):
def __init__(self, exception, fs: FS, path: str, file: str):
super().__init__()
self.message = "An exception occured while trying to clone a file"
self.detail.append('fs type: ' + str(type(fs)))
self.detail.append('path: ' + path)
self.detail.append('file: ' + file)
self.detail.append('message: ' + str(exception))
23 changes: 23 additions & 0 deletions openra/classes/screenshot_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

from openra.classes.exceptions import ExceptionBase


class ScreenshotResource:

type: str
id: int

def __init__(self, type: str, id: int):
if type not in ['maps']:
raise ExceptionScreenshotResourceTypeInvalid(type, id)

self.type = type
self.id = id


class ExceptionScreenshotResourceTypeInvalid(ExceptionBase):
def __init__(self, type: str, id: int):
super().__init__()
self.message = "Invalid resource type for screenshot resource"
self.detail.append('Type : ' + type)
self.detail.append('Id: ' + str(id))
10 changes: 10 additions & 0 deletions openra/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from openra.services.log import Log
from openra.services.map_file_repository import MapFileRepository
from openra.services.map_search import MapSearch
from openra.services.screenshot_repository import ScreenshotRepository
from openra.services.uploaded_file_importer import UploadedFileImporter
from openra.services.utility import Utility


Expand Down Expand Up @@ -41,6 +43,14 @@ class Container(containers.DeclarativeContainer):
)
)

uploaded_file_importer = providers.Singleton(
UploadedFileImporter
)

screenshot_repository = providers.Singleton(
ScreenshotRepository
)

engine_file_repository = providers.Singleton(
EngineFileRepository
)
Expand Down
93 changes: 93 additions & 0 deletions openra/services/screenshot_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import io
from dependency_injector.wiring import Provide, inject
from django.conf import os
from django.contrib.auth.models import User
from django.core.files.uploadedfile import UploadedFile
from django.utils import timezone
from fs.base import FS, copy
from openra.classes.exceptions import ExceptionBase
from openra.classes.file_location import FileLocation
from openra.classes.screenshot_resource import ScreenshotResource
from openra.models import Screenshots
from PIL import Image

from openra.services.uploaded_file_importer import UploadedFileImporter


class ScreenshotRepository:

_data_fs: FS
_uploaded_file_importer: UploadedFileImporter

@inject
def __init__(
self,
data_fs: FS = Provide['data_fs'],
uploaded_file_importer: UploadedFileImporter = Provide['uploaded_file_importer']
):
self._data_fs = data_fs
self._uploaded_file_importer = uploaded_file_importer

def create_from_uploaded_file(self, uploaded_file: UploadedFile, user: User, resource: ScreenshotResource, map_preview: bool):

if uploaded_file.content_type not in ['image/jpeg', 'image/png', 'image/gif']:
raise ExceptionInvalidMimeType(uploaded_file.name, uploaded_file.content_type)

extension = uploaded_file.content_type.split('/')[1]

uploaded = self._uploaded_file_importer.import_file(
uploaded_file,
uploaded_file.name
)

image = Image.open(
uploaded.get_file_clone()
)

image.thumbnail((
250,
250
))

thumbnail = io.BytesIO()

image.save(thumbnail, extension)

thumbnail.seek(0)

model = Screenshots(
user=user,
ex_id=resource.id,
ex_name=resource.type,
posted=timezone.now(),
map_preview=map_preview,
)

model.save()

directory = os.path.join('screenshots', str(model.id))

uploaded.copy_to_file_location(
FileLocation(
self._data_fs,
directory,
str(resource.id) + '.' + extension
)
)

preview_path = os.path.join('screenshots', str(model.id), str(resource.id) + '-mini.' + extension)

self._data_fs.writefile(
preview_path,
thumbnail
)

return model


class ExceptionInvalidMimeType(ExceptionBase):
def __init__(self, filename: str, mimetype):
super().__init__()
self.message = "Mimetype invalid for a screenshot"
self.detail.append('Filename : ' + filename)
self.detail.append('Mimetype: ' + str(mimetype))
38 changes: 38 additions & 0 deletions openra/services/uploaded_file_importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django.core.files.uploadedfile import File
from fs.tempfs import TempFS

from openra.classes.exceptions import ExceptionBase
from openra.classes.file_location import FileLocation


class UploadedFileImporter:

def import_file(self, request_file: File, filename: str):

try:
temp_fs = self._create_temp_fs()

for chunk in request_file.chunks():
temp_fs.appendbytes(
filename,
chunk
)

return FileLocation(
temp_fs,
'',
filename
)
except Exception as exception:
raise ExceptionUploadedFileImporter(exception, filename)

def _create_temp_fs(self):
return TempFS()


class ExceptionUploadedFileImporter(ExceptionBase):
def __init__(self, exception, filename: str):
super().__init__()
self.message = "Uploaded file importer caught an exception while attempting to upload this file"
self.detail.append('filename: ' + filename)
self.detail.append('message: ' + str(exception))
4 changes: 2 additions & 2 deletions openra/templates/addScreenshotForm.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% if request.user.is_authenticated %}
<div class="upload_container">
<form action="/maps/{{arg}}/" method="POST" enctype="multipart/form-data">{% csrf_token %}
<form action="/maps/{{arg}}/upload-screenshot" method="POST" enctype="multipart/form-data">{% csrf_token %}
<div class='cBlock no-pd-bot'>
<h3>Upload screenshot of your map</h3>
</div>
Expand All @@ -22,4 +22,4 @@ <h3>Upload screenshot of your map</h3>
</div>
</form>
</div>
{% endif %}
{% endif %}
64 changes: 63 additions & 1 deletion openra/tests/test_classes_file_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from unittest import TestCase

from openra.classes.file_location import ExceptionFileLocationCopyToTempFS, ExceptionFileLocationGetOSDir, ExceptionFileLocationGetOSPath, FileLocation
from openra.classes.file_location import ExceptionFileLocationCopyToTempFS, ExceptionFileLocationGetFileClone, ExceptionFileLocationGetOSDir, ExceptionFileLocationGetOSPath, FileLocation


class TestFileLocation(TestCase):
Expand Down Expand Up @@ -85,6 +85,33 @@ def test_get_os_path_throws_exception_if_no_os_path(self):
file.get_os_path
)

def test_copy_to_file_location_copies_a_file(self):
fs = MemoryFS()

fs.makedir('location')
fs.writetext('location/test_file', 'file_content')

file = FileLocation(
fs,
'location/',
'test_file'
)

fs2 = MemoryFS()

file2 = FileLocation(
fs2,
'location2/',
'test_file2'
)

file.copy_to_file_location(file2)

self.assertEquals(
'file_content',
file2.fs.readtext(file2.get_fs_path())
)

def test_copy_to_tempfs_copies_a_file(self):
fs = MemoryFS()

Expand Down Expand Up @@ -125,3 +152,38 @@ def test_copy_to_tempfs_throws_exception_if_unable_to_copy(self):
file.copy_to_tempfs,
'new_name'
)

def test_get_file_clone(self):
fs = MemoryFS()

fs.makedir('location')
fs.writetext('location/test_file', 'file_content')

file = FileLocation(
fs,
'location/',
'test_file'
)

clone = file.get_file_clone()

self.assertEquals(
b'file_content',
clone.read()
)

def test_get_file_clone_throws_exception_if_unable_to_clone(self):
fs = MemoryFS()

fs.makedir('location')

file = FileLocation(
fs,
'location/',
'test_file'
)

self.assertRaises(
ExceptionFileLocationGetFileClone,
file.get_file_clone
)
Loading

0 comments on commit 7e9219f

Please sign in to comment.