Skip to content

Commit

Permalink
Add progress template
Browse files Browse the repository at this point in the history
Ready for deployment
  • Loading branch information
saurzv committed May 18, 2023
1 parent 3a001e9 commit 1e87796
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 87 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ dmypy.json
# Cython debug symbols
cython_debug/

.vscode

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
Expand Down
34 changes: 14 additions & 20 deletions api/tasks.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import re
import os
from celery import shared_task
from django.conf import settings
from .models import Subtitle
import boto3
from dotenv import load_dotenv
import json

load_dotenv()
from celery import shared_task
from django.conf import settings
from server.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

tempFolder = os.path.join(settings.BASE_DIR, 'media/')

AWS_ACCESS_KEY = os.getenv('AWS_ACCESS_KEY')
AWS_SECRET_KEY = os.getenv('AWS_SECRET_KEY')

# extract content, start time, end time and make a json object


def parse_srt(path):
with open(path, 'r', encoding='utf-8') as f:
Expand All @@ -42,20 +34,22 @@ def parse_srt(path):
return sub_content


@shared_task(bind=True)
def generateSRT(self, video_name, video_id):
video_path = tempFolder+'uploads/'+video_name
sub_name = tempFolder+'subs/'+video_name[:-4]
def get_path(video_name):
return [os.path.join(tempFolder, 'uploads', video_name), os.path.join(tempFolder, 'subs', video_name[:-4]+'.srt')]

os.system("ccextractor {} -o {}.srt".format(video_path, sub_name))

sub_path = sub_name+'.srt'

srt_list = parse_srt(sub_path)
@shared_task(bind=True)
def generateSRT(self, video_name, video_id):
video_path, subtitle_path = get_path(video_name)
os.system("ccextractor {} -o {}".format(video_path, subtitle_path))
srt_list = parse_srt(subtitle_path)

dynamo_client = boto3.resource(service_name='dynamodb', region_name='ap-south-1',
aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY)
aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY)

table = dynamo_client.Table('subs')
data = {'test-key-1': str(video_id), 'srt': json.dumps(srt_list)}
table.put_item(Item=data)

os.remove(video_path)
os.remove(subtitle_path)
7 changes: 4 additions & 3 deletions api/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.urls import path
from .views import VideoView, SubtitleView
from .views import VideoView, SubtitleView, statusView

app_name = 'api'

urlpatterns = [
path('upload/', VideoView.as_view()),
path('subtitle/<int:id>', SubtitleView.as_view()),
]
path('subtitle/<int:id>/', SubtitleView.as_view()),
path('status/<str:task_id>/', statusView, name="status"),
]
28 changes: 15 additions & 13 deletions api/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
from .serializers import VideoSerializer, SubtitleSerializer
from rest_framework import filters
from rest_framework.generics import CreateAPIView, ListAPIView
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from server import celery_app
from .serializers import VideoSerializer, SubtitleSerializer
from .tasks import generateSRT
from .models import Subtitle
from rest_framework import filters
from server import celery_app
from django.shortcuts import redirect, HttpResponse
from django.urls import reverse


def statusView(request, task_id):
task = celery_app.AsyncResult(task_id)

return JsonResponse({'status': task.state})


class SubtitleView(ListAPIView):
Expand All @@ -26,14 +33,9 @@ def post(self, request, *args, **kwargs):
handle_upload(video)
video_name = video.name
res = super().post(request, *args, **kwargs)
task_id = generateSRT.delay(video_name, res.data['id'])

while True:
task = celery_app.AsyncResult(task_id)
if task.state == 'SUCCESS':
return redirect(reverse('pages:subtitle', kwargs={'id': res.data['id']}))
elif task.status == 'FAILURE':
return HttpResponse({'error': 'Something went wrong'})
task = generateSRT.delay(video_name, res.data['id'])

return redirect(reverse('pages:progress', kwargs={'task_id': task.task_id, 'id': res.data['id']}))


def handle_upload(video):
Expand Down
1 change: 0 additions & 1 deletion manage.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
Expand Down
12 changes: 12 additions & 0 deletions pages/static/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');

body {
box-sizing: border-box;
margin: 30px;
padding: 10px;
font-family: 'Montserrat', sans-serif;
}

