Commit 8d42b26a authored by sim's avatar sim

Remove old web frontend

parent e710a96f
......@@ -2,7 +2,6 @@
Views are shared between these modules:
- `api`, for JSON and CSV interaction with data
- `pages`, to present HTML views to the user
- `contents`, for Python-generated contents
"""
......@@ -12,12 +11,10 @@ from django.views.generic.base import RedirectView as Redirect
from django.contrib.staticfiles.storage import staticfiles_storage as static
import gargantext.views.api.urls
import gargantext.views.pages.urls
urlpatterns = [ url(r'^admin/' , admin.site.urls )
, url(r'^api/' , include( gargantext.views.api.urls ) )
, url(r'^' , include( gargantext.views.pages.urls ) )
, url(r'^favicon.ico$', Redirect.as_view( url=static.url('favicon.ico')
, permanent=False), name="favicon" )
]
from django.contrib.auth import authenticate, login, logout
from django.core.urlresolvers import reverse_lazy
from django.views.generic import FormView
from django.shortcuts import redirect
from gargantext.util.db import session
from gargantext.models.users import User
from django import forms
from gargantext.models import Node, User
from gargantext.views.pages.projects import overview
from gargantext.views.pages.forms import AuthenticationForm
class LoginView(FormView):
form_class = AuthenticationForm
success_url = reverse_lazy(overview) #A la place de profile_view, choisir n'importe quelle vue
template_name = 'pages/main/login.html'
def form_valid(self, form):
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(self.request, user)
node_user = session.query(Node).filter(Node.user_id == user.id, Node.typename== "USER").first()
#user hasn't been found inside Node table
#create it from auth table => node table
if node_user is None:
node_user = Node(
typename = 'USER',
#in node = > name
#in user = > username
name = user.username,
user_id = user.id,
)
node_user.hyperdata = {"language":"fr"}
session.add(node_user)
session.commit()
return super(LoginView, self).form_valid(form)
else:
return self.form_invalid(form)
def out(request):
"""Logout the user, and redirect to main page
"""
logout(request)
return redirect('/')
from gargantext.util.http import *
from gargantext.util.db import *
from gargantext.util.db_cache import cache
from gargantext.models import *
from gargantext.constants import *
from gargantext.settings import *
from datetime import datetime
from .main import get_user_params
from gargantext.constants import USER_LANG
def _get_user_project_corpus(request, project_id, corpus_id):
"""Helper method to get a corpus, knowing the project's and corpus' ID.
Raises HTTP errors when parameters (user, IDs...) are invalid.
"""
user = cache.User[request.user.id]
project = session.query(Node).filter(Node.id == project_id).first()
corpus = session.query(Node).filter(Node.id == corpus_id).filter(Node.parent_id == project_id).first()
if corpus is None:
raise Http404()
if not user.owns(corpus):
print("CORPORA: invalid user %i (User doesn't own this corpus)" % user.id)
return (False, user, project, corpus)
return (True, user, project, corpus)
@requires_auth
def docs_by_titles(request, project_id, corpus_id):
authorized, user, project, corpus = _get_user_project_corpus(request, project_id, corpus_id)
if not authorized:
return HttpResponseForbidden()
source_type = corpus.resources()[0]['type']
# response!
return render(
template_name = 'pages/corpora/titles.html',
request = request,
context = {
'debug': DEBUG,
'date': datetime.now(),
'project': project,
'corpus': corpus,
'resourcename' : get_resource(source_type)['name'],
'view': 'titles',
'user': request.user,
'user_parameters': get_user_params(user),
'languages': USER_LANG
},
)
@requires_auth
def docs_by_sources(request, project_id, corpus_id):
'''
Browse source titles for a given corpus
NB: javascript in page will GET counts from our api: facets?subfield=source
# TODO refactor Sources_dyna_charts_and_table.js
'''
# we pass our corpus to mark it's a corpora page
corpus = cache.Node[corpus_id]
# and the project just for project.id in corpusBannerTop
project = cache.Node[project_id]
user = cache.User[request.user.id]
source_type = corpus.resources()[0]['type']
# rendered page : sources.html
return render(
template_name = 'pages/corpora/sources.html',
request = request,
context = {
'debug': settings.DEBUG,
'date': datetime.now(),
'project': project,
'corpus' : corpus,
'resourcename' : get_resource(source_type)['name'],
'user': request.user,
'user_parameters': get_user_params(user),
'view': 'sources',
'languages': USER_LANG
},
)
@requires_auth
def docs_by_authors(request, project_id, corpus_id):
'''
Browse authors for a given corpus
NB: javascript in page will GET counts from our api: facets?subfield=author
# TODO refactor Author && Sources_dyna_charts_and_table.js
'''
# we pass our corpus to mark it's a corpora page
corpus = cache.Node[corpus_id]
# and the project just for project.id in corpusBannerTop
project = cache.Node[project_id]
user = cache.User[request.user.id]
source_type = corpus.resources()[0]['type']
# rendered page : sources.html
node_user = get_node_user(user)
return render(
template_name = 'pages/corpora/authors.html',
request = request,
context = {
'debug': settings.DEBUG,
'date': datetime.now(),
'project': project,
'corpus' : corpus,
'resourcename' : get_resource(source_type)['name'],
'view': 'authors',
'user': request.user,
'user_parameters': node_user.hyperdata,
'languages': USER_LANG
},
)
@requires_auth
def analytics(request, project_id, corpus_id):
authorized, user, project, corpus = _get_user_project_corpus(request, project_id, corpus_id)
if not authorized:
return HttpResponseForbidden()
source_type = corpus.resources()[0]['type']
# response!
return render(
template_name = 'pages/analytics/histories.html',
request = request,
context = {
'debug': DEBUG,
'date': datetime.now(),
'project': project,
'corpus': corpus,
'resourcename' : get_resource(source_type)['name'],
'view': 'analytics',
'user': request.user,
'user_parameters': get_user_params(user),
'languages': USER_LANG
},
)
from django import forms
from django.contrib.auth import (
authenticate, get_user_model, password_validation,
)
from django.contrib.auth.hashers import (
UNUSABLE_PASSWORD_PREFIX, identify_hasher,
)
from django.utils.html import format_html, format_html_join
from django.utils.text import capfirst
from django.utils.translation import ugettext, ugettext_lazy as _
from gargantext.models.users import User
class AuthenticationForm(forms.Form):
"""
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
username = forms.CharField(max_length=254, widget=forms.TextInput(attrs={'class':"form-control", 'placeholder': "username"}))
password = forms.CharField(label=_("Password"), strip=False, widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder': 'Password'}))
error_messages = {
'invalid_login': _("Please enter a correct %(username)s and password. "
"Note that both fields may be case-sensitive."),
'inactive': _("This account is inactive."),
}
def __init__(self, request=None, *args, **kwargs):
"""
The 'request' parameter is set for custom auth use by subclasses.
The form data comes in via the standard 'data' kwarg.
"""
self.request = request
self.user_cache = None
super(AuthenticationForm, self).__init__(*args, **kwargs)
# Set the label for the "username" field.
UserModel = get_user_model()
self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
if self.fields['username'].label is None:
self.fields['username'].label = capfirst(self.username_field.verbose_name)
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username and password:
self.user_cache = authenticate(username=username,
password=password)
if self.user_cache is None:
raise forms.ValidationError(
'Invalid username or password'
)
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
"""
Controls whether the given User may log in. This is a policy setting,
independent of end-user authentication. This default behavior is to
allow login by active users, and reject login by inactive users.
If the given user cannot log in, this method should raise a
``forms.ValidationError``.
If the given user may log in, this method should return None.
"""
if not user.is_active:
raise forms.ValidationError(
'Compte Inactif'
)
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
def get_user(self):
return self.user_cache
from gargantext.util.http import *
from gargantext.util.db import session
from gargantext.models import Node, User
import datetime
from gargantext.util.generators import paragraphs, credits
from gargantext.constants import USER_LANG
def get_user_node(user):
if user is not None:
node_user = session.query(Node).filter(Node.user_id == user.id, Node.typename== "USER").first()
return node_user
else:
return None
def get_user_params(user):
node_user = get_user_node(user)
if node_user is not None:
return node_user.hyperdata
return {}
def home(request):
'''Home describes the platform.
A video draws the narratives.
If not logged a project test is shown.
'''
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(),
'languages': USER_LANG,
'user_parameters': get_user_params(request.user)
},
)
def about(request):
'''About Gargantext, its team and sponsors
'''
return render(
template_name = 'pages/main/about.html',
request = request,
context = {
'user': request.user,
'date': datetime.datetime.now(),
'team' : credits.members(),
'teamPast': credits.membersPast(),
'institutions': credits.institutions(),
'labos': credits.labs(),
'grants': credits.grants(),
'user_parameters': get_user_params(request.user),
'languages': USER_LANG,
},
)
def robots(request):
'''Robots rules
'''
return render(
template_name = 'pages/main/robots.txt',
request = request,
content_type='text/plain',
)
def maintenance(request):
'''Gargantext out of service
'''
user_node = get_user_node(request.user)
return render(
template_name = 'pages/main/maintenance.html',
request = request,
context = {
'user': request.user,
'date': datetime.datetime.now(),
'user_parameters': get_user_params(request.user)
},
)
from gargantext.util.http import *
from gargantext.util.db import *
from gargantext.util.db_cache import cache
from gargantext.util.files import upload
from gargantext.models import *
from gargantext.constants import *
from .main import get_user_params
from gargantext.util.scheduling import scheduled
from gargantext.util.toolchain import parse_extract_indexhyperdata
from datetime import datetime
from collections import defaultdict
from django.utils.translation import ugettext_lazy
import re
def get_node_user(user):
node_user = session.query(Node).filter(Node.user_id == user.id, Node.typename == "USER").first()
if node_user is None:
node_user = Node(user_id = user.id,
typename = 'USER',
name = user.name,
)
#default language for now is 'fr'
node_user.hyperdata["language"] = "fr"
session.add(node_user)
session.commit()
print(node_user.hyperdata)
return node_user
@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.
'''
user = cache.User[request.user.id]
print(user)
node_user = get_node_user(user)
# If POST method, creates a new project...
if request.method == 'POST':
name = str(request.POST['name'])
if name != '':
new_project = Node(
user_id = user.id,
typename = 'PROJECT',
name = name,
parent_id = node_user.id,
)
session.add(new_project)
session.commit()
# list of projects created by the logged user
user_projects = user.nodes(typename='PROJECT', order=True)
# list of contacts of the logged user
contacts_projects = list(user.contacts_nodes(typename='PROJECT'))
# 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': user_projects.count(),
'projects': user_projects,
'user_parameters': get_user_params(request.user),
'languages': USER_LANG,
# projects owned by the user's contacts
'common_users': (contact for contact, projects in contacts_projects),
'common_projects': sum((projects for contact, projects in contacts_projects), []),
# status refreshing params (when active workflows)
'status_refresh_initial_interval': PROJECT_VIEW_REFRESH_INTERVAL,
'status_refresh_max_attempts': PROJECT_VIEW_MAX_REFRESH_ATTEMPTS,
},
)
class NewCorpusForm(forms.Form):
#mapping choices based on ressource.type
source_list = [(resource["type"], resource["name"]) for resource in RESOURCETYPES]
source_list.insert(0, (0,"Select a database below"))
type = forms.ChoiceField(
choices = source_list,
widget = forms.Select(attrs={ 'onchange' :'CustomForSelect(this.value); checkReady()'})
)
name = forms.CharField( label='Name', max_length=199 ,
widget = forms.TextInput(attrs={ 'required': 'true', 'onkeyup':'checkReady()' })
)
file = forms.FileField(
widget = forms.FileInput(attrs={ 'onchange':'checkReady()' })
)
def clean_resource(self):
file_ = self.cleaned_data.get('file')
def clean_file(self):
file_ = self.cleaned_data.get('file')
if len(file_) > 1024 ** 3 : # we don't accept more than 1GB
raise forms.ValidationError(ugettext_lazy('File too heavy! (>1GB).'))
return file_
@requires_auth
def project(request, project_id):
# security check
project = session.query(Node).filter(Node.id == project_id).first()
user = cache.User[request.user.id]
node_user = get_node_user(user)
if project is None:
raise Http404()
if not user.owns(project):
return HttpResponseForbidden()
# end of security check
# new corpus
if request.method == 'POST':
corpus = project.add_child(
name = request.POST['name'],
typename = 'CORPUS',
)
corpus.add_resource(
type = int(request.POST['type']),
path = upload(request.FILES['file']),
)
session.add(corpus)
session.commit()
# parse_extract: fileparsing -> ngram extraction -> lists
scheduled(parse_extract_indexhyperdata)(corpus.id)
wait = True
else:
wait = False
# corpora within this project
corpora = project.children('CORPUS', order=True).all()
sourcename2corpora = defaultdict(list)
for corpus in corpora:
# we only consider the first resource of the corpus to determine its type
resources = corpus.resources()
if len(resources):
resource = resources[0]
#resource_type_name = RESOURCETYPES[resource['type']]['name']
resource_type_name = get_resource(resource["type"])["name"]
else:
print("(WARNING) PROJECT view: no listed resource")
# add some data for the viewer
corpus.count = corpus.children('DOCUMENT').count()
status = corpus.status()
if status is not None and not status['complete']:
if not status['error']:
corpus.status_message = '(in progress: %s, %d complete)' % (
status['action'].replace('_', ' '),
status['progress'],
)
else:
corpus.status_message = '(aborted: "%s" after %i docs)' % (
status['error'][-1],
status['progress']
)
else:
corpus.status_message = ''
# add
sourcename2corpora[resource_type_name].append(corpus)
# source & their respective counts
total_documentscount = 0
sourcename2documentscount = defaultdict(int)
for sourcename, corpora in sourcename2corpora.items():
sourcename = re.sub(' \(.*$', '', sourcename)
for corpus in corpora:
count = corpus.children('DOCUMENT').count()
sourcename2documentscount[sourcename] += count
total_documentscount += count
donut = [
{ 'source': sourcename,
'count': count,
'part' : round(count * 100.0 / total_documentscount, 1) if total_documentscount else 0,
}
for sourcename, count in sourcename2documentscount.items()
]
if wait:
return render(
template_name = 'pages/projects/wait.html',
request = request,
context = {
'form': NewCorpusForm,
'user': request.user,
'user_parameters': get_user_params(request.user),
'languages': USER_LANG,
'date': datetime.now(),
'project': project,
'donut': donut,
'list_corpora': dict(sourcename2corpora),
'whitelists': [],
'blacklists': [],
'cooclists': [],
'number': len(corpora),
'query_size': QUERY_SIZE_N_DEFAULT,
# status refreshing params (when active workflows)
'status_refresh_initial_interval': PROJECT_VIEW_REFRESH_INTERVAL,
'status_refresh_max_attempts': PROJECT_VIEW_MAX_REFRESH_ATTEMPTS,
},
)
# response!
return render(
template_name = 'pages/projects/project.html',
request = request,
context = {
'user_parameters': get_user_params(request.user),
"languages": USER_LANG,
'form': NewCorpusForm,
'user': request.user,
'date': datetime.now(),
'project': project,
'donut': donut,
'list_corpora': dict(sourcename2corpora),
'whitelists': [],
'blacklists': [],
'cooclists': [],
'number': len(corpora),
'query_size': QUERY_SIZE_N_DEFAULT,
# status refreshing params (when active workflows)
'status_refresh_initial_interval': PROJECT_VIEW_REFRESH_INTERVAL,
'status_refresh_max_attempts': PROJECT_VIEW_MAX_REFRESH_ATTEMPTS,
},
)
from gargantext.util.http import requires_auth, render, settings
from gargantext.util.db import session
from gargantext.util.db_cache import cache
from gargantext.models import Node
from gargantext.constants import get_resource
from gargantext.constants import USER_LANG
from .main import get_user_params
from datetime import datetime
@requires_auth
def ngramtable(request, project_id, corpus_id):
'''
Browse and modify all lists together.
=> maplist and mainlist terms in a table
with groupings as '+' nodes
=> uses API GET batch of lists
=> uses API PUT/DEL for list modifications
=> uses frontend AJAX through Ngrams_dyna_charts_and_table.js
# TODO refactor Ngrams_dyna_charts_and_table.js
'''
# corpus still necessary to find all lists
corpus = cache.Node[corpus_id]
# and the project just for project.id in corpusBannerTop
project = cache.Node[project_id]
# retrieve all corpora of this user for list import option
# POSSIBILITY: could do same task in ajax "only if needed"
# (use api for that when merged)
corpora_infos_q = (session.query(Node.id, Node.name)
.filter(Node.typename == "CORPUS")
.filter(Node.user_id == project.user_id))
# .filter(Node.id != corpus_id)
corpora_infos = corpora_infos_q.all()
source_type = corpus.resources()[0]['type']
# rendered page : terms.html
return render(
template_name = 'pages/corpora/terms.html',
request = request,
context = {
'debug': settings.DEBUG,
'user': request.user,
'date': datetime.now(),
'project': project,
'corpus' : corpus,
'resourcename' : get_resource(source_type)['name'],
'view': 'terms',
# for the CSV import modal
'importroute': "/api/ngramlists/import?onto_corpus=%i"% corpus.id,
'corporainfos' : corpora_infos,
#user params
'user_parameters': get_user_params(request.user),
'languages': USER_LANG
},
)
from django.conf.urls import url
from . import main
from . import projects, corpora, terms
from .auth import LoginView, out
urlpatterns = [
# presentation pages
url(r'^$', main.home),
url(r'^about/?$', main.about),
url(r'^robots.txt$', main.robots),
# maintenance mode
url(r'^maintenance/?$', main.maintenance),
# authentication
url(r'^auth/login/?$' , LoginView.as_view()),
url(r'^auth/logout/?$', out),
# projects
url(r'^projects/?$' , projects.overview),
url(r'^projects/(\d+)/?$' , projects.project),
# corpora
url(r'^projects/(\d+)/corpora/(\d+)/?$', corpora.docs_by_titles),
# corpus by sources
url(r'^projects/(\d+)/corpora/(\d+)/sources/?$', corpora.docs_by_sources),
# corpus by authors
url(r'^projects/(\d+)/corpora/(\d+)/authors/?$', corpora.docs_by_authors),
# terms table for the corpus
url(r'^projects/(\d+)/corpora/(\d+)/terms/?$', terms.ngramtable),
# Analytics
url(r'^projects/(\d+)/corpora/(\d+)/analytics/?$', corpora.analytics),
]
{% extends "pages/menu.html" %}
{% block content %}
{% load staticfiles %}
<div class="container">
<h3 class="help" id="filter_analytics">
<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span>
Filter your documents with terms and watch histories (you can compare all your corpora).
</h3>
</div>
<!-- All the templates used by the Javascript framework -->
{% verbatim %}
{% endverbatim %}
<script type="text/javascript" src="{% static "lib/jquery/2.2.0/jquery.min.js" %}"></script>
{% verbatim %}
<style type="text/css">
div.controller div.autocomplete {margin: 0; padding: 0; }
div.controller div.autocomplete * {background: transparent; }
div.controller div.autocomplete ul.suggestion-list {background: rgba(255,255,255,.75); }
div.controller .tags li.tag-item {background: transparent; border: solid 1px rgba(0,0,0,.1); box-shadow: inset .05em .1em .4em rgba(0,0,0,.4); border-radius: 0; font-weight: bold; }
div.controller div.autocomplete li.suggestion-item:hover, div.controller div.autocomplete li.suggestion-item.selected {background: rgba(0,0,0,.5)}
div.controller div.autocomplete li.suggestion-item em {background: transparent; }
div.controller div.tags>input {padding: 0; border: 0; outline: 0; box-shadow: none; background: transparent;}
div.controller div.tags>input::-webkit-input-placeholder,div.controller div.tags input::-webkit-input-placeholder {color: rgba(0,0,0,.25); }
div.controller, div.controller * {color: rgba(0,0,0,.75); }
div.controller button {background: none; border: solid 1px rgba(0,0,0,.25); box-shadow: .05em .1em .4em rgba(0,0,0,.5); opacity: .5; }
div.controller button:hover {opacity: .65; }
div.controller button:active {opacity: .8; }
div.controller>button {width: 100%; }
div.controller input[type=checkbox] {position: relative; top: .125em; }
div.controller input[type=text], div.controller select, div.controller div.tags {font-weight: bold; box-shadow: inset .05em .1em .4em rgba(0,0,0,.2); outline: solid 1px rgba(0,0,0,.125); border: 0; background: rgba(255,255,255,.5); }
div.controller input[type=text] {padding-left: 0.5em;}
ul.datasets {padding: 0; margin: 0; list-style: none; }
li.dataset {padding: 0.3em; border: solid 1px rgba(0,0,0,.125); margin-bottom: 0.5em; box-shadow: inset .1em .2em .8em rgba(0,0,0,.1) }
li.dataset * { }
li.dataset button {float: right; position: relative; top: -.15em; margin-left: .25em; }
li.dataset select {cursor: pointer; border: 0; padding: 0; }
ul.filters {list-style: none; margin: 0; padding: 0; margin-top: .25em;}
ul.filters>li {padding-top: .5em; margin-top: .5em; border-top: solid 1px rgba(0,0,0,.125);}
ul.filters>li>ul {list-style: none; padding-left: 0; margin-top: .5em; }
ul.filters>li>ul>li.inline {width: 30%; display: inline-block; }
ul.filters>li>ul>li>label {font-weight: normal; cursor: pointer; }
ul.filters>li input[type=checkbox] {opacity: .8;}
</style>
<div class="container">
<div ng-app="Gargantext" ng-controller="GraphController" class="controller">
<!-- add a new dataset -->
<button ng-click="addDataset()">Add a dataset</button>
<ul class="datasets">
<li class="dataset" ng-controller="DatasetController" ng-repeat="dataset in datasets" style="background-color:{{ getColor($index, datasets.length) }}">
<!-- main part -->
<div class="main">
<!-- buttons -->
<button ng-click="show_filters = !show_filters">{{ show_filters ? 'Hide' : 'Show' }} filters</button>
<button ng-click="removeDataset($index)">Remove dataset</button>
<!-- description of Y values -->
Evolution of the
<select ng-model="query_y.value" ng-options="value as key for (key, value) in {'documents count': 'documents_count', 'expressions count': 'ngrams_count'}" ng-change="updateDataset()"></select>
<select ng-model="query_y.is_relative" ng-options="value as key for (key, value) in {'in absolute terms': false}" ng-change="updateDataset()"></select>
<!-- <select ng-model="query_y.is_relative" ng-options="value as key for (key, value) in {'in absolute terms': false, 'relative to the': true}" ng-change="updateDataset()"></select>
-->
<span ng-if="query_y.is_relative">
<select ng-model="query_y.divided_by" ng-options="value as key for (key, value) in {'total expressions count': 'total_ngrams_count', 'total documents count': 'total_documents_count'}" ng-change="updateDataset()"></select>
</span>
</div>
<!-- filters -->
<ul class="filters" ng-show="show_filters">
<!-- filter corpora -->
<li>
<button ng-click="corporaSelectAll()">select all</button>
<button ng-click="corporaSelectNone()">select none</button>
...restrict to the following corpora:
<ul>
<li ng-repeat="corpus in corpora" class="inline">
<label>
<input type="checkbox" ng-model="corpus.is_selected" ng-change="updateHyperdataList();updateDataset()"/>
<span style="font-weight: {{ corpus.is_selected ? 'bold' : 'normal' }}">{{ corpus.name }}</span>
</label>
</li>
</ul>
</li>
<!-- filter ngrams -->
<li class="ngrams">
...only consider documents containing the following expressions:
<tags-input ng-model="query_y.ngrams" display-property="terms" placeholder="Add an expression" on-tag-added="updateDataset()" on-tag-removed="updateDataset()" add-from-autocomplete-only="true"
replace-spaces-with-dashes="false">
<auto-complete source="getNgrams($query)"></auto-complete>
</tags-input ng-model="tags">
</li>
<!-- filter hyperdata
<li>
<ul>
<li ng-repeat="hyperdata in hyperdataList">
...with
<span ng-if="!hyperdata.operator &amp;&amp; (!hyperdata.values || !hyperdata.value)">"{{ hyperdata.name }}"</span>
<strong ng-if="hyperdata.operator || (hyperdata.values &amp;&amp; hyperdata.value)">{{ hyperdata.name }}</strong>
<span ng-if="hyperdata.values">
is
<select ng-model="hyperdata.value" ng-options="value for value in hyperdata.values" ng-change="updateDataset()"></select>
</span>
<span ng-if="!hyperdata.values">
<select ng-model="hyperdata.operator" ng-options="operator.key as operator.label for operator in operators[hyperdata.type]"></select>
<input type="text" ng-if="hyperdata.operator" ng-model="hyperdata.value" ng-change="updateDataset()" placeholder="type a value here..." />
</span>
</li>
</ul>
</li>
-->
</ul>
</li>
</ul>
<!-- X-axis (time) resolution -->
<p>
(group results by
<select ng-model="query_x.resolution" ng-options="period as period for period in periods" ng-change="updateDatasets(true)"></select>)
</p>
<!-- data representation -->
Represent data with
<select ng-model="seriesOptions.type" ng-options="type for type in ['column', 'area', 'line']" ng-change="updateDatasets()"></select>
<span ng-show="seriesOptions.type == 'area' || seriesOptions.type == 'column'">
(<select ng-model="options.stacking" ng-options="value as key for (key, value) in {'with':true, 'without':false}" ng-change="updateDatasets()"></select> stacking)
</span>
<div class="graph">
<linechart data="graph.data" options="graph.options"></linechart>
</div>
</div>
{% endverbatim %}
<script type="text/javascript" src="{% static "lib/angular/1.2.26/angular.min.js" %}"></script>
<script type="text/javascript" src="{% static "lib/angular-cookies/1.2.29/angular-cookies.min.js" %}"></script>
<!-- <script type="text/javascript" src="{% static "lib/d3/d3/d3.v2.min.js" %}"></script> -->
<script type="text/javascript" src="{% static "lib/d3/n3.line-chart.min.js" %}"></script>
<script type="text/javascript" src="{% static "lib/ng-tags/ng-tags-input.min.js" %}"></script>
<link rel="stylesheet" href="{% static "lib/ng-tags/ng-tags-input.min.css" %}">
<script type="text/javascript" src="{% static "lib/gargantext/gargantext.angular.js" %}"></script>
{% endblock %}
{% extends "pages/menu.html"}
{% block css %}
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static "lib/bootstrap/3.0.2/bootstrap.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "lib/d3/dc.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/jquery/dynatable/jquery.dynatable.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/gargantext/tables.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/gargantext/charts.css"%}"/>
<script type="text/javascript" src="{% static "lib/d3/d3.js"%}"></script>
<script type="text/javascript" src="{% static "lib/d3/crossfilter.js"%}"></script>
<script type="text/javascript" src="{% static "lib/d3/dc.js"%}"></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="col-md-3 col-md-offset-2">
<div id="monthly-move-chart">
<center>
Select a frequency group in the chart with blue bars to zoom in
<p align="center">
<!--<a class="btn btn-xs btn-default" role="button" href="/chart/corpus/{{ corpus.id }}/data.csv">Save</a>-->
<a class="btn btn-xs btn-default" href="javascript:volumeChart.filterAll();dc.redrawAll();">Reset</a></p>
<!-- <p style="font-size:70%">
<b>x</b>: amount of documents for the author
<b>y</b>: number of authors with that amount
</p> -->
<div class="clearfix"></div>
</center>
</div>
<div class="bs-callout">
<div class="row">
<div id="monthly-volume-chart"></div>
</div>
<div id="content_loader">
<br>
<center>
<!-- <img width="10%" src="{% static "img/ajax-loader.gif"%}"></img> -->
</center>
<br>
</div>
</div>
</div>
</div>
<div class="container">
<div class="jumbotron">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<center>
<span class="glyphicon glyphicon-hand-down" aria-hidden="true"></span>
Publications by source
</center>
</h2>
</div>
<div class="panel-body">
<div id="div-table">
<!-- (table id="my-ajax-table") dynamically set by Authors_dyna_chart_and_table -->
</div>
</div>
</div> <!-- /div panel -->
</div> <!-- /jumbotron -->
<!--</div> This div is closed in the menu !-->
<script type="text/javascript" src="{% static "lib/jquery/dynatable/jquery.dynatable.js" %}"></script>
<!-- custom-lib for dynatable.js and dc.js -->
<script type="text/javascript" src="{% static "lib/gargantext/Authors_dyna_chart_and_table.js" %}"></script>
<script type="text/javascript" src="{% static "lib/gargantext/help.js" %}"></script>
{% endblock %}
This diff is collapsed.
{% extends "pages/menu.html"%}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" type="text/css" href="{% static "lib/d3/dc.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/jquery/dynatable/jquery.dynatable.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/gargantext/tables.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/gargantext/charts.css"%}"/>
<script type="text/javascript" src="{% static "lib/d3/d3.js"%}"></script>
<script type="text/javascript" src="{% static "lib/d3/crossfilter.js"%}"></script>
<script type="text/javascript" src="{% static "lib/d3/dc.js"%}"></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="col-md-3 col-md-offset-2">
<div class="bs-callout">
<div class="row">
<div id="monthly-volume-chart"></div>
</div>
</div>
<div class="bs-callout">
<div class="row">
<div id="monthly-move-chart">
<center>
<p class="help" id="sources_time">Select a time range in the chart with blue bars to zoom in </p>
<p align="center">
<!--<a class="btn btn-xs btn-default" role="button" href="/chart/corpus/{{ corpus.id }}/data.csv">Save</a>-->
<a class="btn btn-xs btn-default" href="javascript:volumeChart.filterAll();dc.redrawAll();">Reset</a>
</p>
<div class="clearfix"></div>
</center>
</div>
</div>
<div id="content_loader">
<br>
<center>
<img width="10%" src="{% static "img/ajax-loader.gif"%}"></img>
</center>
<br>
</div>
</div>
</div>
</div>
<div class="container">
<div class="jumbotron">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<center>
<span class="glyphicon glyphicon-hand-down" aria-hidden="true"></span>
Publications by source
</center>
</h2>
</div>
<div class="panel-body">
<div id="div-table">
<!-- (table id="my-ajax-table") dynamically set by Sources_dyna_chart_and_table -->
</div>
</div>
</div> <!-- /div panel -->
</div> <!-- /jumbotron -->
<!--</div> This div is closed in the menu !-->
<script type="text/javascript" src="{% static "lib/jquery/dynatable/jquery.dynatable.js" %}"></script>
<!-- custom-lib for dynatable.js and dc.js -->
<script type="text/javascript" src="{% static "lib/gargantext/Sources_dyna_chart_and_table.js" %}"></script>
<!-- <script type="text/javascript" src="{% static "lib/gargantext/help.js" %}"></script> -->
{% endblock %}
This diff is collapsed.
{% extends "pages/menu.html"%}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" type="text/css" href="{% static "lib/d3/dc.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/jquery/dynatable/jquery.dynatable.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/gargantext/tables.css"%}"/>
<link rel="stylesheet" type="text/css" href="{% static "lib/gargantext/charts.css"%}"/>
<script type="text/javascript" src="{% static "lib/d3/d3.js"%}"></script>
<script type="text/javascript" src="{% static "lib/d3/crossfilter.js"%}"></script>
<script type="text/javascript" src="{% static "lib/d3/dc.js"%}"></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="col-md-3 col-md-offset-2">
<div class="bs-callout">
<div class="row">
<div id="monthly-volume-chart"></div>
</div>
</div>
<div class="bs-callout">
<div class="row">
<div id="monthly-move-chart">
<center>
<p class="help" id="titles_time">Select a time range in the chart with blue bars to zoom in </p>
<p align="center">
<!--<a class="btn btn-xs btn-default" role="button" href="/chart/corpus/{{ corpus.id }}/data.csv">Save</a>-->
<a class="btn btn-xs btn-default" href="javascript:volumeChart.filterAll();dc.redrawAll();">Reset</a>
</p>
<div class="clearfix"></div>
</center>
</div>
</div>
<div id="content_loader">
<br>
<center>
<img width="10%" src="{% static "img/ajax-loader.gif"%}"></img>
</center>
<br>
</div>
</div>
</div>
</div>
<input type="hidden" id="list_id" value="{{ list_id }}"></input>
<div class="container">
<div class="jumbotron">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<center>
<span class="glyphicon glyphicon-hand-down" aria-hidden="true"></span>
Publications by title
</center>
</h2>
<!-- search box with custom function in Docs_dyna_chart_and_tables.js -->
<div class="pull-left" style="margin-top:1.85em; font-size: 16px;">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search:
<input type="search" id="doubleSearch"/>
<span style="font-size:70%;">
<span class="glyphicon glyphicon-filter" aria-hidden="true"></span>
<!-- Used by the #doubleSearch associated function -->
<input title="Search in Titles" id="searchTI" name="searchTI" type="checkbox" checked onclick="return false">
TI&nbsp;
</input>
<span class="glyphicon glyphicon-filter" aria-hidden="true"></span>
<input title="Search in Abstracts" id="searchAB" name="searchAB" type="checkbox">
AB&nbsp;&nbsp;
</input>
</span>
<span class="glyphicon glyphicon-filter" aria-hidden="true"></span>
<select id="docFilter" name="docFilter" class="help">
<option value="filter_all">All</option>
<option value="filter_favs">Favorite documents</option>
<option value="filter_dupl_all">Duplicates (title, date &amp; src)</option>
</select>
</div>
</div>
<div class="panel-body">
<div id="div-table"></div>
<p align="right">
<button id="empty-trash" class="btn btn-primary btn-lg" >
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
Trash It!
</button>
</p>
</div>
</div>
</div>
<!--</div> This div is closed in the menu !-->
<!-- here goes import script js/bootstrap/bootstrap-multiselect.js, mais ca marche pas-->
<script type="text/javascript" src="{% static "lib/jquery/dynatable/jquery.dynatable.js" %}"></script>
<!-- custom-lib for dynatable.js and dc.js -->
<script type="text/javascript" src="{% static "lib/gargantext/Docs_dyna_chart_and_table.js" %}"></script>
<!-- <script type="text/javascript" src="{% static "lib/gargantext/help.js" %}"></script> -->
{% endblock %}
This diff is collapsed.
{% extends "pages/menu.html" %}
{% load staticfiles %}
{% block css %}
<script src="{% static "lib/jquery/1.11.1/jquery.min.js" %}" type="text/javascript"></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="jumbotron">
<div class="row">
<div class="col-md-8 content">
<h1>Gargantext</h1>
<p>A web platform to explore text-mining</p>
<p>
<a class="btn btn-primary btn-lg" href="/projects" title="Click and test by yourself">
<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span>
Log in
</a>
<a class="btn btn-warning btn-lg" target="blank" href="https://iscpif.fr/services/applyforourservices/" title="Fill the form to sign up">
<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span>
Sign Up
</a>
<a class="btn btn-success btn-lg" target="blank" href="https://iscpif.fr/gargantext/your-first-map/" title="Fill the form to sign up">
<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span>
Documentation
</a>
</p>
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"></span>
<i>
Some features may not work without a javascript optimized browser (Chromium for instance).
</i>
</p>
</div>
<div class="col-md-2 content">
<p class="right">
<div style="border:15px">
<img src="{% static "img/logo.png"%}" title="Logo designed by dacha and anoe" style="100px; height:150px; border:3px solid white">
</div>
</p>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="content">
<center>
<img src="{% static "img/Gargantextuel-212x300.jpg"%}" title="Gargantextuel drawn by Cecile Meadel" style="border:2px solid black">
<!--
<h2>Introduction Video</h2>
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support this video sorry. Try Firefox or Chromium.
</video>
-->
</center>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-4 content">
<h3><a href="#" title="Random sentences in Gargantua's Books chapters, historically true">Historic</a></h3>
<p> {{ paragraph_gargantua }}</p>
</div>
<div class="col-md-4 content">
<h3><a href="#" title="Randomized words, semantically and syntaxically falses." >Presentation</a></h3>
<p> {{ paragraph_lorem }}
</p>
</div>
<div class="col-md-4 content">
<h3><a href="#" title="Randomized letters, true or false ?">Tutoreil</a></h3>
<p>
{{ paragraph_tutoreil }}
<!-- Why not French ? -->
<!-- find Cambridge source which inspired this -->
</p>
</div>
</div>
{% endblock %}
<script type="text/javascript" src="{% static "lib/gargantext/help.js" %}"></script>
<!DOCTYPE html>
<html>
{% load staticfiles %}
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Login | Gargantext</title>
<!-- Prevent the demo from appearing in search engines (REMOVE THIS) -->
<meta name="robots" content="noindex">
<!-- Material Design Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Roboto Web Font -->
<link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet">
<!-- App CSS -->
<link type="text/css" href="{% static "lib/bootstrap/4.0.0/login.min.css" %}" rel="stylesheet">
</head>
<body class="login">
<div class="row">
<div class="col-sm-10 col-sm-push-1 col-md-6 col-md-push-3 col-lg-6 col-lg-push-3">
<h2 class="text-primary center m-a-2">
<i class="material-icons md-36">control_point</i> <span class="icon-text">Gargantext</span>
</h2>
<div class="card-group">
<div class="card">
<div class="card-block">
<div class="center">
<h4 class="m-b-0"><span class="icon-text">Connexion</span></h4>
<p class="text-muted">Login to your account or <a target="blank" href="https://iscpif.fr/services/applyforourservices/">ask to get an access</a></p>
</div>
{% if form.errors %}
<div class="alert alert-danger fade in">
<a href="#" class="close" data-dismiss="alert" aria-label="close" title="close">×</a>
<strong>{{form.non_field_errors}}</strong>
</div>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
{{form.username}}
</div>
<div class="form-group">
{{form.password}}
<div class="clearfix"></div>
</div>
<div class="center">
<div class="checkbox">
<label>
<input id="terms-accept" type="checkbox" value="" onclick="enableAuth(this)">
I accept the terms of uses <a href="http://gitlab.iscpif.fr/humanities/tofu/tree/master" target=blank>
[Read the terms of use]</a>.
</input>
</label>
</div>
<button id="login-button" type="submit" class="btn btn-primary btn-rounded" disabled>Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- jQuery -->
<script src="{% static "lib/jquery/1.11.1/jquery.min.js" %}"></script>
<!-- Bootstrap -->
<script src="{% static "lib/bootstrap/3.2.0/bootstrap.min.js" %}"></script>
<!-- checkbox => submit -->
<script type="text/javascript">
var okButton = document.getElementById('login-button')
function enableAuth(box) {
okButton.disabled = ! box.checked
}
</script>
</body>
</html>
{% extends "pages/menu.html" %}
{% block css %}
{% load staticfiles %}
<link rel="stylesheet" href="{% static "lib/bootstrap/3.0.2/bootstrap.css" %}">
<script src="{% static "lib/jquery/1.11.1/jquery.min.js" %}" type="text/javascript"></script>
{% endblock %}
{% block content %}
<div class="container theme-showcase" role="main">
<div class="jumbotron">
<h1>Gargantext in maintenance</h1>
<h2>Thanks for your comprehension</h2>
</div>
</div>
{% endblock %}
User-agent: *
Disallow : /auth/
Disallow : /projects/
This diff is collapsed.
<div class ="container">
<div id="addform" class="row collapse">
<div class="col-md-3"></div>
<div class="col-md-6">
<center>
<div class="panel panel-info">
<div class="panel-heading">Add a corpus</div>
<div class="panel-body">
<form id="form" class="add" role="form" action="/project/{{ project_id }}/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div id="radioBtn" class="btn-group">
<a id="parse" class="btn btn-info active" data-toggle="method" data-title="parse">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" > UPLOAD</span>
</a>
<div class="btn">
OR
</div>
<a id="scan" class="btn btn-info notActive" data-toggle="method" data-title="scan">
<span class="glyphicon glyphicon-search" aria-hidden="true" > SEARCH</span>
</a>
</div>
<br />
<br />
<div class="form-group" for="corpus_name">
<label for="name">Name:</label>
<input type="text" id="name"/>
<span class="help-block collapse" for="name">This field is required.</span>
</div>
<div id="source-group">
<label for="source">Select a database</label>
<select id="source" name="source" required>
<option value=""> Select a database &dArr; </option>
{% for element in ressources %}
{% if element.parser != None and element.crawler != None %}
<option value="{{element.type}}" data-parser ="true" data-crawler="true" data-format={{element.file_formats|join:","}}>{{element.name}}</option>
{% elif element.parser != None and element.crawler == None %}
<option value="{{element.type}}" data-parser ="true" data-crawler="false" data-format ={{element.file_formats| join:","}}>{{element.name}}</option>
{% elif element.parser == None and element.crawler != None %}
<option value="{{element.type}}" data-parser ="false" data-crawler="true" data-format ={{element.file_formats|join:","}}>{{element.name}}</option>
{%else%}
<option value="{{element.type}}" data-parser ="false" data-crawler="false" data-format ={{element.file_formats|join:","}}>{{element.name}}</option>
{% endif %}
{% endfor %}
</select>
<span class="help-block collapse" for="source">This field is required</span>
</div>
<br />
<div id="parser" class="form-group">
<input type="file" id="file" data-validation="mime size" data-validation-allowing="csv, txt, xml, zip" data-validation-max-size="1M" name="file" class="form-control-file" accept="text/*,application/xml, application/zip">
<span class="help-block collapse" for="file" class="danger">This field is required</span>
</div>
<br />
<div id="crawler" class="form-group">
<label for="query">Query:</label>
<textarea id="query" type="input" name="query" class="form-control col-xs-12"></textarea>
<span class="help-block collapse" for="id_query" class="danger">This field is required</span>
<br>
</div>
<br />
<div class="form-group" id="btnsubmit">
<button type="button" id="create" class="btn btn-info" >
Add corpus
</button>
</div>
</form>
<span id="simpleloader"></span>
</div>
</div>
</center>
</div>
<div class="col-md-3"></div>
</div>
</div>
{% if list_corpora %}
{% for key, corpora in list_corpora.items %}
<h2>
<div class="row">
<div class="col-md-1 content"></div>
<span class="glyphicon glyphicon-cd" aria-hidden="true"></span>
{{ key }}
</h2>
{% for corpus in corpora %}
<div id="corpus_{{corpus.id}}">
<div class="row">
<h4>
<div class="col-md-1 content"></div>
<div class="col-md-5 content">
<a href="/projects/{{project.id}}/corpora/{{corpus.id}}">
<span class="glyphicon glyphicon-file" aria-hidden="true"></span>
{{corpus.name}}, {{ corpus.count }} documents {{ corpus.status_message }}
</a>
</div>
<div class="col-md-3 content">
<!-- -->
{% for state in corpus.hyperdata.statuses %}
{% ifequal state.action "Workflow" %}
{% if state.complete %}
<a href="/projects/{{project.id}}/corpora/{{corpus.id}}" title="View the corpus">
<button type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
</button>
</a>
<button type="button" class="btn btn-default yopla" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="focus"
data-content="
<ul>
<li
onclick=&quot;
garganrest.metrics.update({{corpus.id}}, function(){alert('The corpus ({{corpus.name|escapejs}}) was updated')});
&quot;>
<a href='#'>Recalculate ngram metrics</a> <br/> (can take a little while)
</li>
</ul>
">
<span class="glyphicon glyphicon-repeat" aria-hidden="true"
title='Recalculate ngram scores and similarities'></span>
</button>
{% endif %}
<!-- TODO: delete non seulement si state.complete mais aussi si state.error -->
<button type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="bottom"
data-content="
<ul>
<li
onclick=&quot;
garganrest.nodes.delete({{corpus.id}}, function(){$('#corpus_'+{{corpus.id}}).remove()});
$(this).parent().parent().remove();
&quot;>
<a href='#'>Delete this</a>
</li>
</ul>
">
<span class="glyphicon glyphicon-trash" aria-hidden="true"
title='Delete this corpus'></span>
</button>
{% endifequal %}
{% endfor %}
</div>
<div class="col-md-3 content">
{% for state in corpus.hyperdata.statuses %}
{% ifequal state.action "Workflow" %}
{% if state.complete %}
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
{% else %}
{% if state.error %}
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
{{ state.error }}
{% else %}
<div class="progress">
<div class=" progress-bar progress-bar-striped
progress-bar-success
"
role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 20%">
<span>
Upload
</span>
</div>
{% for state in corpus.hyperdata.statuses %}
<div class=" progress-bar progress-bar-striped
{% if state.complete %}
progress-bar-success
{% else %}
active
{% endif %}
"
role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 20%">
<span>
{{ state.action }}
{% if not state.complete %}
Processing
{% endif %}
</span>
</div>
{% endfor %}
</div>
{% endif %}
{% endif %}
{% endifequal %}
{% endfor %}
</div>
<div class="col-md-1 content"></div>
</h4>
</div>
</div>
{% endfor %}
{% endfor %}
{% endif %}
<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 <a href="https://gogs.iscpif.fr/humanities/faq_gargantext/wiki/FAQ#import--export-a-dataset">
<span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span>
</a>
</h3>
</div>
<div class="modal-body">
<!-- FAQ -->
<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">
<span class="glyphicon glyphicon-remove" aria-hidden="true" ></span>
Close
</button>
<button onclick='bringDaNoise();' id="submit_thing" disabled class="btn btn-primary" >
<span class="glyphicon glyphicon-ok" aria-hidden="true" ></span>
Process this!
</button><span id="simpleloader"></span>
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal -->
<div id="wait" class="modal fade">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h2 class="modal-title"><h2><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>Building corpus...</h2>
</div>
<div class="modal-body">
<h5>
Gargantext is gathering your texts
and need some time to eat it.
Duration depends on the size of the dish.
</h5>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Continue on Gargantext</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
This diff is collapsed.
This diff is collapsed.
{% extends "pages/menu.html" %}
{% block css %}
{% load staticfiles %}
<link rel="stylesheet" href="{% static "lib/bootstrap/3.0.2/bootstrap.css" %}">
<script type="text/javascript" src="{% static "lib/jquery/1.11.1/jquery.min.js" %}"></script>
<script type="text/javascript" src="{% static "lib/gargantext/garganrest.js" %}"></script>
<link rel="stylesheet" href="{% static "lib/jquery/1.11.2/jquery-ui.css" %}">
<script type="text/javascript" src="{% static "lib/morris/morris.min.js" %}"></script>
<link rel="stylesheet" href="{% static "lib/morris/morris.css" %}">
<script src="{% static "lib/raphael/raphael-min.js"%}"></script>
<style type="text/css">
.ui-autocomplete {
z-index: 5000;
}
.ui-autocomplete .ui-menu-item {
font-size:x-small;
}
/* for wait gif in buttons */
.wait-img-active {
margin-left: .5em;
}
/* hover red like btn_danger */
.btn.delete:hover {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
</style>
{% endblock %}
{% block content %}
<div class="container theme-showcase" role="main">
<div class="jumbotron">
<div class="row">
<div class="col-md-4">
<h1>
<span class="glyphicon glyphicon-home" aria-hidden="true"></span>
Projects
</h1>
</div>
<div class="col-md-3"></div>
<div class="col-md-5">
<p id="project" class="help">
<br>
<button id="add" type="button" class="btn btn-primary btn-lg help" data-container="body" data-toggle="popover" data-placement="bottom">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add a new project
</button>
<div id="popover-content" class="hide">
<form>
<div id="createForm" class="form-group">
{% csrf_token %}
<div id="status-form" class="collapse"></div>
<div class="row inline">
<label class="col-lg-3" for="inputName" ><span class="pull-right">Name:</span></label>
<input class="col-lg-8" type="text" id="inputName" class="form-control">
</div>
<div class="row inline">
<div class="col-lg-3"></div>
<button id="createProject" class="btn btn-primary btn-sm col-lg-8 push-left">Add Project</button>
<div class="col-lg-2"></div>
</div>
</div>
</form>
</div>
</p>
</div>
</div>
</div>
<div class="container">
<!-- GENERIC STATUS INFO -->
<div id="status" class="row col-lg-12 collapse">
<div id="status-msg" class="alert">
</div>
</div>
<!-- CHECKBOX EDITION -->
<!--
<div class="row collapse" id="editor">
<button title="delete selected project" type="button" class="btn btn-danger" id="delete">
<span class="glyphicon glyphicon-trash " aria-hidden="true" ></span>
</button>
<button title="edit selected project" type="button" class="btn btn-warning" id="edit">
<span class="glyphicon glyphicon-pencil " aria-hidden="true" onclick="editProjects()"></span>
</button> -->
<!-- <button type="button" class="btn btn-info" id="recalculate">
<span class="glyphicon glyphicon-refresh " aria-hidden="true" onclick="recalculateProjects()"></span>
</button>
</div>
-->
<br />
<div class="row container" id="projects">
<!--here loading projectlist from GET /projects-->
</div>
<img id="wait-img" width="90%" style="display:none" src="{% static "img/ajax-loader.gif"%}"></img>
<script type="html/tpl" id="project_item">
<div id="{url}" class="item row">
<h3>
<div class="col-md-6 content">
<!--
<input type="checkbox" value="{url}" data-id="{id}">
-->
<a href="{url}">
<span class="glyphicon glyphicon-book" aria-hidden="true"></span>
<span class="item_name">{name}</span>
</a>
</div>
</h3>
<div id="project_detail" class="col-md-4 content">
<div id="item-editor">
<!-- DELETE PROJECT -->
<button type="button" class="btn btn-default delete pull-right" data-url="{url}" >
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
<!-- EDIT PROJECT-->
<button class="btn btn-default edit pull-right" data-id="{id}" data-url="{url}" data-toggle="collapse">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</button>
<!-- REFRESH PROJECT -->
<!--
<button type="button" class="btn btn-default refresh pull-right" data-id="{id}">
<span class="glyphicon glyphicon-refresh pull-right" aria-hidden="true"></span>
</button>
-->
<!-- GET Project -->
<a href="{url}">
<button type="button" title="see project" class="btn btn-default show pull-right" aria-label="Left Align">
<span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
</button>
</a>
</div>
<div id="project_status">
<!-- Here add nb of the corpus? -->
</div>
</div>
</div>
<div id="editForm-{id}" class="collapse ">
<!-- status of the form -->
<div id="status-form" class="collapse"></div>
<b>Name:</b><input type="text" id="name-{id}" />
<button id="edit-submit-{id}" class="btn btn-success btn-sm"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
<button id="edit-cancel-{id}" class="btn btn-danger btn-sm" ><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
</div>
</script>
<style type="text/css">
label {
padding:10px;
margin:0 0 10px;
display:block;
}
label:hover {
background:#eee;
cursor:pointer;
}
</style>
<script type="text/javascript" src="{% static "lib/gargantext/garganrest_projects.js" %}"></script>
<!-- <script type="text/javascript" src="{% static "lib/gargantext/help.js" %}"></script> -->
<script type="text/javascript">
getProjects();
// $(document).on("input#inoutName").bind('keypress', function(e) {
// if(e.keyCode==13){
// $('#createProject').trigger('click');
// }
// });
$(document).on("click","#createProject", function(e){
//alert("clicked");
//
//resetStatusForm("#createForm");
//$('input#inputName').val("");
createProject();
$('#add').on('hidden.bs.popover', function () {
// do something…
resetStatusForm("#createForm");
})
return false;
})
</script>
{% endblock %}
This diff is collapsed.
{% for state in corpus.hyperdata.statuses %}
{% ifequal state.action "Workflow" %}
{% if state.complete %}
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
{% else %}
{% if state.error %}
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
{{ state.error }}
{% else %}
<div class="progress">
{% for state in corpus.hyperdata.statuses %}
{% if state.action != "Workflow" %}
<div class=" progress-bar progress-bar-striped
{% if state.complete %}
progress-bar-success
{% else %}
active
{% endif %}
"
role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 25%">
<span>
{{ state.action }}
{% if state.complete %}
Ok
{% else %}
Processing
{% endif %}
</span>
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endif %}
{% endifequal %}
{% endfor %}
function manageStatus(statuses){
status_bar = ""
status_bar += '<div class="progress">'
statuses.forEach(function (status){
if (status["action"] == "Workflow"){
if (status["complete"]){
status_bar += '<span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div>'
return status_bar;
};
else if (status["error"]) {
status_bar += '<span class="glyphicon glyphicon-exclamation-sign pull-right" aria-hidden="true"></span></div>'
return status_bar;
};
else{
};
};
else{
status_bar +='<div class=" progress-bar progress-bar-striped'
if (status["complete"]){
status_bar +='progress-bar-sucess'
};
else{
status_bar +='active'
};
status_bar+= '" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 25%"> <span>'
if (status["action"]){
if (status["complete"]){
status_bar+= " OK </span></div>"
};
else{
status_bar+= " Processing </span>"
};
}
});
}
}
})
status_bar+="</div>"
return status_bar
};
console.log(errors)
errors.forEach(function(err) {
div = err[0].split(" ")
logs = []
logs.push(div[0])
if (err[1] == false)
{
alert(div[0])
//$(div[0]).parent().addClass("alert danger error");
$(div[0]).next(div[1]).collapse("show");
//$(div[0]).find(div[1]).collapse("show")
}
else
{
$("<span class='glyphicon glyphicon-ok' aria-hidden='true'>").appendTo(div[0])
}
});
return errors
};
function checkInput(source){
if (source.val().length > 0){
return true
}
else {
return false
}
}
function checkSourceFormat(){
source = $("select#source").find(':selected')
if (source.val() != '') {
console.log(source)
source_data = source.data("format")
alert(source_data)
formats = source_data.split(',');
alert(formats);
extension = $("#file").val().substr( (filename.lastIndexOf('.') +1) );
if ($.inArray(extension, formats) == -1){
//$("span.format").collapse("show");
return false;
}
else{
//$("span.format").collapse("hide");
return true;
}
}
return true
}
function checkFileSize(filesize, max_size){
if (filesize > max_size){
return true
}
else{
return false
}
};
//ADD CORPUS FORM
// //source
// $('#source').change(function() {
// $("#source").next("span.required").collapse("hide");
// source_type = $('#source').find(":selected");
// var formats = source_type.data("format").split(',');
// if (formats.length == 0){
// $("#source").next("span.required").collapse("show");
//
// }
// else{
// $("#source").next("span.required").collapse("hide");
// }
// });
// //file
// var max_size = parseInt($('#file').data("max-size"));
// $('#file').change(function() {
// var filesize = parseInt(this.files[0].size);
// if( filesize > max_size){
// alert("Upload file can't exceed 1 Mo because Gargantext would have an indigestion. Consult the special diet of Gargantext in our FAQ")
// $("#file").empty();
// };
// });
//
//
// });
$("#create").bind("click",function(){
var method = $('#radioBtn').find('a.active').data("title");
errors = checkForm()
if (has_error == "true"){
alert("Invalid Form");
}
else{
alert("OK")
//if (checkFileExtension() == true){
//preparePost(method, form)
//}
}
});
/////////////////FORM VALIDATION
function checkFilename(filename){
if (filename == ""){
$("#filename").next("span.required").collapse("show");
return false;
}
else{
$("#file").next("span.required").collapse("hide");
return true;
}
};
function checkFileSize(filesize, max_size){
if (filesize > max_size){
$("span.size").collapse("show");
}
else{
$("span.size").collapse("hide");
}
};
function checkFileExtension(){
filename = $('#file').val()
source_type = $('#source').find(":selected");
if (filename != "" && source_type.val() !== "0"){
fextension = filename.substr( (filename.lastIndexOf('.') +1) );
var formats = source_type.data("format").split(',');
if ($.inArray(extension, formats) == -1){
$("span.format").collapse("show");
return false;
}
else{
$("span.format").collapse("hide");
return true;
}
}
};
//name
$("span.error").collapse("hide");
$('#name').on('input', function() {
var input=$(this);
var is_name=input.val();
if ( is_name.length < 0){
$("#name").next("span.required").collapse("show");
$("form-group#name").addClass("error");
}
else {
$("#name").next("span").collapse("hide");
}
});
//source
$('#source').change(function() {
$("#source").next("span.required").collapse("hide");
source_type = $('#source').find(":selected");
var formats = source_type.data("format").split(',');
if (formats.length == 0){
$("#source").next("span.required").collapse("show");
}
else{
$("#source").next("span.required").collapse("hide");
}
});
//file
var max_size = parseInt($('#file').data("max-size"));
$('#file').change(function() {
$('#name span').collapse("hide");
var input=$(this);
var filename= input.val()
var filesize = parseInt(this.files[0].size);
checkFileSize(filesize, max_size);
});
//console.log("ERRORS?,)
$("#create").bind("click",function(){
var method = $('#radioBtn').find('a.active').data("title");
has_error = $("span.error").hasClass("collapse in");
if (has_error == "true"){
alert("Invalid Form");
}
else{
if (checkFileExtension() == true){
//preparePost(method, form)
}
}
});
This diff is collapsed.
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