summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--fossee_anime/settings.py12
-rw-r--r--fossee_anime/urls.py6
-rw-r--r--fossee_manim/admin.py29
-rw-r--r--fossee_manim/forms.py24
-rw-r--r--fossee_manim/models.py48
-rw-r--r--fossee_manim/send_mails.py31
-rw-r--r--fossee_manim/static/css/sticky-footer.css26
-rw-r--r--fossee_manim/templates/fossee_manim/base.html15
-rw-r--r--fossee_manim/templates/fossee_manim/categorical_list.html38
-rw-r--r--fossee_manim/templates/fossee_manim/edit_proposal.html16
-rw-r--r--fossee_manim/templates/fossee_manim/how_to.html21
-rw-r--r--fossee_manim/templates/fossee_manim/index.html50
-rw-r--r--fossee_manim/templates/fossee_manim/search_results.html31
-rw-r--r--fossee_manim/templates/fossee_manim/upload_success.html29
-rw-r--r--fossee_manim/templates/fossee_manim/video.html89
-rw-r--r--fossee_manim/tests/test_models.py61
-rw-r--r--fossee_manim/tests/test_views.py94
-rw-r--r--fossee_manim/urls.py18
-rw-r--r--fossee_manim/views.py222
-rw-r--r--requirements.txt6
21 files changed, 734 insertions, 133 deletions
diff --git a/.gitignore b/.gitignore
index 8b5c84e..ec6dd19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,4 @@ migrations/
index_clutter.html
base_clutter.html
+data/
diff --git a/fossee_anime/settings.py b/fossee_anime/settings.py
index 53b200b..9b3d6ed 100644
--- a/fossee_anime/settings.py
+++ b/fossee_anime/settings.py
@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/1.9/ref/settings/
import os
import sys
-from local_settings import (
+from .local_settings import (
EMAIL_HOST,
EMAIL_PORT,
EMAIL_HOST_USER,
@@ -77,6 +77,8 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
+ 'django.template.context_processors.media',
+
],
},
},
@@ -140,11 +142,11 @@ LOGIN_URL = '/login/'
MEDIA_URL = '/data/'
-MEDIA_ROOT = os.path.join(BASE_DIR, "workshop_app", "data")
+MEDIA_ROOT = os.path.join(BASE_DIR, "fossee_manim", 'data')
-LOG_FOLDER = os.path.join(BASE_DIR, "workshop_app", "logs")
+LOG_FOLDER = os.path.join(BASE_DIR, "fossee_manim", "logs")
-#Email Connection Settings
+# Email Connection Settings
EMAIL_HOST = EMAIL_HOST
EMAIL_HOST_USER = EMAIL_HOST_USER
EMAIL_HOST_PASSWORD = EMAIL_HOST_PASSWORD
@@ -155,7 +157,7 @@ SENDER_EMAIL = SENDER_EMAIL
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
-#Change this to the production url
+# Change this to the production url
PRODUCTION_URL = 'your_production_url'
ADMIN_EMAIL = 'your admin email' \ No newline at end of file
diff --git a/fossee_anime/urls.py b/fossee_anime/urls.py
index dff7bac..9fb65d5 100644
--- a/fossee_anime/urls.py
+++ b/fossee_anime/urls.py
@@ -17,9 +17,13 @@ Including another URLconf
from django.conf.urls import url, include
from django.contrib import admin
from fossee_manim import views
+from django.conf import settings
+from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('fossee_manim.urls')),
url(r'^', include('fossee_manim.urls_password_reset'))
-] \ No newline at end of file
+]
+urlpatterns += static(settings.MEDIA_URL,
+ document_root=settings.MEDIA_ROOT) \ No newline at end of file
diff --git a/fossee_manim/admin.py b/fossee_manim/admin.py
index 35bf57b..121c487 100644
--- a/fossee_manim/admin.py
+++ b/fossee_manim/admin.py
@@ -46,5 +46,32 @@ class CategoryAdmin(admin.ModelAdmin):
list_filter = ['name']
+class AnimationAdmin(admin.ModelAdmin):
+ list_display = ['title', 'status', 'contributor']
+ list_filter = ['category']
+ actions = ['download_data']
+
+ def download_data(self, request, queryset):
+ openfile = string_io()
+ response = HttpResponse(content_type='text/csv')
+ response['Content-Disposition'] = 'attachment;\
+ filename=animations_data.csv'
+
+ writer = csv.writer(response)
+ writer.writerow(['title', 'contributor', 'reviewer', 'description',
+ 'status', 'github link', 'category'])
+
+ for q in queryset:
+ writer.writerow([q.title, q.contributor.get_full_name(),
+ q.reviewer.get_full_name(), q.description, q.status, q.github,
+ q.category])
+
+ openfile.seek(0)
+ response.write(openfile.read())
+ return response
+
+ download_data.short_description = "Download data CSV file."
+
admin.site.register(Category, CategoryAdmin)
-admin.site.register(Profile, ProfileAdmin) \ No newline at end of file
+admin.site.register(Profile, ProfileAdmin)
+admin.site.register(Animation, AnimationAdmin) \ No newline at end of file
diff --git a/fossee_manim/forms.py b/fossee_manim/forms.py
index ec7568d..7543935 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,18 +253,30 @@ class AnimationProposal(forms.ModelForm):
class CommentForm(forms.ModelForm):
"""
- Instructors will post comments on Coordinators profile
"""
def __init__(self, *args, **kwargs):
super(CommentForm, self).__init__(*args, **kwargs)
self.fields['comment'].label = ""
- self.fields['comment'].widget.attrs['rows'] = 5
- self.fields['comment'].widget.attrs['cols'] = 95
class Meta:
model = Comment
- exclude = ['animation', 'created_date', 'commentor']
+ exclude = ['animation', 'created_date', 'commentor',
+ 'animation_status']
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..a3b3537 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()
@@ -169,6 +179,7 @@ class Comment(models.Model):
commentor = models.ForeignKey(User, on_delete=models.CASCADE)
animation = models.ForeignKey(Animation, on_delete=models.CASCADE)
created_date = models.DateTimeField(default=timezone.now)
+ animation_status = models.CharField(max_length=255)
def __str__(self):
return u"{1} | {0}".format(
@@ -181,4 +192,35 @@ 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):
+ 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)
+
+ def _create_ogv(self):
+ video_input = self.video_path.path
+ vid_output = path.join(
+ tempfile.mkdtemp(), "{0}.ogv".format(self.animation.title)
+ )
+ file_name = "{0}.ogv".format(self.animation.title)
+ subprocess.call(['ffmpeg', '-i', video_input, '-r', '24', vid_output])
+ if path.exists(vid_output):
+ que_file = open(vid_output, 'rb')
+ # Converting to Python file object with
+ # some Django-specific additions
+ django_file = File(que_file)
+ self.video_path.save(file_name, django_file, save=True) \ No newline at end of file
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/static/css/sticky-footer.css b/fossee_manim/static/css/sticky-footer.css
index ea445db..4bcbcc5 100644
--- a/fossee_manim/static/css/sticky-footer.css
+++ b/fossee_manim/static/css/sticky-footer.css
@@ -72,15 +72,19 @@
}
-/**
- * Footer Styles
- */
-
-.footer {
- position: fixed;
- right: 0;
- bottom: 0;
- left: 0;
- background-color: #efefef;
- text-align: center;
+/* video-thumbnail over image */
+#play-btn
+{
+ position: absolute;
+ top: 40%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ -ms-transform: translate(-50%, -50%);
+ background-color: #555;
+ color: white;
+ font-size: 16px;
+ padding: 10px 20px;
+ border: none;
+ cursor: pointer;
+ border-radius: 5px;
} \ No newline at end of file
diff --git a/fossee_manim/templates/fossee_manim/base.html b/fossee_manim/templates/fossee_manim/base.html
index c9d6242..1a4945d 100644
--- a/fossee_manim/templates/fossee_manim/base.html
+++ b/fossee_manim/templates/fossee_manim/base.html
@@ -43,10 +43,11 @@
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Categories
</a>
+
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
- <a class="dropdown-item" href="#">Math</a>
- <a class="dropdown-item" href="#">Aerospace</a>
- <a class="dropdown-item" href="#">Biology</a>
+ {% for c in categories %}
+ <a class="dropdown-item" href="{% url 'search_category' c.name %}">{{c.name}}</a>
+ {% endfor %}
</div>
</li>
</ul>
@@ -59,6 +60,7 @@
</a>
{% if request.user.profile.position == 'contributor' %}
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
+ <a class="dropdown-item" href="{% url 'how_to' %}">How To</a>
<a class="dropdown-item" href="{% url 'send_proposal' %}">Send Proposal</a>
<a class="dropdown-item" href="{% url 'proposal_status' %}">Proposal Status</a>
<a class="dropdown-item" href="{% url 'view_profile' %}">View Profile</a>
@@ -93,10 +95,5 @@
{% endblock %}
</body>
-<br><br>
- <footer class="footer">
- <div class="container">
- <p align="center">Developed by FOSSEE group, IIT Bombay</p>
- </div>
- </footer>
+<br>
</html> \ No newline at end of file
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..0084b83
--- /dev/null
+++ b/fossee_manim/templates/fossee_manim/categorical_list.html
@@ -0,0 +1,38 @@
+{% extends 'fossee_manim/base.html' %}
+
+ {% block title %}
+ FOSSEE Animation
+ {% endblock %}
+
+{% block content %}
+ <br>
+ <div class="container-fluid" >
+ <br>
+ <div class="row" align="center">
+ <div class="col-md-12">
+ <h1 style="float: left;">{{ categorial_list.0.animation.category }}</h1>
+ </div>
+ </div>
+ <hr>
+ <br>
+
+ {% for video in categorial_list %}
+ <div class="row">
+ <div class="col-md-4">
+ <a href="{% url 'video' video.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="90%" width="100%" src="{{ video.thumbnail.url }}">
+ </a>
+ </div>
+ <div class="col-md-4">
+ <p style="color:#26A669; font-size: 300%;"> {{ video.animation.title }} </p>
+ <p style="color:#26A669; font-size: 100%;"> {{ video.animation.description | truncatewords:5}} </p>
+ <a target="_blank" href="{{ video.animation.github }}"><p style="font-size: 70%;"> {{ video.animation.github }} </p></a>
+ </div>
+ </div>
+ <hr>
+ {% endfor %}
+ <br>
+ </div>
+ <br>
+{% 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..e42a358 100644
--- a/fossee_manim/templates/fossee_manim/edit_proposal.html
+++ b/fossee_manim/templates/fossee_manim/edit_proposal.html
@@ -19,7 +19,23 @@
<br>
<button class="btn btn-primary pull-right" type="submit">Save</button>
+ <br>
+ </form>
+ <br>
+
+ {% if proposal_form.instance.status == 'changes' and request.user.profile.position == 'contributor' %}
+ <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>
+ {% else %}
+ <video width="100%" height="100%" controls>
+ <source src="{{video.0.video_path.url}}" type="video/mp4">
+ </video>
+ {% endif %}
<br><br>
{% if request.user.profile.position == 'reviewer' %}
diff --git a/fossee_manim/templates/fossee_manim/how_to.html b/fossee_manim/templates/fossee_manim/how_to.html
new file mode 100644
index 0000000..830bdff
--- /dev/null
+++ b/fossee_manim/templates/fossee_manim/how_to.html
@@ -0,0 +1,21 @@
+{% extends 'fossee_manim/base.html' %}
+
+ {% block title %}
+ FOSSEE Animation
+ {% endblock %}
+
+{% block content %}
+ <div class="container-fluid">
+ <br>
+ <h1>How to contribute</h1>
+ <ul>
+ <li><a class="nav-link" href="{% url 'register' %}">Register</a></li>
+ <li><a class="nav-link" href="https://purusharthsaxena.wordpress.com/getting-started-with-manim/" target="_blank">Visit here to know about manim(python based animation library)</a></li>
+ <li>Send proposal for a topic</li>
+ <li>Wait for the reviewer to respond</li>
+ <li>Upload animation video</li>
+ <li>Once approved, video will be released</li>
+ <li>Get Honorarium</li>
+ </ul>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/fossee_manim/templates/fossee_manim/index.html b/fossee_manim/templates/fossee_manim/index.html
index 3d39b41..0753918 100644
--- a/fossee_manim/templates/fossee_manim/index.html
+++ b/fossee_manim/templates/fossee_manim/index.html
@@ -4,12 +4,11 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="Akshen Doke" content="PRE, FOSSEE-IITB">
- <meta name="title" content="Welcome to FOSSEE's Python Workshops">
+ <meta name="title" content="Welcome to FOSSEE's Animation for Education">
<meta name="description" content="The FOSSEE team at IIT Bombay conducts remote-assisted training programs in Python.
These are interactive workshop sessions with hands-on experience, live assistance, practice sessions and evaluation quizzes.
- These programs can be conducted at your institution / organisation, free of charge.
- Please note that you will require a coordinator and a minimum number of 25 participants to request for these workshops.">
- <meta name="keywords" content="learn python for free, fossee, iit bombay, python workshops, fossee python, python workshops">
+ These programs can be conducted at your institution / organisation, free of charge.">
+ <meta name="keywords" content="fossee, iit bombay, animation based learning math, manim, python based animations">
<!-- favicon -->
<link rel="shortcut icon" type="image/png" href="{{ URL_ROOT}}/static/img/fevicon_python.png"/>
@@ -37,22 +36,23 @@
<div class="container-fluid" style="height:100%; background-color: #3D5A50;">
<div class="row" id="r1" style="background-color:#ffffff">
<div class="col-md-2" id="brand"><strong>FOSSEE</strong> <br>Animation</div>
- <div class="col-md-10" style="text-align:center;" id="tag"><strong>Python based animation for math</strong></div>
+ <div class="col-md-10" style="text-align:center;" id="tag"><strong>Animation based learning</strong></div>
</div>
<div class="row" id="r2" style="background-color:#3D5A50">
<div class="col-md-8">
- <form class="example" action="" id="search_bar">
- <input type="text" placeholder="Search." name="search" id="search_tab">
+ <form class="example" id="search_bar" method="POST" action="/search/">
+ {% csrf_token %}
+ <input type="text" id="sbox" name="sbox" type="search" placeholder="Search" id="search_tab">
<button type="submit"><i class="fa fa-search"></i></button>
</form>
</div>
<div class="col-md-2" id="btns" style="text-align:center;">
- <a href="{{URL_ROOT}}/login"><strong>Login</strong></a>
+ <a href="{% url 'login' %}"><strong>Login</strong></a>
</div>
<div class="col-md-2" id="btns" style="text-align:center;">
- <a href="{{URL_ROOT}}/register"><strong>Register</strong></a>
+ <a href="{% url 'register' %}"><strong>Register</strong></a>
</div>
</div>
@@ -71,28 +71,28 @@
<div class="row" id="r4" style="background-color:ghostwhite">
<hr style="height:3px;">
<div class="col-md-3" style="text-align:center;">
- <iframe width="240" height="125"
- src="https://www.youtube.com/embed/JGLfa66Os0Q" frameborder="0" allow="accelerometer;
- encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
- </iframe>
+ <a href="{% url 'video' anime.0.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="25%" width="65%" src="{{ anime.0.thumbnail.url }}">
+ </a>
</div>
<div class="col-md-3" style="text-align:center;">
- <iframe width="240" height="125"
- src="https://www.youtube.com/embed/JGLfa66Os0Q" frameborder="0" allow="accelerometer;
- encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
- </iframe>
+ <a href="{% url 'video' anime.1.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="25%" width="65%" src="{{ anime.1.thumbnail.url }}">
+ </a>
</div>
<div class="col-md-3" style="text-align:center;">
- <iframe width="240" height="125"
- src="https://www.youtube.com/embed/JGLfa66Os0Q" frameborder="0" allow="accelerometer;
- encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
- </iframe>
+ <a href="{% url 'video' anime.2.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="25%" width="65%" src="{{ anime.2.thumbnail.url }}">
+ </a>
</div>
<div class="col-md-3" style="text-align:center;">
- <iframe width="240" height="125"
- src="https://www.youtube.com/embed/JGLfa66Os0Q" frameborder="0" allow="accelerometer;
- encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
- </iframe>
+ <a href="{% url 'video' anime.3.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="25%" width="65%" src="{{ anime.3.thumbnail.url }}">
+ </a>
</div>
</div>
diff --git a/fossee_manim/templates/fossee_manim/search_results.html b/fossee_manim/templates/fossee_manim/search_results.html
index 2e70f78..744f953 100644
--- a/fossee_manim/templates/fossee_manim/search_results.html
+++ b/fossee_manim/templates/fossee_manim/search_results.html
@@ -1,13 +1,34 @@
{% extends 'fossee_manim/base.html' %}
{% block title %}
- Login
+ Search Result
{% endblock %}
{% block content %}
- <br>
- <div class="container" align="center">
- {{ args }}
- </div>
+<br>
+<div class="container-fluid" >
+ <br>
+
+ <hr>
+ <br>
+ {% for anime in s_result %}
+ <div class="row">
+ <div class="col-md-4" >
+ <a href="{% url 'video' anime.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="90%" width="100%" src="{{ anime.thumbnail.url }}">
+ </a>
+ </div>
+ <div class="col-md-4">
+ <p style="color:#26A669; font-size: 300%;"> {{ anime.animation.title }} </p>
+ <p style="color:#26A669; font-size: 100%;"> {{ anime.animation.description | truncatewords:5}} </p>
+ <a target="_blank" href="{{ anime.animation.github }}"><p style="font-size: 70%;"> {{ anime.animation.github }} </p></a>
+ </div>
+ </div>
+ <hr>
+ {% endfor %}
+ <br>
+</div>
+<br>
{% endblock %} \ No newline at end of file
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..b94a34e
--- /dev/null
+++ b/fossee_manim/templates/fossee_manim/video.html
@@ -0,0 +1,89 @@
+{% extends 'fossee_manim/base.html' %}
+
+ {% block title %}
+ FOSSEE Animation
+ {% endblock %}
+
+{% block content %}
+ <div class="container" >
+ <div class="row" >
+ <div class="col-md-12" >
+ <br>
+ <video width="100%" height="90%" controls>
+ <source src="{{video.0.video_path.url}}" type="video/mp4">
+ </video>
+ <div class="row">
+ <div class="col-md-8">
+ <p style="color:#26A669; font-size: 200%; float: left;"> {{ video.0.animation.title }} </p>
+ </div>
+ <div class="col-md-4">
+ <a target="_blank" href="{{ video.animation.github }}"><p style="font-size: 70%; float: right;"> {{ video.0.animation.github }} </p></a>
+ </div>
+ </div>
+ <br>
+ </div>
+
+ </div>
+ <div class="row">
+ <div class="col-md-10">
+ <hr>
+ <br>
+ <p style="color:#26A669; font-size: 100%; float: left;">
+ {{ video.0.animation.description }}
+ </p>
+ <br>
+ </div>
+ </div>
+ <hr>
+ <div class="row">
+ <div class="col-md-4">
+ <a href="{% url 'video' reco.0.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="95%" width="95%" src="{{ reco.0.thumbnail.url }}">
+ </a>
+ </div>
+ <div class="col-md-4">
+ <a href="{% url 'video' reco.1.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="95%" width="95%" src="{{ reco.1.thumbnail.url }}">
+ </a>
+ </div>
+ <div class="col-md-4">
+ <a href="{% url 'video' reco.2.id %}" >
+ <span class="fa fa-play fa-4x" id="play-btn"></span>
+ <img height="95%" width="95%" src="{{ reco.2.thumbnail.url }}">
+ </a>
+ </div>
+ </div>
+ <div>
+ <br> <br>
+ <h2>Comments</h2>
+ <div>
+ <form method="POST">
+ <br>
+ {% csrf_token %}
+ {{ comment_form.as_p }}
+ <button type="submit" class="btn btn-default">Post</button>
+ </form>
+
+ </div>
+ <hr style="background-color: #fff;
+ border-top: 5px double #8c8b8b;">
+ <table>
+ {% for comment in comments %}
+ <tbody>
+ <tr>
+ <td>
+ <h5>{{ comment.commentor.profile.user.get_full_name }} | {{ comment.created_date | date }}</h5>
+ <h6 style="background-color: #ecf0f1; padding:10px;">{{ comment.comment }}</h6>
+ <hr style="border-top: 0.5px solid #8c8b8b;">
+ </td>
+ </tr>
+ </tbody>
+ {% endfor %}
+ </table>
+
+ <br>
+ </div>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/fossee_manim/tests/test_models.py b/fossee_manim/tests/test_models.py
index d7ffade..8b2162c 100644
--- a/fossee_manim/tests/test_models.py
+++ b/fossee_manim/tests/test_models.py
@@ -1,6 +1,7 @@
from django.test import TestCase
from fossee_manim.models import (
- Profile, User
+ Profile, User, Category, Animation,
+ Comment, AnimationStats
)
from datetime import datetime
@@ -22,6 +23,8 @@ def setUpModule():
testUser2 = User.objects.create(username='testuser2',
email='test.user@gmail.com', password='pass@123')
+ category1 = Category.objects.create(name='Math', description='Mathematics')
+
reviewer_profile = Profile.objects.create(user=testUser2, position='reviewer',
department='computer engineering', institute='ace', phone_number='1122334456',
title='Doctor', how_did_you_hear_about_us='Google', location='powai', state='IN-MH',
@@ -35,8 +38,10 @@ def setUpModule():
def tearDownModule():
- User.objects.all().delete()
- Profile.objects.all().delete()
+ User.objects.all().delete()
+ Profile.objects.all().delete()
+ Category.objects.all().delete()
+
class ProfileModelTest(TestCase):
'''
@@ -67,4 +72,52 @@ class ProfileModelTest(TestCase):
self.assertEqual(self.contributor_profile1.position,'contributor')
self.assertEqual(self.contributor_profile1.location,'powai')
self.assertEqual(self.reviewer_profile1.location,'powai')
- self.assertEqual(self.contributor_profile1.how_did_you_hear_about_us,'Google') \ No newline at end of file
+ self.assertEqual(self.contributor_profile1.how_did_you_hear_about_us,'Google')
+
+
+class CategoryModelTest(TestCase):
+ def setUp(self):
+ self.category1 = Category.objects.create(name='Biology', description='study of nature')
+ self.category2 = Category.objects.create(name='Aerospace',
+ description='Aerospace is the human effort in science, engineering, and business to fly in the atmosphere of Earth \
+ (aeronautics) and surrounding space (astronautics). \
+ Aerospace organizations research, design, manufacture, operate, or maintain aircraft or spacecraft. Aerospace activity \
+ is very diverse, with a multitude of commercial, industrial and military applications.'
+ )
+
+ def test_category_model(self):
+ self.assertEqual(self.category1.description, 'study of nature')
+ self.assertEqual(self.category2.name, 'Aerospace')
+
+
+class AnimationModelTest(TestCase):
+ def setUp(self):
+ self.demoUser2 = User.objects.create(username='demouser21',
+ email='test.user@gmail.com', password='pass@123')
+ self.testUser2 = User.objects.create(username='testuser21',
+ email='test.user@gmail.com', password='pass@123')
+ self.category1 = Category.objects.create(name='Biology', description='study of nature')
+ self.animation1 = Animation.objects.create(title='Testing Anime', contributor=self.demoUser2,
+ reviewer=self.testUser2, description='This is test animation upload', github='https://github.come/FOSSEE',
+ category=self.category1)
+
+ def test_animation_model(self):
+ self.assertEqual(self.animation1.title, 'Testing Anime')
+ self.assertEqual(self.category1.name, 'Biology')
+
+
+class CommentModelTest(TestCase):
+ def setUp(self):
+ self.demoUser2 = User.objects.create(username='demouser21',
+ email='test.user@gmail.com', password='pass@123')
+ self.testUser2 = User.objects.create(username='testuser21',
+ email='test.user@gmail.com', password='pass@123')
+ self.category1 = Category.objects.create(name='Biology', description='study of nature')
+ self.animation1 = Animation.objects.create(title='Testing Anime', contributor=self.demoUser2,
+ reviewer=self.testUser2, description='This is test animation upload', github='https://github.come/FOSSEE',
+ category=self.category1)
+ self.comment1 = Comment.objects.create(comment='This is a comment', commentor=self.testUser2,
+ animation=self.animation1, animation_status='changes')
+
+ def test_comment_model(self):
+ self.assertEqual(self.comment1.comment, 'This is a comment')
diff --git a/fossee_manim/tests/test_views.py b/fossee_manim/tests/test_views.py
index e69de29..3209f42 100644
--- a/fossee_manim/tests/test_views.py
+++ b/fossee_manim/tests/test_views.py
@@ -0,0 +1,94 @@
+from django.test import TestCase
+from fossee_manim.models import (
+ Profile, User, Category, Animation,
+ Comment, AnimationStats, has_profile
+ )
+from datetime import datetime
+from django.test import Client
+from django.contrib.auth.models import Group, Permission
+from django.contrib.auth import authenticate
+from django.core.urlresolvers import reverse
+from fossee_manim.views import view_profile, user_login, edit_profile
+
+class TestProfile(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.user1 = User.objects.create(
+ username='demo_test_user1',
+ password='pass@123',
+ email='test.user@gmail.com')
+
+ self.user2 = User.objects.create(
+ username='demo_test_user2',
+ email='test.user@gmail.com')
+
+ self.user2.set_password('pass@123')
+ self.user2.save()
+
+ self.user2_profile = Profile.objects.create(
+ user=self.user2,
+ department='Computer Engineering',
+ institute='ace',
+ title='Doctor',
+ position='instructor',
+ phone_number='1122993388',
+ location='mumbai',
+ how_did_you_hear_about_us='Google',
+ state='IN-MH',
+ is_email_verified=1
+ )
+
+ def test_has_profile_for_user_without_profile(self):
+ """
+ If no profile exists for user passed as argument return False
+ """
+ has_profile_status = has_profile(self.user1)
+ self.assertFalse(has_profile_status)
+
+ def test_has_profile_for_user_with_profile(self):
+ """
+ If profile exists for user passed as argument return True
+ """
+ has_profile_status = has_profile(self.user2)
+ self.assertTrue(has_profile_status)
+
+ def test_view_profile_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse(view_profile), follow=True)
+ redirect_destination = '/login/?next=/view_profile/'
+ self.assertTrue(response.status_code,200)
+ self.assertRedirects(response, redirect_destination)
+
+ def test_edit_profile_get(self):
+ """
+ GET request to edit profile should display profile form
+ """
+
+ self.client.login(username=self.user2, password='pass@123')
+ response = self.client.get(reverse(edit_profile))
+ user_profile = User.objects.get(id=self.user2.id)
+ profile = Profile.objects.get(user=user_profile)
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(profile.institute, 'ace')
+ self.client.logout()
+
+ def test_edit_profile_post(self):
+
+ self.client.login(username=self.user2, password='pass@123')
+ response = self.client.post('/edit_profile/',
+ {
+ 'first_name': 'demo_test',
+ 'last_name': 'user2',
+ 'institute': 'IIT',
+ 'department': 'aerospace engineering'
+ })
+
+ updated_profile_user = User.objects.get(id=self.user2.id)
+ updated_profile = Profile.objects.get(user=updated_profile_user)
+ self.assertEqual(updated_profile.institute, 'IIT')
+ self.assertEqual(updated_profile.department, 'aerospace engineering')
+ self.assertEqual(updated_profile.position, 'instructor')
+ self.assertEqual(response.status_code, 200)
diff --git a/fossee_manim/urls.py b/fossee_manim/urls.py
index 7bc7740..6181b67 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,19 @@ 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'^how_to/$', views.how_to, name='how_to'),
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..44f20c1 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 django.core.files.uploadhandler import FileUploadHandler
+from django.db.models import F, Subquery, OuterRef, Q
from zipfile import ZipFile
-from django.contrib import messages
-from django.db.models import Q
+from textwrap import dedent
+from requests import get
+from random import sample
+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,21 +81,24 @@ 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})
+ anime = AnimationStats.objects.filter(animation__status='released').order_by('-id')[:5]
+ return render(request, "fossee_manim/index.html", {"form": form,
+ "anime" : anime
+ })
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):
'''User Login'''
user = request.user
+ categories = Category.objects.all()
if is_superuser(user):
return redirect('/admin')
if user.is_authenticated():
@@ -91,12 +113,13 @@ def user_login(request):
login(request, user)
if user.groups.filter(name='reviewer').count() > 0:
return redirect('/view_profile/')
- return redirect('/view_profile/')
+ return redirect('/how_to/')
else:
return render(request, 'fossee_manim/login.html', {"form": form})
else:
form = UserLoginForm()
- return render(request, 'fossee_manim/login.html', {"form": form})
+ return render(request, 'fossee_manim/login.html', {"form": form,
+ 'categories': categories })
def user_logout(request):
@@ -178,10 +201,12 @@ def user_register(request):
def view_profile(request):
""" view instructor and coordinator profile """
user = request.user
+ categories = Category.objects.all()
if is_superuser(user):
return redirect('/admin')
if is_email_checked(user) and user.is_authenticated():
- return render(request, "fossee_manim/view_profile.html")
+ return render(request, "fossee_manim/view_profile.html",
+ {'categories': categories})
else:
if user.is_authenticated():
return render(request, 'fossee_manim/activation.html')
@@ -198,6 +223,7 @@ def edit_profile(request):
""" edit profile details facility for reviewer and contributor """
user = request.user
+ categories = Category.objects.all()
if is_superuser(user):
return redirect('/admin')
if is_email_checked(user):
@@ -229,38 +255,42 @@ def edit_profile(request):
form_data.save()
return render(
- request, 'fossee_manim/profile_updated.html'
+ request, 'fossee_manim/profile_updated.html',
+ {'categories': categories}
)
else:
context['form'] = form
return render(request, 'fossee_manim/edit_profile.html', context)
else:
form = ProfileForm(user=user, instance=profile)
- return render(request, 'fossee_manim/edit_profile.html', {'form': form}
+ return render(request, 'fossee_manim/edit_profile.html', {'form': form,
+ 'categories': categories}
)
@login_required
def send_proposal(request):
user = request.user
+ categories = Category.objects.all()
if request.method == 'POST':
form = AnimationProposal(request.POST)
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, 'categories': categories})
return redirect('/proposal_status/')
else:
form = AnimationProposal()
return render(request, 'fossee_manim/send_proposal.html',
- {'form': form})
+ {'form': form, 'categories': categories})
@login_required
@@ -269,13 +299,14 @@ def proposal_status(request):
profile = Profile.objects.get(user_id=user)
anime = {}
anime_list = {}
+ categories = Category.objects.all()
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})
+ {'anime': anime, 'anime_list': anime_list,
+ 'categories': categories})
@login_required
@@ -284,28 +315,32 @@ 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()
+ categories = Category.objects.all()
+ video = AnimationStats.objects.filter(animation=proposal_id)
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:
@@ -313,11 +348,13 @@ def edit_proposal(request, proposal_id=None):
form_data = comment_form.save(commit=False)
form_data.commentor = user
form_data.animation = proposal
+ form_data.animation_status = proposal.status
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 +382,106 @@ 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,
+ 'video': video,
+ 'categories': categories})
def search(request):
+ categories = Category.objects.all()
if request.method == 'POST':
word = request.POST.get('sbox')
+ anime_list = AnimationStats.objects.filter(
+ Q(animation__title__contains=word) | Q(animation__description__contains=word)
+ | Q(animation__category__name__contains=word), animation__status='released')
- return render(request, 'fossee_manim/search_results.html')
+ return render(request, 'fossee_manim/search_results.html',
+ {'s_result': anime_list, 'categories': categories})
+
+
+@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, aid=None):
+ user = request.user
+ video = AnimationStats.objects.filter(id=aid, animation__status="released")
+ if len(video):
+ comment_form = CommentForm()
+ # if views crosses limit comment the line below
+ video.update(views=F('views')+1)
+ video.update(like=F('like')+1)
+ anim_list = AnimationStats.objects.filter(animation__status="released")
+ suggestion_list = [x for x in anim_list if (
+ x.animation.category == video[0].animation.category)]
+ reviewer_id = video[0].animation.reviewer.id
+ comment_list = Comment.objects.filter(animation=video[0].animation)
+ comments = [x for x in comment_list if x.animation.status !=
+ ('pending' or 'changes')]
+ if request.method == 'POST':
+ if is_email_checked(user):
+ comment_form = CommentForm(request.POST)
+ form_data = comment_form.save(commit=False)
+ form_data.commentor = user
+ form_data.animation = video[0].animation
+ form_data.animation_status = video[0].animation.status
+ form_data.save()
+ return redirect('/video/{}'.format(aid))
+ else:
+ return redirect('/login/')
+ else:
+ return redirect('/view_profile/')
+
+ if len(suggestion_list)>3:
+ suggestion_list = sample(suggestion_list, 3)
+ else:
+ suggestion_list = [x for x in anim_list if x.id != int(aid)][:3]
+ categories = Category.objects.all()
+ return render(request, 'fossee_manim/video.html',
+ {'video': video, 'categories': categories,
+ 'reco': suggestion_list,
+ "comment_form": comment_form,
+ 'comments': comments})
+
+
+def search_category(request, cat=None):
+ cat_id = Category.objects.get(name=cat)
+ anim_list = AnimationStats.objects.filter(animation__status="released")
+ cat_video_list = [x for x in anim_list if (x.animation.category == cat_id)]
+ categories = Category.objects.all()
+ return render(request, 'fossee_manim/categorical_list.html',
+ {'categorial_list': cat_video_list, 'categories': categories
+ })
+
+
+def how_to(request):
+ return render(request, 'fossee_manim/how_to.html') \ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 85b47d2..27e309b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,10 @@
+certifi==2018.11.29
+chardet==3.0.4
Django==1.11
django-simple-history==2.7.0
django-taggit==0.23.0
+idna==2.8
+Pillow==5.4.1
pytz==2018.9
+requests==2.21.0
+urllib3==1.24.1