summaryrefslogtreecommitdiff
path: root/fossee_manim
diff options
context:
space:
mode:
Diffstat (limited to 'fossee_manim')
-rw-r--r--fossee_manim/forms.py19
-rw-r--r--fossee_manim/models.py35
-rw-r--r--fossee_manim/send_mails.py31
-rw-r--r--fossee_manim/templates/fossee_manim/categorical_list.html28
-rw-r--r--fossee_manim/templates/fossee_manim/edit_proposal.html12
-rw-r--r--fossee_manim/templates/fossee_manim/upload_success.html29
-rw-r--r--fossee_manim/templates/fossee_manim/video.html24
-rw-r--r--fossee_manim/urls.py17
-rw-r--r--fossee_manim/views.py142
9 files changed, 277 insertions, 60 deletions
diff --git a/fossee_manim/forms.py b/fossee_manim/forms.py
index ec7568d..b3b33eb 100644
--- a/fossee_manim/forms.py
+++ b/fossee_manim/forms.py
@@ -2,7 +2,7 @@ from django import forms
from django.utils import timezone
from .models import (
Profile, User, Animation,
- Comment
+ Comment, AnimationStats
)
from string import punctuation, digits
try:
@@ -253,7 +253,6 @@ class AnimationProposal(forms.ModelForm):
class CommentForm(forms.ModelForm):
"""
- Instructors will post comments on Coordinators profile
"""
def __init__(self, *args, **kwargs):
@@ -267,4 +266,18 @@ class CommentForm(forms.ModelForm):
exclude = ['animation', 'created_date', 'commentor']
widgets = {
'comments': forms.CharField(),
- } \ No newline at end of file
+ }
+
+
+class UploadAnimationForm(forms.ModelForm):
+
+ def __init__(self, *args, **kwargs):
+ super(UploadAnimationForm, self).__init__(*args, **kwargs)
+ self.fields['video_path'].label = "Animation"
+
+ class Meta:
+ model = AnimationStats
+ exclude = ['animation', 'views', 'like', 'dislike', 'thumbnail']
+ widgets = {
+ 'video_path': forms.FileInput(),
+ }
diff --git a/fossee_manim/models.py b/fossee_manim/models.py
index 77c7552..75f03da 100644
--- a/fossee_manim/models.py
+++ b/fossee_manim/models.py
@@ -1,9 +1,14 @@
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import RegexValidator
+from django.conf import settings
+from django.utils import timezone
+from django.core.files import File
from taggit.managers import TaggableManager
from simple_history.models import HistoricalRecords
-from django.utils import timezone
+from os import path, sep
+import tempfile
+import subprocess
position_choices = (
@@ -96,6 +101,12 @@ def has_profile(user):
return True if hasattr(user, 'profile') else False
+def attachments(instance, filename):
+ return path.join(instance.animation.category.name,
+ instance.animation.title,
+ str(instance.animation.id), filename)
+
+
class Profile(models.Model):
"""Profile for users(instructors and coordinators)"""
@@ -156,7 +167,6 @@ class Animation(models.Model):
github = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
created = models.DateTimeField(default=timezone.now)
- updated = models.DateTimeField(default=timezone.now)
tags = TaggableManager()
history = HistoricalRecords()
@@ -181,4 +191,23 @@ class AnimationStats(models.Model):
animation = models.ForeignKey(Animation, on_delete=models.CASCADE)
views = models.PositiveIntegerField(default=0)
like = models.PositiveIntegerField(default=0)
- dislike = models.PositiveIntegerField(default=0) \ No newline at end of file
+ dislike = models.PositiveIntegerField(default=0)
+ thumbnail = models.ImageField(null=True, blank=True, upload_to=attachments)
+ video_path = models.FileField(null=True, blank=True, upload_to=attachments)
+
+ def _create_thumbnail(self):
+ # anime = AnimationStats.objects.get(
+ # animation=proposal)
+ video_path = self.video_path.path
+ img_output = path.join(
+ tempfile.mkdtemp(), "{0}.jpg".format(self.animation.title)
+ )
+ file_name = "{0}.jpg".format(self.animation.title)
+ subprocess.call(['ffmpeg', '-i', video_path, '-ss', '00:00:09.000',
+ '-vframes', '1', img_output])
+ if path.exists(img_output):
+ que_file = open(img_output, 'rb')
+ # Converting to Python file object with
+ # some Django-specific additions
+ django_file = File(que_file)
+ self.thumbnail.save(file_name, django_file, save=True)
diff --git a/fossee_manim/send_mails.py b/fossee_manim/send_mails.py
index f9f7a75..a329e8b 100644
--- a/fossee_manim/send_mails.py
+++ b/fossee_manim/send_mails.py
@@ -1,20 +1,19 @@
-from django.core.mail import EmailMultiAlternatives
+from django.core.mail import EmailMultiAlternatives, send_mail
from django.conf import settings
+from django.utils.crypto import get_random_string
from os import listdir, path
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from time import sleep
-import hashlib
-import logging.config
-import re
-from django.core.mail import send_mail
from textwrap import dedent
from random import randint
from smtplib import SMTP
-from django.utils.crypto import get_random_string
from string import punctuation, digits
+from hashlib import sha256
+import logging.config
+import re
try:
from string import letters
except ImportError:
@@ -29,13 +28,15 @@ from fossee_anime.settings import (
SENDER_EMAIL,
ADMIN_EMAIL
)
+
+
__author__ = "Akshen Doke"
def validateEmail(email):
if len(email) > 7:
if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$",
- email) != None:
+ email) is not None:
return 1
return 0
@@ -43,8 +44,8 @@ def validateEmail(email):
def generate_activation_key(username):
"""Generates hashed secret key for email activation"""
chars = letters + digits + punctuation
- secret_key = get_random_string(randint(10,40), chars)
- return hashlib.sha256((secret_key + username).encode('utf-8')).hexdigest()
+ secret_key = get_random_string(randint(10, 40), chars)
+ return sha256((secret_key + username).encode('utf-8')).hexdigest()
def send_email(request, call_on, contributor=None, key=None, proposal=None):
@@ -53,7 +54,7 @@ def send_email(request, call_on, contributor=None, key=None, proposal=None):
try:
with open(path.join(settings.LOG_FOLDER,
- 'emailconfig.yaml'), 'r') as configfile:
+ 'emailconfig.yaml'), 'r') as configfile:
config_dict = yaml.load(configfile)
logging.config.dictConfig(config_dict)
except:
@@ -87,7 +88,8 @@ def send_email(request, call_on, contributor=None, key=None, proposal=None):
Congratulations! your animations has been released on
FOSSEE's website.
- Please start with your honouriam process
+ Your animation will be live in 72 working hours.
+ Please start with your honorarium process
In case of queries, please revert to this
email.""".format(contributor.profile.user.username))
@@ -112,7 +114,7 @@ def send_email(request, call_on, contributor=None, key=None, proposal=None):
logging.info("Animation Rejected: %s", request.user.email)
send_mail(
"FOSSEE Animation Status Update", message, SENDER_EMAIL,
- [contributor.profile.user.email], fail_silently=True
+ [contributor.profile.user.email], fail_silently=True
)
elif call_on == 'changes':
message = dedent("""\
@@ -123,10 +125,9 @@ def send_email(request, call_on, contributor=None, key=None, proposal=None):
In case of queries, please revert to this
email.""".format(contributor.profile.user.username,
- proposal.title))
+ proposal.title))
logging.info("Changes Required: %s", request.user.email)
send_mail(
"FOSSEE Animation Changes required", message, SENDER_EMAIL,
- [contributor.profile.user.email], fail_silently=True
- ) \ No newline at end of file
+ [contributor.profile.user.email], fail_silently=True)
diff --git a/fossee_manim/templates/fossee_manim/categorical_list.html b/fossee_manim/templates/fossee_manim/categorical_list.html
new file mode 100644
index 0000000..a61ab40
--- /dev/null
+++ b/fossee_manim/templates/fossee_manim/categorical_list.html
@@ -0,0 +1,28 @@
+{% extends 'fossee_manim/base.html' %}
+
+ {% block title %}
+ FOSSEE Animation
+ {% endblock %}
+
+{% block content %}
+ <br>
+ <div class="container" align="center">
+ <br>
+ <div class="row">
+ <div class="col-md-12">
+ <h1 style="float: left;">{{ categorial_list.0.animation.category }}</h1>
+ </div>
+ </div>
+ <hr>
+ <br>
+ <div style="width:150px; float: left;">
+ {% for video in categorial_list %}
+ <div class="row">
+ <a href="{% url 'video' video.id %}" ><img height="100%" width="200%" src="{{ video.thumbnail.url }}"></a>
+ </div>
+ <hr>
+ {% endfor %}
+ </div>
+ <br>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/fossee_manim/templates/fossee_manim/edit_proposal.html b/fossee_manim/templates/fossee_manim/edit_proposal.html
index c73071b..3edad99 100644
--- a/fossee_manim/templates/fossee_manim/edit_proposal.html
+++ b/fossee_manim/templates/fossee_manim/edit_proposal.html
@@ -19,7 +19,19 @@
<br>
<button class="btn btn-primary pull-right" type="submit">Save</button>
+ <br>
+ </form>
+ <br>
+
+ {% if proposal_form.instance.status == 'changes' %}
+ <form method="POST" action="{% url 'upload_animation' proposal_form.instance.id %}" enctype="multipart/form-data">
+ {% csrf_token %}
+ <label class="btn btn-info">
+ {{ upload_form }}
+ <button class="btn btn-success" type="submit">Upload</button>
+ </label>
</form>
+ {% endif %}
<br><br>
{% if request.user.profile.position == 'reviewer' %}
diff --git a/fossee_manim/templates/fossee_manim/upload_success.html b/fossee_manim/templates/fossee_manim/upload_success.html
new file mode 100644
index 0000000..61a992a
--- /dev/null
+++ b/fossee_manim/templates/fossee_manim/upload_success.html
@@ -0,0 +1,29 @@
+
+{% extends 'fossee_manim/base.html' %}
+
+{% block title %}
+ Upload success
+{% endblock %}
+
+
+ {% block extra %}
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="{{URL_ROOT}}/static/fossee_manim/js/bootstrap-3.3.7.min.js"></script>
+ <script type="text/javascript">
+ window.setTimeout(function()
+ {
+ location.href="{% url 'proposal_status' %}"
+ }, 9000);
+</script>
+
+ {% endblock %}
+{% block content %}
+ <div class="container">
+ <br><br>
+ <div class="jumbotron">
+ <h3><strong>Congrats!</strong> video uploaded successfully!</h3>
+ <br>
+ <h5><strong>If you've previously uploaded any video, it would be overridden by this upload</h5>
+ </div>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/fossee_manim/templates/fossee_manim/video.html b/fossee_manim/templates/fossee_manim/video.html
new file mode 100644
index 0000000..ff020e5
--- /dev/null
+++ b/fossee_manim/templates/fossee_manim/video.html
@@ -0,0 +1,24 @@
+{% extends 'fossee_manim/base.html' %}
+
+ {% block title %}
+ FOSSEE Animation
+ {% endblock %}
+
+{% block content %}
+ <br>
+ <div class="container" align="center">
+ <br>
+ <div class="row" >
+ <div class="col-md-8">
+ <video width="100%" height="100%" controls>
+ <source src="{{video.0.video_path.url}}" type="video/mp4">
+ </video>
+ <p style="float: left;"> {{ video.0.views }} views</p>
+ </div>
+ <div class="col-md-4">
+ </div>
+
+ </div>
+ <br>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/fossee_manim/urls.py b/fossee_manim/urls.py
index 7bc7740..278dee2 100644
--- a/fossee_manim/urls.py
+++ b/fossee_manim/urls.py
@@ -1,5 +1,8 @@
from django.conf.urls import url
from fossee_manim import views
+from django.conf import settings
+from django.conf.urls.static import static
+
urlpatterns = [
url(r'^$', views.index, name='index'),
@@ -11,8 +14,18 @@ urlpatterns = [
url(r'^send_proposal/$', views.send_proposal, name='send_proposal'),
url(r'^edit_proposal/([1-9][0-9]*)$', views.edit_proposal,
name='edit_proposal'),
+ url(r'^upload_animation/([1-9][0-9]*)$', views.upload_animation,
+ name='upload_animation'),
url(r'^proposal_status/$', views.proposal_status, name='proposal_status'),
url(r'^search/$', views.search, name='search'),
url(r'^view_profile/$', views.view_profile, name='view_profile'),
- url(r'^edit_profile/$', views.edit_profile, name='edit_profile')
-] \ No newline at end of file
+ url(r'^edit_profile/$', views.edit_profile, name='edit_profile'),
+ url(r'^video/([1-9][0-9]*)$', views.video, name='video'),
+ url(r'^search_category/(?P<cat>.+)$', views.search_category,
+ name='search_category')
+]
+
+urlpatterns += static(
+ settings.MEDIA_URL,
+ document_root=settings.MEDIA_ROOT
+)
diff --git a/fossee_manim/views.py b/fossee_manim/views.py
index d9b27b2..58cc794 100644
--- a/fossee_manim/views.py
+++ b/fossee_manim/views.py
@@ -1,12 +1,13 @@
-from django.shortcuts import render
+from os import listdir, path, sep, makedirs, remove
from .forms import (
UserRegistrationForm, UserLoginForm,
- ProfileForm, AnimationProposal,
- CommentForm
+ ProfileForm, AnimationProposal,
+ CommentForm, UploadAnimationForm
)
from .models import (
Profile, User, AnimationStats,
- has_profile, Animation, Comment
+ has_profile, Animation, Comment,
+ Category
)
from datetime import datetime, date
from django.contrib.auth import login, logout, authenticate
@@ -15,24 +16,42 @@ from django.contrib import messages
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render, redirect
from django.utils import timezone
-from .send_mails import send_email
from django.http import HttpResponse, HttpResponseRedirect
-from textwrap import dedent
from django.conf import settings
-from os import listdir, path, sep
-from zipfile import ZipFile
+from django.core.files.uploadhandler import FileUploadHandler
from django.contrib import messages
-from django.db.models import Q
+from django.db.models import F, Subquery, OuterRef
+from zipfile import ZipFile
+from textwrap import dedent
+from requests import get
+from .send_mails import send_email
import datetime as dt
-import os
+import shutil
try:
from StringIO import StringIO as string_io
except ImportError:
from io import BytesIO as string_io
+def makepath(proposal_data, reject=None):
+ if not path.exists(path.join(settings.MEDIA_ROOT,
+ proposal_data.category.name)):
+ makedirs(path.join(settings.MEDIA_ROOT,
+ proposal_data.category.name))
+
+ if reject:
+ shutil.rmtree(path.join(
+ settings.MEDIA_ROOT, proposal_data.category.name,
+ proposal_data.title.replace(" ", "_")
+ + str(proposal_data.id)))
+ else:
+ makedirs(path.join(settings.MEDIA_ROOT, proposal_data.category.name,
+ proposal_data.title.replace(" ", "_")
+ + str(proposal_data.id)))
+
+
def check_repo(link):
- return True if 'github.com' in link else False
+ return (get(link).status_code == 200)
def is_email_checked(user):
@@ -43,7 +62,7 @@ def is_email_checked(user):
def is_superuser(user):
- return True if user.is_superuser else False
+ return user.is_superuser
def index(request):
@@ -52,8 +71,8 @@ def index(request):
user = request.user
form = UserLoginForm()
if user.is_authenticated() and is_email_checked(user):
- if user.groups.filter(name='reviewer').count() > 0:
- return redirect('/view_profile/')
+ if user.groups.filter(name='reviewer').exists:
+ return redirect('/proposal_status/')
return redirect('/view_profile/')
elif request.method == "POST":
form = UserLoginForm(request.POST)
@@ -62,8 +81,8 @@ def index(request):
login(request, user)
if is_superuser(user):
return redirect("/admin")
- if user.groups.filter(name='reviewer').count() > 0:
- return redirect('/view_profile/')
+ if user.groups.filter(name='reviewer').exists():
+ return redirect('/proposal_status/')
return redirect('/view_profile/')
return render(request, "fossee_manim/index.html", {"form": form})
@@ -71,7 +90,7 @@ def index(request):
def is_reviewer(user):
'''Check if the user is having reviewer rights'''
- return True if user.groups.filter(name='reviewer').count() > 0 else False
+ return user.groups.filter(name='reviewer').exists()
def user_login(request):
@@ -248,14 +267,15 @@ def send_proposal(request):
if form.is_valid():
form_data = form.save(commit=False)
form_data.contributor = user
- form_data.status = "pending"
+ form_data.status = "pending"
if check_repo(form_data.github):
form_data.save()
form.save_m2m()
+ # makepath(form_data)
else:
messages.warning(request, 'Please enter valid github details')
return render(request, 'fossee_manim/send_proposal.html',
- {'form': form})
+ {'form': form})
return redirect('/proposal_status/')
else:
form = AnimationProposal()
@@ -272,8 +292,7 @@ def proposal_status(request):
if profile.position == 'contributor':
anime = Animation.objects.filter(contributor_id=user)
else:
- anime_list = Animation.objects.filter(Q(status='pending') |
- Q(status='changes'))
+ anime_list = Animation.objects.order_by('-created')
return render(request, 'fossee_manim/proposal_status.html',
{'anime': anime, 'anime_list': anime_list})
@@ -284,28 +303,30 @@ def edit_proposal(request, proposal_id=None):
comment_form = CommentForm()
proposal = Animation.objects.get(id=proposal_id)
proposal_form = AnimationProposal(instance=proposal)
+ upload_form = UploadAnimationForm()
try:
- comments = Comment.objects.all().order_by('-created_date')
+ comments = Comment.objects.filter(animation_id=proposal_id).order_by(
+ '-created_date'
+ )
except:
comments = None
if request.method == 'POST':
text = request.POST.get('comment')
- s1 = request.POST.get('release')
- s2 = request.POST.get('rejected')
+ status1 = request.POST.get('release')
+ status2 = request.POST.get('rejected')
- if s1 or s2 is not None:
- if s1:
+ if status1 or status2 is not None:
+ if status1:
proposal.status = 'released'
- proposal.reviewer = user
- proposal.save()
send_email(request, call_on='released',
- contributor=proposal.contributor)
+ contributor=proposal.contributor)
else:
proposal.status = 'rejected'
- proposal.reviewer = user
- proposal.save()
+ makepath(proposal, reject=1)
send_email(request, call_on='rejected',
- contributor=proposal.contributor)
+ contributor=proposal.contributor)
+ proposal.reviewer = user
+ proposal.save()
return redirect('/proposal_status/')
if text is not None:
@@ -315,9 +336,10 @@ def edit_proposal(request, proposal_id=None):
form_data.animation = proposal
if user.profile.position == 'reviewer':
proposal.status = 'changes'
+ proposal.save()
send_email(request, call_on='changes',
- contributor=proposal.contributor,
- proposal=proposal)
+ contributor=proposal.contributor,
+ proposal=proposal)
form_data.save()
return redirect('/edit_proposal/{}'.format(proposal_id))
proposal_form = AnimationProposal(request.POST, instance=proposal)
@@ -345,13 +367,59 @@ def edit_proposal(request, proposal_id=None):
comments = paginator.page(paginator.num_pages)
return render(request, 'fossee_manim/edit_proposal.html',
{'proposal_form': proposal_form,
- "comments": comments,
- "comment_form": comment_form})
+ "comments": comments,
+ "comment_form": comment_form,
+ "upload_form": upload_form})
def search(request):
if request.method == 'POST':
word = request.POST.get('sbox')
-
return render(request, 'fossee_manim/search_results.html')
+
+@login_required
+def upload_animation(request, proposal_id=None):
+ if request.method == 'POST':
+ proposal = Animation.objects.get(id=proposal_id)
+ anim_stats = UploadAnimationForm(request.POST or None,
+ request.FILES or None)
+
+ # return redirect('/edit_proposal/{}'.format(proposal_id))
+ if anim_stats.is_valid():
+ anim = AnimationStats.objects.filter(
+ animation=proposal)
+ if anim.exists():
+ anobj = anim.first()
+ try:
+ remove(anobj.thumbnail.path)
+ except:
+ pass
+ remove(anobj.video_path.path)
+ anobj.delete()
+ anobj = AnimationStats.objects.create(
+ animation=proposal, video_path=request.FILES['video_path'])
+ else:
+ anobj = AnimationStats.objects.create(
+ animation=proposal, video_path=request.FILES['video_path'])
+ anobj._create_thumbnail()
+ return render(request, 'fossee_manim/upload_success.html')
+ else:
+ return redirect('/view_profile/')
+
+
+def video(request, id=None):
+ video = AnimationStats.objects.filter(id=id)
+ # if views crosses limit comment the line below
+ video.update(views=F('views')+1)
+ video.update(like=F('like')+1)
+ suggestion_list = AnimationStats.objects.filter()
+ return render(request, 'fossee_manim/video.html', {'video': video})
+
+
+def search_category(request, cat=None):
+ cat_id = Category.objects.get(name=cat)
+ anim_list = AnimationStats.objects.all()
+ cat_video_list = [x for x in anim_list if (x.animation.category == cat_id)]
+ return render(request, 'fossee_manim/categorical_list.html',
+ {'categorial_list': cat_video_list})