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

Add template renderer #66

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
43371f9
Add template renderer
nirizr Sep 3, 2016
6b0d19e
Add a basic template and include registration urls
nirizr Nov 7, 2016
1ac4d20
Add accounts/profile template
nirizr Dec 22, 2016
a11ba74
Add additional js scripts
nirizr Dec 22, 2016
fe59ef5
Use Font-Awesome from CDN instead of local copy
nirizr Dec 22, 2016
3e3c290
Move sidebar from base.html to sidebar.html
nirizr Dec 22, 2016
3ee0be1
Remove execute bit from js, css and html files
nirizr Dec 22, 2016
5029cb5
Move topbar from base.html to topbar.html
nirizr Dec 22, 2016
6007c5a
Adjust spaces
nirizr Dec 22, 2016
59b3114
Fix footer size by adding an nbsp
nirizr Dec 22, 2016
e5160cd
dos2unix template files
nirizr Jan 2, 2017
8e2d9e2
Make sidebar navigation menu dynamically generated
nirizr Jan 11, 2017
59f721a
Replace menus with relevant ones
nirizr Jan 11, 2017
42e48fc
Add app wide action template lookups (collab/list.html)
nirizr Jan 11, 2017
0297163
Inherit ViewSetTemplateMixin in TaskViewSet
nirizr Jan 13, 2017
8404a99
Add index page and final touches to navigation urls handling
nirizr Feb 4, 2017
f1c44aa
force remote scripts javascript and crossorigin=anonymous
nirizr Feb 4, 2017
5715473
Fix template rendering for lists
nirizr Feb 5, 2017
ee556fa
Remove TaskEditSerializer and fix TaskViewset template
nirizr Feb 7, 2017
124ce5f
Add list table template
nirizr Feb 9, 2017
f841ff4
Add templatetafs.py and user the title filter for list titles
nirizr Feb 11, 2017
b3dffb2
Fix line to long error
nirizr Feb 11, 2017
5310188
WIP: a minor restructure of template code
nirizr Feb 20, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion idaplugin/rematch/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def get_headers(token, json):

headers = {}
if json:
headers['Accept'] = 'application/json, text/html, */*'
headers['Accept'] = 'application/json; indent=2, application/json, */*'
headers['Content-Type'] = 'application/json'
if token is None and 'token' in config['login']:
token = config['login']['token']
Expand Down
9 changes: 9 additions & 0 deletions server/accounts/templates/profile.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% extends "base.html" %}

{% block title %}
Welcome, {{ username }}!
{% endblock %}

{% block content %}
This is your personal space!
{% endblock %}
2 changes: 2 additions & 0 deletions server/accounts/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
urlpatterns = [
url(r'^profile/$', views.profile, name='profile'),
url(r'', include('rest_auth.urls')),
url(r'', include('registration.backends.default.urls')),
# url('^/', include('django.contrib.auth.urls')),
]
2 changes: 1 addition & 1 deletion server/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ def profile(request):
"last_name": request.user.last_name,
"email": request.user.email,
})
return Response(user)
return Response(user, template_name='profile.html')
9 changes: 0 additions & 9 deletions server/collab/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,6 @@ class Meta:
'progress_max')


class TaskEditSerializer(TaskSerializer):
target_project = serializers.ReadOnlyField()
target_file = serializers.ReadOnlyField()
source_file = serializers.ReadOnlyField()
source_file_version = serializers.ReadOnlyField()
source_start = serializers.ReadOnlyField()
source_end = serializers.ReadOnlyField()


class SimpleInstanceSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField()

Expand Down
34 changes: 18 additions & 16 deletions server/collab/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
Match, Annotation)
from collab.serializers import (ProjectSerializer, FileSerializer,
FileVersionSerializer, TaskSerializer,
TaskEditSerializer, InstanceVectorSerializer,
VectorSerializer, MatchSerializer,
SimpleInstanceSerializer, AnnotationSerializer)
InstanceVectorSerializer, VectorSerializer,
SimpleInstanceSerializer, MatchSerializer,
AnnotationSerializer)
from collab.permissions import IsOwnerOrReadOnly
from collab import tasks
from rematch.template import ViewSetTemplateMixin


