Commit 6952a98f authored by Mathieu Rodic's avatar Mathieu Rodic

[FEAT] implemented database with SQLAlchemy

[FEAT] url '/projects/' is available
parent da22c30c
*.pyc
*/__pycache__/*
VENV/*
from .nodes import *
from .users import *
from django.contrib.auth import models
from gargantext.util.db import *
__all__ = ['User']
class User(Base):
# Do not change!
# The properties below are a reflection of Django's auth module's models.
__tablename__ = 'auth_user'
id = Column(Integer, primary_key=True)
password = Column(String(128))
last_login = DateTime(timezone=False)
is_superuser = Column(Boolean(), default=False)
username = Column(String(30))
first_name = Column(String(30))
last_name = Column(String(30))
email = Column(String(75))
is_staff = Column(Boolean())
is_active = Column(Boolean())
date_joined = DateTime(timezone=False)
def get_contacts(self, session=None):
"""get all contacts in relation with the user"""
if session is None:
session = Session()
Friend = aliased(User)
query = (session
.query(Friend)
.join(Contact, Contact.user2_id == Friend.id)
.filter(Contact.user1_id == self.id)
)
return query.all()
def get_nodes(self, session=None, nodetype=None):
"""get all nodes belonging to the user"""
from .nodes import Node
if session is None:
session = Session()
query = (session
.query(Node)
.filter(Node.user_id == self.id)
.order_by(Node.date)
)
if nodetype is not None:
query = query.filter(Node.type_id == nodetype.id)
return query.all()
def owns(user, node):
"""check if a given node is owned by the user"""
return True
class Contact(Base):
__tablename__ = 'contacts'
id = Column(Integer, primary_key=True)
user1_id = Column(Integer, primary_key=True)
user2_id = Column(Integer, primary_key=True)
is_blocked = Column(Boolean())
date_creation = DateTime(timezone=False)
__table_args__ = (UniqueConstraint('user1_id', 'user2_id'), )
from django.template.loader import get_template
from django.template import Context, RequestContext
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.shortcuts import render_to_response,redirect
from django.shortcuts import render, redirect
from urllib.parse import quote_plus as urlencode
......@@ -9,6 +9,9 @@ from gargantext import settings
def requires_auth(func):
"""Provides a decorator to force authentication on a given view.
Also passes the URL to redirect towards as a GET parameter.
"""
def _requires_auth(request, *args, **kwargs):
if not request.user.is_authenticated():
url = '/auth/login/?next=%s' % urlencode(request.path)
......
......@@ -26,7 +26,7 @@ def bootstrap(request):
css['form'] = '#093558'
css['help'] = '#093558'
css_data = template.render(Context({
css_data = template.render({
'css': css,
}))
})
return HttpResponse(css_data, content_type="text/css")
......@@ -10,7 +10,7 @@ def logo(request):
else:
# color of the css adapted to the logo
color = '#AE5C5C'
svg_data = template.render(Context({\
'color': color,\
}))
svg_data = template.render({
'color': color,
})
return HttpResponse(svg_data, content_type='image/svg+xml')
......@@ -9,7 +9,7 @@ def home(request):
A video draws the narratives.
If not logged a project test is shown.
'''
t = get_template('pages/main/home.html')
template = get_template('pages/main/home.html')
user = request.user
date = datetime.datetime.now()
html = t.render(Context({
......
from gargantext.util.http import *
from gargantext.util.db import *
from gargantext.util.db_cache import cache
from gargantext.models import *
from datetime import datetime
@requires_auth
def overview(request):
'''This view show all projects for a given user.
Each project is described with hyperdata that are updateded on each following view.
To each project, we can link a resource that can be an image.
'''
session = Session()
user = cache.User[request.user.username]
project_type = cache.NodeType['Project']
# If POST method, creates a new project...
if request.method == 'POST':
name = str(request.POST['name'])
if name != '':
new_project = Node(
name = name,
type_id = project_type.id,
user_id = user.id,
)
session.add(new_project)
session.commit()
# list of projects created by the logged user
user_projects = user.get_nodes(session=session, nodetype=project_type)
# list of contacts of the logged user
contacts = user.get_contacts(session=session)
contacts_projects = []
for contact in contacts:
contact_projects = (session
.query(Node)
.filter(Node.user_id == contact.id)
.filter(Node.type_id == project_type.id)
.order_by(Node.date)
).all()
contacts_projects += contact_projects
# render page
return render(
template_name = 'pages/projects/overview.html',
request = request,
context = {
'debug': settings.DEBUG,
'date': datetime.now(),
# projects owned by the user
'number': len(user_projects),
'projects': user_projects,
# projects owned by the user's contacts
'common_users': contacts if len(contacts) else False,
'common_projects': contacts_projects if len(contacts_projects) else False,
},
)
from django.conf.urls import url
from . import main, auth
from . import main, auth, projects
urlpatterns = [
# presentation pages
url(r'^$', main.home),
url(r'^about/?$', main.about),
......@@ -12,4 +13,8 @@ urlpatterns = [
# authentication
url(r'^auth/login/?$', auth.login),
url(r'^auth/logout/?$', auth.logout),
# overview on projects
url(r'^projects/?$', projects.overview),
]
Django==1.9.2
Django==1.6.11
RandomWords==0.1.12
django-pgfields==1.4.4
django-pgjsonb==0.0.16
psycopg2==2.6.1
pytz==2015.7
six==1.10.0
ujson==1.35
{% extends "pages/menu.html" %}
{% block css %}
{% load staticfiles %}
<link rel="stylesheet" href="{% static "css/bootstrap.css" %}">
<script src="{% static "js/jquery/jquery.min.js" %}" type="text/javascript"></script>
{% endblock %}
{% block content %}
<div class="container theme-showcase" role="main">
<div class="jumbotron">
<h1>My {{number}} projects</h1>
<p>Template showing my working space</p>
<p>
<button
type="button"
class="btn btn-primary btn-lg"
data-container="body"
data-toggle="popover"
data-placement="bottom"
>Add a project</button>
<div id="popover-content" class="hide">
<form enctype='multipart/form-data' action='/projects/' method='post'>
{% csrf_token %}
<p>
<label for="id_name">Name:</label>
<input id="id_name" maxlength="255" name="name" type="text" />
</p>
<input type='submit' class="btn" value='Add this project !'/>
</form>
</div>
</p>
</div>
</div>
<div class="container">
<div class="row">
{% if projects %}
{% for project in projects %}
<!--<div class="col-md-offset-7 col-md-4 content" style="background-color:grey">!-->
<div class="col-md-3 content">
<h3><a href="/project/{{ project.id }}">{{ project.name }}</a>
<button type="button" class="btn btn-xs btn-default" data-container="body" data-toggle="popover" data-placement="bottom"
data-content='
<ul>
<li> Rename </li>
<li><a href="/project/{{ project.id }}">Add new corpus</a></li>
<li><a href="/delete/{{ project.id }}">Delete</a></li>
</ul>
'>Manage</button>
{% if common_users %}
<a style="cursor:pointer;"><img class="share_button" data-id="{{ project.id }}" title="Share it!" width="20px" src="{% static "img/share.png" %}"></img></a>
{% endif %}
</h3>
<h4>{{ project.subtitle }}<h4>
</div>
{% endfor %}
{% endif %}
{% if common_projects %}
<br><br><br><br><br><br>
<h3><i> - - Shared projects - -</i></h3>
{% for project in common_projects %}
<!--<div class="col-md-offset-7 col-md-4 content" style="background-color:grey">!-->
<div class="col-md-3 content">
<h3><a href="/project/{{ project.id }}">{{ project.name }}</a>
<button type="button" class="btn btn-xs btn-default" data-container="body" data-toggle="popover" data-placement="bottom"
data-content='
<ul>
<li> Rename </li>
<li><a href="/project/{{ project.id }}">Add new corpus</a></li>
<li><a href="/delete/{{ project.id }}">Delete</a></li>
</ul>
'>Manage</button>
</h3>
<h4>{{ project.subtitle }}<h4>
</div>
{% endfor %}
{% endif %}
</div>
</div>
<div id="sharemodal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title">Share this Corpus with your Groups</h3>
</div>
<div class="modal-body form-horizontal">
<h4>List of available groups:</h4>
<div id="groups_list">here show the groups</div>
<div class="modal-footer">
<button id="closesharemodal" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="send_share" type="button" class="btn btn-primary" >Share<span id="simpleloader"></span></button>
</div>
</div>
</div>
</div>
</div>
<style>
label {
padding:10px;
margin:0 0 10px;
display:block;
}
label:hover {
background:#eee;
cursor:pointer;
}
</style>
<script>
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var last_project = -1
function get_groups() {
console.log( "IN get_groups()!" )
var url_ = "/get_groups"
$.ajax({
type: "GET",
url: url_,
dataType: "json",
success : function(data, textStatus, jqXHR) {
var _content = ""
for(var i in data) {
var g_id = data[i][0] , g_name=data[i][1]
_content += '<label><input name="groups" data-id="'+g_id+'" type="checkbox" />&nbsp;'+g_name+'</label>'
}
$("#groups_list").html( _content )
},
error: function(exception) {
console.log("exception!:"+exception.status)
}
});
}
if( $(".share_button").length>0 ) {
$(".share_button").click(function(){
last_project = $(this).data("id")
get_groups()
$("#sharemodal").modal("show");
});
$("#send_share").click(function() {
$('input[name=groups]:checked').each(function () {
$("#send_share").attr("disabled","disabled")
console.log( $(this).data("id") );
$("#simpleloader").html('<img width="30px" src="{% static "js/libs/img2/loading-bar.gif" %}"></img>')
$.ajax({
url: "/api/share/"+last_project+"/"+$(this).data("id"),
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function(data) {
console.log("SUCCESS!")
window.location.reload();
},
error: function(result) {
console.log("FAIL!")
console.log(result)
}
});
});
});
}
</script>
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment