feature(File TTL):

Added File TTL Option, with example
Removed Databases config in settings
This commit is contained in:
Devoalda 2023-10-23 15:12:17 +08:00
parent e28fc89b3d
commit f818ac3d52
3 changed files with 118 additions and 48 deletions

View File

@ -115,31 +115,31 @@ WSGI_APPLICATION = 'safeshare.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases # https://docs.djangoproject.com/en/4.2/ref/settings/#databases
if os.getenv('GITHUB_WORKFLOW'): # if os.getenv('GITHUB_WORKFLOW'):
DATABASES = { # DATABASES = {
'default': { # 'default': {
'ENGINE': 'django.db.backends.postgresql', # 'ENGINE': 'django.db.backends.postgresql',
'NAME': 'github-actions', # 'NAME': 'github-actions',
'USER': 'postgres', # 'USER': 'postgres',
'PASSWORD': 'postgres', # 'PASSWORD': 'postgres',
'HOST': 'localhost', # 'HOST': 'localhost',
'PORT': '5432' # 'PORT': '5432'
} # }
} # }
else: # else:
DATABASES = { # DATABASES = {
'default': { # 'default': {
'ENGINE': 'django.db.backends.mysql', # 'ENGINE': 'django.db.backends.mysql',
'NAME': env.str('DB_NAME', 'safeshare'), # 'NAME': env.str('DB_NAME', 'safeshare'),
'USER': env.str('DB_USER', 'mariadb'), # 'USER': env.str('DB_USER', 'mariadb'),
'PASSWORD': env.str('DB_PASSWORD', 'mariadb'), # 'PASSWORD': env.str('DB_PASSWORD', 'mariadb'),
'HOST': env.str('DB_HOST', 'localhost'), # 'HOST': env.str('DB_HOST', 'localhost'),
'PORT': env.str('DB_PORT', '3306'), # 'PORT': env.str('DB_PORT', '3306'),
'OPTIONS': { # 'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES', innodb_strict_mode=1", # 'init_command': "SET sql_mode='STRICT_TRANS_TABLES', innodb_strict_mode=1",
}, # },
} # }
} # }
if env.bool('CACHE', default=False): if env.bool('CACHE', default=False):
CACHES = { CACHES = {

View File

@ -1,23 +1,33 @@
import requests import requests
import json import json
import time
url = "http://127.0.0.1:8000/api/files/" url = "http://127.0.0.1:8000/api/files/"
file = {'file': open('test.text', 'rb')} file = {'file': open('test.text', 'rb')}
data = {'ttl': 2}
r = requests.post(url, files=file) r = requests.post(url, files=file, data=data)
# Print response message # Print response message
print(json.dumps(r.json(), indent=4)) print(json.dumps(r.json(), indent=4))
key = r.json()['key'] key = r.json()['key']
# Wait for file to expire
time.sleep(3)
url = "http://127.0.0.1:8000/api/files/" + key + "/" url = "http://127.0.0.1:8000/api/files/" + key + "/"
r = requests.get(url) r = requests.get(url)
file = r.json()['file'] # Print response message
print(json.dumps(r.json(), indent=4))
if r.json()['file'] is not None:
file = r.json()['file']
# Change file to bytes # Change file to bytes
file = bytes(file, 'utf-8') file = bytes(file, 'utf-8')
# Write response('file') to disk # Write response('file') to disk
with open('test2.text', 'wb') as f: with open('test2.text', 'wb') as f:
f.write(file) f.write(file)

View File

@ -1,43 +1,103 @@
import uuid import uuid
import threading
import redis import redis
from django.conf import settings from django.conf import settings
from rest_framework.decorators import api_view from rest_framework.decorators import api_view
from rest_framework.response import Response from rest_framework.response import Response
from django.core.cache import cache
redis_instance = redis.StrictRedis(host=settings.REDIS_HOST, # redis_instance = redis.StrictRedis(host=settings.REDIS_HOST,
port=settings.REDIS_PORT, db=0) # port=settings.REDIS_PORT, db=0)
@api_view(['GET', 'POST']) @api_view(['GET', 'POST'])
def manage_items(request, *args, **kwargs): def manage_items(request, *args, **kwargs):
if request.method == 'GET': if request.method == 'GET':
# Not supposed to enumerate all items, so return 405 # Not supposed to enumerate all items, so return 405
return Response({ return Response({'msg': 'Method not allowed'}, status=405)
'msg': 'Method not allowed'
}, status=405)
if request.method == 'POST': if request.method == 'POST':
# Define a timeout value (in seconds)
timeout = 5
ttl = request.data['ttl']
if not ttl:
return Response({'msg': 'TTL not provided'}, status=400)
try:
# Convert the TTL to an integer
ttl = int(ttl)
if ttl <= 0:
return Response({'msg': 'TTL must be a positive integer'}, status=400)
except ValueError:
return Response({'msg': 'Invalid TTL format'}, status=400)
# Define a function to save the file in a thread
def save_file_to_redis():
key = uuid.uuid4().hex key = uuid.uuid4().hex
file = request.FILES['file'] file = request.FILES['file']
filename = 'file.txt' if not file:
return Response({'msg': 'No file provided'}, status=400)
filename = file.name
# Convert file to bytes # Convert file to bytes
file = file.read() file = file.read()
redis_instance.set(key, file)
# Set with ttl if ttl is provided
cache.set(key, file, timeout=ttl)
response = { response = {
'key': key, 'key': key,
'msg': f"{key} successfully set to {filename}: {file}" 'msg': f"{key} successfully set to {filename}: {file}, with a ttl of {ttl} seconds"
} }
return Response(response, 201)
# Store the response in a shared variable
nonlocal saved_response
saved_response = response
# Create a shared variable to store the response
saved_response = None
# Create a new thread for the file-saving process
file_saving_thread = threading.Thread(target=save_file_to_redis)
# Start the file-saving thread
file_saving_thread.start()
# Use a Timer to add a timeout
timeout_event = threading.Event()
timeout_timer = threading.Timer(timeout, lambda: timeout_event.set())
try:
# Start the timer
timeout_timer.start()
# Wait for the file-saving thread to complete
file_saving_thread.join()
# Check if the thread completed without a timeout
if not timeout_event.is_set():
if saved_response:
return Response(saved_response, status=201)
else:
return Response({'msg': 'File saving failed'}, status=500)
else:
return Response({'msg': 'File saving timed out'}, status=500)
finally:
# Always cancel the timer to prevent it from firing after the thread completes
timeout_timer.cancel()
@api_view(['GET', 'PUT', 'DELETE']) @api_view(['GET', 'PUT', 'DELETE'])
def manage_item(request, *args, **kwargs): def manage_item(request, *args, **kwargs):
if request.method == 'GET': if request.method == 'GET':
if kwargs['key']: if kwargs['key']:
value = redis_instance.get(kwargs['key']) value = cache.get(kwargs['key'])
if value: if value:
response = { response = {
'key': kwargs['key'], 'key': kwargs['key'],
@ -76,7 +136,7 @@ def manage_item(request, *args, **kwargs):
elif request.method == 'DELETE': elif request.method == 'DELETE':
if kwargs['key']: if kwargs['key']:
result = redis_instance.delete(kwargs['key']) result = cache.delete(kwargs['key'])
if result == 1: if result == 1:
response = { response = {
'msg': f"{kwargs['key']} successfully deleted" 'msg': f"{kwargs['key']} successfully deleted"