Commit 90dd952b authored by Mathieu Rodic's avatar Mathieu Rodic

[FEAT] started working on the `/projects/(\d+)` page

[CODE] more cleaning (espacially in the views)
parent 0f8fc1ea
......@@ -34,6 +34,7 @@ class User(Base):
def get_nodes(self, nodetype=None):
"""get all nodes belonging to the user"""
# ↓ this below is a workaround because of Python's lame import system
from .nodes import Node
query = (session
.query(Node)
......@@ -54,7 +55,7 @@ class Contact(Base):
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)
is_blocked = Column(Boolean(), default=False)
date_creation = Column(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, redirect
......
......@@ -4,45 +4,40 @@ from django.contrib import auth
def login(request):
logout(request)
username = password = ''
next_page = ""
if request.method == "GET":
"""Performs user login
"""
auth.logout(request)
# if the user wants to access the login form
if request.method == 'GET':
additional_context = {}
# if for exemple: auth/?next=/project/5/corpus/554/document/556/
# => we'll forward ?next="..." into template with form
if ('next' in request.GET):
if 'next' in request.GET:
additional_context = {'next_page':request.GET['next']}
return render_to_response('pages/auth/login.html',
additional_context,
context_instance=RequestContext(request)
)
return render(
template_name = 'pages/auth/login.html',
request = request,
context = additional_context,
)
# if the user send her authentication data to the page
elif request.method == "POST":
username = request.POST['username']
# /!\ pass is sent clear in POST data
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
if user.is_active:
auth.login(request, user)
# if "next" forwarded from the GET via the template form
if ('the_next_page' in request.POST):
return HttpResponseRedirect(request.POST['the_next_page'])
else:
return HttpResponseRedirect('/projects/')
# /!\ pass is sent clear in POST data: use SSL
user = auth.authenticate(
username = request.POST['username'],
password = request.POST['password']
)
if user is not None and user.is_active:
auth.login(request, user)
# if "next" forwarded from the GET via the template form
if 'the_next_page' in request.POST:
return redirect(request.POST['the_next_page'])
else:
return redirect('/projects/')
def logout(request):
'''Logout the user, and redirect to main page
'''
"""Logout the user, and redirect to main page
"""
auth.logout(request)
return HttpResponseRedirect('/')
return redirect('/')
......@@ -9,49 +9,45 @@ def home(request):
A video draws the narratives.
If not logged a project test is shown.
'''
template = get_template('pages/main/home.html')
user = request.user
date = datetime.datetime.now()
html = t.render(Context({
'debug': settings.DEBUG,
'user': user,
'date': date,
'paragraph_gargantua': paragraphs.gargantua(),
'paragraph_lorem' : paragraphs.lorem(),
'paragraph_tutoreil': paragraphs.tutoreil(),
}))
return HttpResponse(html)
return render(
template_name = 'pages/main/home.html',
request = request,
context = {
'debug': settings.DEBUG,
'user': request.user,
'date': datetime.datetime.now(),
'paragraph_gargantua': paragraphs.gargantua(),
'paragraph_lorem' : paragraphs.lorem(),
'paragraph_tutoreil': paragraphs.tutoreil(),
},
)
def about(request):
'''About Gargantext, its team and sponsors
'''
template = get_template('pages/main/about.html')
user = request.user
date = datetime.datetime.now()
html = template.render(Context({
'user': user,
'date': date,
'team': credits.members(),
'institutions': credits.institutions(),
'labos': credits.labs(),
'grants': credits.grants(),
}))
return HttpResponse(html)
return render(
template_name = 'pages/main/about.html',
request = request,
context = {
'user': request.user,
'date': datetime.datetime.now(),
'team': credits.members(),
'institutions': credits.institutions(),
'labos': credits.labs(),
'grants': credits.grants(),
},
)
def maintenance(request):
'''Gargantext out of service
'''
template = get_template('pages/main/maintenance.html')
user = request.user
date = datetime.datetime.now()
html = template.render(Context({\
'user': user,\
'date': date,\
}))
return HttpResponse(html)
return render(
template_name = 'pages/main/maintenance.html',
request = request,
context = {
'user': request.user,
'date': datetime.datetime.now(),
},
)
......@@ -58,3 +58,21 @@ def overview(request):
'common_projects': contacts_projects if len(contacts_projects) else False,
},
)
@requires_auth
def project(request, project_id):
return render(
template_name = 'pages/projects/project.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,
},
)
......@@ -16,5 +16,6 @@ urlpatterns = [
# overview on projects
url(r'^projects/?$', projects.overview),
url(r'^projects/(\d+)/?$', projects.project),
]
......@@ -27,10 +27,10 @@
<li><a href="/projects/" title="All your projects are here.">Projects</a></li>
{% endif %}
{% if project %}
<li><a href="/project/{{project.id}}">{{project.name}}</a></li>
<li><a href="/projects/{{project.id}}">{{project.name}}</a></li>
{% endif %}
{% if corpus %}
<li><a href="/project/{{project.id}}/corpus/{{corpus.id}}">{{corpus.name}}</a></li>
<li><a href="/projects/{{project.id}}/corpora/{{corpus.id}}">{{corpus.name}}</a></li>
{% endif %}
</ul>
......
......@@ -46,13 +46,13 @@
{% 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>
<h3><a href="/projects/{{ 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="/projects/{{ project.id }}">Add new corpus</a></li>
<li><a href="/delete/{{ project.id }}">Delete</a></li>
</ul>
'>Manage</button>
......@@ -73,12 +73,12 @@
{% 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>
<h3><a href="/projects/{{ 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="/projects/{{ project.id }}">Add new corpus</a></li>
<li><a href="/delete/{{ project.id }}">Delete</a></li>
</ul>
'>Manage</button>
......
{% extends "pages/menu.html" %}
{% block css %}
{% load staticfiles %}
<link rel="stylesheet" href="{% static "css/bootstrap.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "css/morris.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "css/jquery.easy-pie-chart.css"%}">
<script type="text/javascript" src="{% static "js/jquery/jquery.min.js" %}"></script>
<script src="{% static "js/raphael-min.js"%}"></script>
<script src="{% static "js/morris.min.js"%}"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<style type="text/css">
.ui-autocomplete {
z-index: 5000;
}
.ui-autocomplete .ui-menu-item {
font-size:x-small;
}
</style>
{% endblock %}
{% block content %}
<div class="container theme-showcase" role="main">
<div class="jumbotron">
<div class="row">
<div class="col-md-6">
{% if project %}
<h1>{{ project.name }}</h1>
<!--<h3> {{number}} corpora </h3>-->
{% endif %}
</div>
<div class="col-md-4">
<p>
{% if donut %}
<div id="hero-donut" style="height: 200px;"></div>
{% endif %}
<center>
<a data-toggle="modal" href="#addcorpus">
<button
type="button"
class="btn btn-primary btn-lg"
data-container="body"
data-toggle="popover"
data-placement="bottom"
>
Add a corpus
</button>
</a>
</center>
</p>
</div>
</div>
</div>
<!-- Add jumbotron container for each type of corpus (presse, science etc.) -->
<div id="semLoader" style="position:absolute; top:50%; left:40%; width:80px; visibility: hidden;">
<img src="{% static "js/libs/img2/loading-bar.gif" %}"></img>
</div>
<div class="container">
{% if list_corpora %}
<h1>Resources</h1>
<h2>Corpora</h2>
<ul>
{% for key, corpora in list_corpora.items %}
<li>
{{ key }}
<ul>
{% for corpus in corpora %}
<li>
{% ifequal corpus.processing 1 %}
{{corpus.name}}:
<img width="20px" src="{% static "js/libs/img2/loading-bar.gif" %}">
Processing, drink a cup of tea, and refresh the page :)
{% else %}
<a href="/projects/{{project.id}}/corpora/{{corpus.id}}"> {{corpus.name}} , {{ corpus.count }} Documents </a>
{% endifequal %}
<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> Add new documents </li>
<li><a href="/delete/{{corpus.id}}">Delete</a></li>
</ul>
'>Manage</button>
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endif %}
{% if list_corporax %}
<div class="col-md-4">
<h3>
<a href="/projects/{{project.id}}/corpora/{{corpus.id}}">{{corpus.name}}</a>
</h3>
<h4>{{ corpus.count }} Documents </h4>
<h5>Activity:</h5>
<div class="chart" data-percent="73">73%</div>
</div>
{% endif %}
<h2>Lists of Ngrams</h2>
{% if whitelists %}
<h3>White Lists</h3>
<ul>
{% for list in whitelists %}
<li>{{list.name }}</li>
{% endfor %}
</ul>
{% endif %}
{% if blacklists %}
<h3>Black Lists</h3>
<ul>
{% for list in blacklists %}
<li>{{list.name}}</li>
{% endfor %}
</ul>
{% endif %}
{% if cooclists %}
<h2>Results (graphs)</h2>
<h3>Cooccurrences Lists</h2>
<ul>
{% for list in cooclists %}
<li> {{list.name }}
</ul>
{% endfor %}
{% endif %}
</div>
<!-- Modal -->
<div class="modal fade" id="stack1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<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>Query to PubMed</h3>
</div>
<div class="modal-body">
<p>One fine body…</p>
<input id="daquery" type="text" class="input-lg" data-tabindex="2">
<a onclick="getGlobalResults();" class="btn">Scan</a>
<div id="results"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button onclick="doTheQuery();" disabled id="id_thebutton" type="button" class="btn btn-primary">Explore a sample!</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal -->
<div class="modal fade" id="addcorpus" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2" aria-hidden="true">
<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>Add a Corpus</h3>
</div>
<div class="modal-body">
<form id="id_form" enctype="multipart/form-data" action="/projects/{{project.id}}/" method="post">
{% csrf_token %}
<table cellpadding="5">
{% for field in form %}
<tr>
<th>{{field.label_tag}}</th>
<td>
{{ field.errors }}
{{ field }}
{% if field.name == "name" %}
<span onclick="getGlobalResults(this);" id="scanpubmed"></span>
<div id="theresults"></div>
{% endif %}
</td>
</tr>
{% endfor %}
<tr>
<th></th>
<td>
<div id="pubmedcrawl" style="visibility: hidden;">
Do you have a file already? &nbsp;
<input type="radio" id="file_yes" name="file1" onclick="FileOrNotFile(this.value);" class="file1" value="true" checked>Yes </input>
<input type="radio" id="file_no" name="file1" onclick="FileOrNotFile(this.value);" class="file1" value="false">No </input>
</div>
</td>
</tr>
</table>
</form>
<div class="modal-footer">
<!-- <div id="pubmedcrawl" align="right" style="visibility: hidden;"><a data-toggle="modal" href="#stack1">&#10142; Query directly in PubMed</a></div> -->
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button onclick='bringDaNoise();' id="submit_thing" disabled class="btn btn-primary" >Process this!</button><span id="simpleloader"></span>
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script type="text/javascript" src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script type="text/javascript">
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 thequeries = [] ;
// load the template's value for N scan size
var querySize = parseInt({{query_size}}) ;
// TODO if is_admin
function doTheQuery() {
if ( $('#submit_thing').prop('disabled') ) return;
console.log("in doTheQuery:");
var origQuery = $("#id_name").val()
var pubmedifiedQuery = {
query : JSON.stringify(thequeries) ,
string: origQuery ,
N : querySize
} ;
console.log(pubmedifiedQuery)
var projectid = window.location.href.split("projects")[1].replace(/\//g, '')//replace all the slashes
$.ajax({
// contentType: "application/json",
url: window.location.origin+"/tests/project/"+projectid+"/pubmedquery/go",
data: pubmedifiedQuery,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function(data) {
console.log("in doTheQuery() Ajax.Success:")
console.log(data)
setTimeout(
function() {
location.reload();
}, 3000);
},
error: function(result) {
console.log("in doTheQuery(). Data not found");
}
});
}
function bringDaNoise() {
var theresults = $("#theresults").html()
if( theresults && theresults.search("No results")==-1 ) {
console.log("we've in dynamic mode")
$("#simpleloader").html('<img width="30px" src="{% static "js/libs/img2/loading-bar.gif" %}"></img>')
$("#submit_thing").prop('onclick',null);
var theType = $("#id_type option:selected").html();
console.log("consoling the typeeee: ")
console.log(theType)
if(theType=="Pubmed (xml format)") doTheQuery();
if(theType=="ISTex") {
var origQuery = $("#id_name").val()
console.log("printing the results:")
console.log(origQuery)
testISTEX(origQuery.replace(" ","+"), querySize)
}
}
else {
console.log("we dont have nothing inside results div")
if ( $("#id_file").is(':visible') ) {
console.log("we're in upload-file mode")
var namefield = $("#id_name").val()!=""
var typefield = $("#id_type").val()!=""
var filefield = $("#id_file").val()!=""
if( namefield && typefield && filefield ) {
$("#simpleloader").html('<img width="30px" src="{% static "js/libs/img2/loading-bar.gif" %}"></img>')
$("#submit_thing").prop('onclick',null);
$( "#id_form" ).submit();
}
}
}
}
function getGlobalResults(value){
console.log("in getGlobalResults()")
// AJAX to django
var pubmedquery = $("#id_name").val()
// var Npubs = $("#id_N").val();
if(pubmedquery=="") return;
var formData = {query:pubmedquery , N:querySize}
$("#theresults").html('<img width="30px" src="{% static "js/libs/img2/loading-bar.gif" %}"></img>')
console.log("disabling "+"#"+value.id)
$("#"+value.id).prop('onclick',null);
var theType = $("#id_type option:selected").html();
if(theType=="Pubmed (xml format)") {
$.ajax({
// contentType: "application/json",
url: window.location.origin+"/tests/pubmedquery",
data: formData,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function(data) {
console.log("SUCCESS")
console.log("in getGlobalResults")
console.log(data)
console.log("enabling "+"#"+value.id)
$("#"+value.id).attr('onclick','getGlobalResults(this);');
// $("#submit_thing").prop('disabled' , false)
$("#submit_thing").html("Process a {{ query_size }} sample!")
thequeries = data
var N=0,k=0;
for(var i in thequeries) N += thequeries[i].count
if( N>0) {
$("#theresults").html("<i> <b>"+pubmedquery+"</b>: "+N+" publications in the last 5 years</i><br>")
$('#submit_thing').prop('disabled', false);
} else {
$("#theresults").html("<i> <b>"+pubmedquery+"</b>: No results!.</i><br>")
if(data[0]==false)
$("#theresults").html("Pubmed connection error!</i><br>")
$('#submit_thing').prop('disabled', true);
}
},
error: function(result) {
$("#theresults").html("Pubmed connection error!</i><br>")
$('#submit_thing').prop('disabled', true);
}
});
}
if(theType=="ISTex") {
console.log(window.location.origin+"tests/istextquery")
$.ajax({
// contentType: "application/json",
url: window.location.origin+"/tests/istextquery",
data: formData,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function(data) {
console.log("in getGlobalResults: Ajax(ISTex)")
console.log("enabling "+"#"+value.id)
$("#"+value.id).attr('onclick','getGlobalResults(this);');
// $("#submit_thing").prop('disabled' , false)
$("#submit_thing").html("Process a {{ query_size }} sample!")
thequeries = data
var N=data.length,k=0;
// for(var i in thequeries) N += thequeries[i].count
if( N>1) {
var total = JSON.parse(data).total
console.log("N: "+total)
$("#theresults").html("<i> <b>"+pubmedquery+"</b>: "+total+" publications.</i><br>")
$('#submit_thing').prop('disabled', false);
} else {
$("#theresults").html("<i> <b>"+data[0]+"</b></i><br>")
$('#submit_thing').prop('disabled', true);
}
},
error: function(result) {
console.log("Data not found");
}
});
}
}
// CSS events for selecting one Radio-Input
function FileOrNotFile( value ) {
var showfile = JSON.parse(value)
var theType = $("#id_type option:selected").html();
// @upload-file events
if (showfile) {
console.log("You've clicked the YES")
$("#id_file").show()
$('label[for=id_file]').show();
$("#id_name").attr("placeholder", "");
$("#scanpubmed").html("")
$("#theresults").html("")
$('#submit_thing').prop('disabled', false);
$( "#id_name" ).on('input',null);
$("#submit_thing").html("Process this!")
}
// @dynamic-query events
else {
console.log("You've clicked the NO")
$("#id_file").hide()
$('label[for=id_file]').hide();
$("#id_name").attr("placeholder", " [ Enter your query here ] ");
$("#id_name").focus();
$("#scanpubmed").html('<a class="btn btn-primary">Scan</a>')//+'Get: <input id="id_N" size="2" type="text"></input>')
$("#theresults").html("")
$("#submit_thing").prop('disabled' , true)
$( "#id_name" ).on('input',function(e){
console.log($(this).val())
if(theType=="Pubmed (xml format)")
testPUBMED( $(this).val() )
});
}
}
//CSS events for changing the Select element
function CustomForSelect( selected ) {
// show Radio-Inputs and trigger FileOrNotFile>@upload-file events
if(selected=="Pubmed (xml format)" || selected=="ISTex") {
// if(selected=="pubmed") {
console.log("show the button for: "+selected)
$("#pubmedcrawl").css("visibility", "visible");
$("#pubmedcrawl").show();
$("#file_yes").click();
$("#submit_thing").html("Process this!")
}
// hide Radio-Inputs and trigger @upload-file events
else {
console.log("hide the button")
$("#pubmedcrawl").css("visibility", "hidden");
$("#id_file").show()
$('label[for=id_file]').show();
FileOrNotFile( "true" )
}
}
var LastData = []
function NSuggest_CreateData(q, data) {
console.log("in the new NSuggest_CreateData:")
LastData = data;
// console.log(LastData)
console.log("adding class ui-widget")
$("#id_name").removeClass( "ui-widget" ).addClass( "ui-widget" )
$( "#id_name" ).autocomplete({
source: LastData
});
return data;
}
function testPUBMED( query ) {
LastData = []
if(!query || query=="") return;
var pubmedquery = encodeURIComponent(query)
$.ajax({
type: 'GET',
url: "http://www.ncbi.nlm.nih.gov/portal/utils/autocomp.fcgi?dict=pm_related_queries_2&q="+pubmedquery,
// data:"db="+db+"&query="+query,
contentType: "application/json",
dataType: 'jsonp'
});
return false;
}
function testISTEX(query,N) {
console.log("in testISTEX:");
if(!query || query=="") return;
var origQuery = query
var postQuery = { query : query , N: N }
var projectid = window.location.href.split("projects")[1].replace(/\//g, '')//replace all the slashes
$.ajax({
// contentType: "application/json",
url: window.location.origin+"/tests/project/"+projectid+"/ISTEXquery/go",
data: postQuery,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function(data) {
console.log("ajax_success: in testISTEX()")
console.log(data)
setTimeout(
function() {
location.reload();
}, 5000);
},
error: function(result) {
console.log("in testISTEX(). Data not found");
}
});
}
// Morris Donut Chart
Morris.Donut({
element: 'hero-donut',
data: [
{% if donut %}
{% for part in donut %}
{label: '{{ part.source }}', value: {{ part.part }} },
{% endfor %}
{% endif %}
],
colors: ["@white", "@white"],
//colors: ["#30a1ec", "#76bdee"],
formatter: function (y) { return y + "%" }
});
</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