class ViewSetOwnerMixin(object):
Expand All @@ -30,19 +31,24 @@ def get_serializer(self, *args, **kwargs):
return super(ViewSetManyAllowedMixin, self).get_serializer(*args, **kwargs)


class ProjectViewSet(ViewSetOwnerMixin, viewsets.ModelViewSet):
class ProjectViewSet(ViewSetOwnerMixin, ViewSetTemplateMixin,
viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
filter_fields = ('created', 'owner', 'name', 'description', 'private')
template_fields = ('name', 'description', 'private', 'created', 'owner')


class FileViewSet(ViewSetOwnerMixin, viewsets.ModelViewSet):
class FileViewSet(ViewSetOwnerMixin, ViewSetTemplateMixin,
viewsets.ModelViewSet):
queryset = File.objects.all()
serializer_class = FileSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
filter_fields = ('created', 'owner', 'project', 'name', 'description',
'md5hash')
template_fields = ('name', 'md5hash', 'description', 'project', 'created',
'owner', 'file')

@decorators.detail_route(url_path="file_version/(?P<md5hash>[0-9A-Fa-f]+)",
methods=['GET', 'POST'])
Expand Down Expand Up @@ -72,10 +78,11 @@ class FileVersionViewSet(viewsets.ModelViewSet):
filter_fields = ('id', 'file', 'md5hash')


class TaskViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin,
mixins.DestroyModelMixin, mixins.ListModelMixin,
viewsets.GenericViewSet):
class TaskViewSet(ViewSetTemplateMixin, mixins.CreateModelMixin,
mixins.RetrieveModelMixin, mixins.DestroyModelMixin,
mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = Task.objects.all()
serializer_class = TaskSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly)
filter_fields = ('task_id', 'created', 'finished', 'owner', 'status')
Expand All @@ -84,12 +91,6 @@ def perform_create(self, serializer):
task = serializer.save(owner=self.request.user)
tasks.match.delay(task_id=task.id)

def get_serializer_class(self):
serializer_class = TaskSerializer
if self.request.method in ('PATCH', 'PUT'):
serializer_class = TaskEditSerializer
return serializer_class

@decorators.detail_route(url_path="locals")
def locals(self, request, pk):
del request
Expand Down Expand Up @@ -156,13 +157,14 @@ class MatchViewSet(viewsets.ReadOnlyModelViewSet):


class InstanceViewSet(ViewSetManyAllowedMixin, ViewSetOwnerMixin,
viewsets.ModelViewSet):
ViewSetTemplateMixin, viewsets.ModelViewSet):
queryset = Instance.objects.all()
serializer_class = InstanceVectorSerializer
filter_fields = ('owner', 'file_version', 'type')


class VectorViewSet(ViewSetManyAllowedMixin, viewsets.ModelViewSet):
class VectorViewSet(ViewSetManyAllowedMixin, ViewSetTemplateMixin,
viewsets.ModelViewSet):
queryset = Vector.objects.all()
serializer_class = VectorSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
Expand Down
45 changes: 45 additions & 0 deletions server/rematch/navigation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Menu:
active_url = None

def __init__(self, name, url=None, icon=None, *submenu):
if self.active_url is None:
raise RuntimeError("Active url is not set when menu item is created")

self.name = name
self.icon = icon if icon else ''
self.url = url
self.submenu = submenu
self.active = (url == self.active_url or
any(sm.active for sm in self.submenu))
print(self.name, self.url)

@classmethod
def set_url(cls, url):
cls.active_url = '' if url is None else url

@property
def menu_class(self):
return 'sub-menu' if self.submenu else 'mf'


def navigation(request):
Menu.set_url(request.resolver_match.url_name)

menu = [Menu("Dashboard", 'index', icon='fa-dashboard'),

Menu("Collaboration", None, 'fa-cogs',
Menu("Projects", url='project-list'),
Menu("Files", url='file-list'),
Menu("Tasks", url='task-list'),
Menu("Instances", url='instance-list'))]

if request.user.is_authenticated():
account = Menu("Account", None, 'fa-desktop',
Menu("Your profile", url='profile'),
# Menu("Settings", url='settings'),
Menu("Logout", url='auth_logout'))
else:
account = Menu("Login", 'auth_login')
menu.append(account)

return {'navigation': menu}
20 changes: 17 additions & 3 deletions server/rematch/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True