h1 {
font-weight: 700;
}
3 changes: 3 additions & 0 deletions pages/templates/base.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
Expand All @@ -9,7 +10,9 @@
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="{% static 'styles.css' %}" />
<title>Subtitle Extractor</title>
{% block script %}{% endblock %}
</head>
<body>
<script
Expand Down
7 changes: 6 additions & 1 deletion pages/templates/form.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{% extends 'base.html' %} {% block content %}
<h1 class="position-absolute start-50 translate-middle">Subtitle Extractor</h1>
<form action="/api/upload/" method="post" enctype="multipart/form-data">
<div class="input-group">
<div
class="input-group position-absolute top-50 start-50 translate-middle w-50"
id="input-form"
>
{% csrf_token %}
<input
type="file"
Expand All @@ -9,6 +13,7 @@
id="inputGroupFile04"
aria-describedby="inputGroupFileAddon04"
aria-label="Upload"
accept="video/*"
/>
<button
class="btn btn-outline-secondary"
Expand Down
41 changes: 41 additions & 0 deletions pages/templates/progress.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% extends "base.html" %} {% block script %}
<script>
window.onload = function () {
function getStatus(url) {
fetch(url).then(function (response) {
response
.json()
.then(function (data) {
if (data.status === "SUCCESS") {
window.location.replace("{% url 'pages:subtitle' id %}");
} else if (data.status === "FALIURE") {
document.getElementById("progress").innerHTML =
"Error while extracting subtitle";
return;
}
})
.catch(function (error) {
console.log(error.message);
});
});
setInterval(getStatus, 10000, url);
}

var url = "{% url 'api:status' task_id %}";
getStatus(url);
};
</script>
{% endblock %} {% block content %}
<div
class="card position-absolute top-50 start-50 translate-middle"
style="width: 18rem"
id="progress"
>
<div class="card-body">
<h1 class="card-title">Please Wait</h1>
<p class="card-text">
Your video is being uploaded and subtitles are being extracted.
</p>
</div>
</div>
{% endblock %}
5 changes: 3 additions & 2 deletions pages/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from .views import index, subtitleView
from .views import index, subtitleView, progressView
from django.urls import path

app_name = 'pages'

urlpatterns = [
path('', index, name='index'),
path('subtitle/<int:id>', subtitleView, name='subtitle'),
]
path('progress/<str:task_id>/<int:id>', progressView, name="progress"),
]
15 changes: 13 additions & 2 deletions pages/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.shortcuts import render, HttpResponse
import boto3
from server.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
import json
from django.shortcuts import render
from server.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY


def index(request):
Expand All @@ -11,17 +11,28 @@ def index(request):
def subtitleView(request, *args, **kwargs):
dynamo_client = boto3.resource(service_name='dynamodb', region_name='ap-south-1',
aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY)

table = dynamo_client.Table('subs')
data = table.get_item(Key={'test-key-1': str(kwargs['id'])})
data = json.loads(data['Item']['srt'])

context = {'subtitles': data}

if request.method == 'POST':
context.clear()
context['subtitles'] = []
query = request.POST['search']

for subtitle in data:
if query.lower() in subtitle['content'].lower():
context['subtitles'].append(subtitle)

return render(request, 'subtitles.html', context)


def progressView(request, *args, **kwargs):
context = {
'task_id': kwargs['task_id'],
'id': kwargs['id'],
}
return render(request, 'progress.html', context)
9 changes: 0 additions & 9 deletions server/asgi.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
"""
ASGI config for server project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application
Expand Down
3 changes: 2 additions & 1 deletion server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
AWS_STORAGE_BUCKET_NAME = "subtitle-extractor"
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME + ".s3.amazonaws.com"

STORAGES = {"default": {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"}}
STORAGES = {"default": {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"},
"staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"}, }
27 changes: 1 addition & 26 deletions server/settings.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
from pathlib import Path
import os
from pathlib import Path
from dotenv import load_dotenv

load_dotenv()

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-j1o6yx$)#^(jlbpi^t+fae6mxik!tcr6s04#-8v7!06a8p=s%9'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
Expand Down Expand Up @@ -68,9 +57,6 @@
WSGI_APPLICATION = 'server.wsgi.application'


# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
Expand All @@ -79,9 +65,6 @@
}


# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
Expand All @@ -98,9 +81,6 @@
]


# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
Expand All @@ -110,9 +90,6 @@
USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'
STATIC_ROOT = 'static/'

Expand All @@ -122,8 +99,6 @@
else:
from server.config import *

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Expand Down
9 changes: 0 additions & 9 deletions server/wsgi.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
"""
WSGI config for server project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application
Expand Down

0 comments on commit 1e87796

Please sign in to comment.