Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor media storage for scalability #45

Merged
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
See for sample https://raw.githubusercontent.com/favoloso/conventional-changelog-emoji/master/CHANGELOG.md
-->


## [0.10.0] - 2024-MM-DD
### 🐛 Bug Fixes
- Fix admin % lighthouse inQueue value (#42)
- Fix admin % lighthouse inQueue value (#42)
- Refactor media storage for scalability (#44)

## [0.9.2] - 2024-05-20
### Improvements
Expand Down
11 changes: 7 additions & 4 deletions django/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,15 @@
AWS_S3_CUSTOM_DOMAIN = os.getenv('AWS_S3_CUSTOM_DOMAIN')
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=3600'}
AWS_S3_FILE_OVERWRITE = True
STATIC_ROOT = os.path.join(BASE_DIR, 'collectstatic')
# s3 static settings
AWS_LOCATION = 'static'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_ROOT = os.path.join(BASE_DIR, 'collectstatic')
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
DEFAULT_FILE_STORAGE = 'core.storage_backends.MediaStorage'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
sebastienbarbier marked this conversation as resolved.
Show resolved Hide resolved

if not AWS_S3_CUSTOM_DOMAIN:
raise ValueError("AWS_S3_CUSTOM_DOMAIN must be set when using S3 storage")

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# Application definition
Expand Down
5 changes: 5 additions & 0 deletions django/core/storage_backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from storages.backends.s3boto3 import S3Boto3Storage

class MediaStorage(S3Boto3Storage):
location = 'media'
file_overwrite = False
sebastienbarbier marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 1 addition & 3 deletions django/performances/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ def save_report(request, server_id, performance_id):
data = json.loads(request.body.decode("utf-8"))

# Generate metadata used for file storage
user = performance.project.user
slug = slugify(performance.url)
path = f'performance/{user}/{slug}'
path = performance.directory_path()
try:
filename = f'{data["audits"]["final-screenshot"]["details"]["timestamp"]}'
except:
Expand Down
1 change: 0 additions & 1 deletion django/performances/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.apps import AppConfig


class PerformancesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'performances'
19 changes: 18 additions & 1 deletion django/performances/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.db import models
from projects.models import Project
from django.conf import settings
from django.core.files.storage import default_storage
from django.template.defaultfilters import slugify
sebastienbarbier marked this conversation as resolved.
Show resolved Hide resolved

from constants import LIGHTHOUSE_FORMFACTOR_CHOICES

Expand Down Expand Up @@ -45,11 +47,26 @@ def last_score(self):
def __str__(self):
return f'{self.url}'

def directory_path(self):
user_pk = self.project.user.pk
project_pk = self.project.pk
return f'/{user_pk}/{project_pk}/performances/{self.pk}'
sebastienbarbier marked this conversation as resolved.
Show resolved Hide resolved

def delete(self):
super().delete()
if default_storage.exists(self.directory_path()):
try:
# Deletes the performance folder.
# Content has already been deleted by cascading.
default_storage.delete(self.directory_path())
sebastienbarbier marked this conversation as resolved.
Show resolved Hide resolved
except Exception as e:
print(f"Error deleting folder: {e}")

"""
REPORT MODEL
"""
def user_directory_path(instance, filename):
return 'performance/reports/{0}/{1}'.format(instance.performance.pk, filename)
return '{0}/{1}'.format(instance.performance.directory_path(), filename)

def delete_old_reports(report):
# Select all reports order from recent to old and if more than 4 delete all older than the 4 more recent
Expand Down
Loading