# As of django 1.10, allowed hosts are validated in debug as well,
# this disables that and makes sure all hosts are acceptible when
# running in debug mode. for more details see
Expand All @@ -47,6 +46,7 @@
'rest_framework.authtoken',
'rest_auth',
'djcelery',
'registration',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand All @@ -72,15 +72,19 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [
os.path.join(BASE_DIR, 'template')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'rematch.navigation.navigation',
],
'builtins': ['templatetags'],
},
},
]
Expand All @@ -100,7 +104,13 @@
'django_filters.rest_framework.DjangoFilterBackend',
),

'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',

'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.TemplateHTMLRenderer',
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
)
}

REST_SESSION_LOGIN = False
Expand Down Expand Up @@ -162,10 +172,14 @@

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, "template/static")]

# Celery configuration

CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

# Django Registration Redux configuration
ACCOUNT_ACTIVATION_DAYS = 1
18 changes: 18 additions & 0 deletions server/rematch/template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os


class ViewSetTemplateMixin(object):
def get_app_name(self):
return self.__class__.__module__.lower().replace('.views', '')

def get_model_name(self):
return self.__class__.__name__.lower().replace('viewset', '')

def get_template_names(self):
page = "{}.html".format(self.action)
model_template_name = os.path.join(self.get_model_name(), page)
app_template_name = os.path.join(self.get_app_name(), page)
return [model_template_name, app_template_name, page]

def get_template_fields(self):
return self.template_fields
2 changes: 2 additions & 0 deletions server/rematch/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
"""
from django.conf.urls import url, include
from django.contrib import admin
from django.views.generic import TemplateView

urlpatterns = [
url(r'^$', TemplateView.as_view(template_name="index.html"), name='index'),
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls')),
url(r'^collab/', include('collab.urls')),
Expand Down
83 changes: 83 additions & 0 deletions server/template/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<meta name="keyword" content="">

<title>Rematch</title>

<!-- Bootstrap core CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Font Awesome core CSS -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

<!-- Custom styles -->
<link href="{% static "css/style.css" %}" rel="stylesheet">
<link href="{% static "css/style-responsive.css" %}" rel="stylesheet">

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>

<body>
<section id="container" >
<!--header start-->
{% include 'topbar.html' %}
<!--header end-->

<!--sidebar start-->
{% include 'sidebar.html' %}
<!--sidebar end-->

<!--main content start-->
<section id="main-content">
<section class="wrapper site-min-height">
<div class="col-lg-12">
<div class="row mt">
<div class="showback">
<h3><i class="fa fa-angle-right"></i> {% block title %}{% endblock %}</h3>
<div class="row mt">
<div class="col-lg-12">
<p>{% block content %}{% endblock %}</p>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
<!--main content end-->

<!--footer start-->
<footer class="site-footer">
<div class="text-center">
&nbsp;
<a href="#" class="go-top">
<i class="fa fa-angle-up"></i>
</a>
</div>
</footer>
<!--footer end-->
</section>

<!-- js placed at the end of the document so the pages load faster -->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<script src="{% static "js/jquery.ui.touch-punch.min.js" %}"></script>
<script class="include" type="text/javascript" src="{% static "js/jquery.dcjqaccordion.2.7.js" %}"></script>
<script src="{% static "js/jquery.scrollTo.min.js" %}"></script>
<script src="{% static "js/jquery.nicescroll.js" %}" type="text/javascript"></script>

<!--common script for all pages-->
<script src="{% static "js/common-scripts.js" %}"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions server/template/components/list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<table class="table table-striped table-advance table-hover">
<thead>
<tr>
{% for header in headers %}
<th>{{ header|title }}</th>
{% endfor %}
<th></th>
</tr>
</thead>
<tbody>
{% for item in items %}
{{ item }}
<tr>
{% for header in headers %}
<td>{{ item|lookup:header }}</td>
{% endfor %}
<td>
<button class="btn btn-success btn-xs"><i class="fa fa-check"></i></button>
<button class="btn btn-primary btn-xs"><i class="fa fa-pencil"></i></button>
<button class="btn btn-danger btn-xs"><i class="fa fa-trash-o"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
9 changes: 9 additions & 0 deletions server/template/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% extends "base.html" %}

{% block title %}
Index
{% endblock %}

{% block content %}
This is the index page!
{% endblock %}
Loading