Commit 5b50e991 authored by delanoe's avatar delanoe

[FIX] Merge fix.

parents cbdf65d5 d8908ff2
...@@ -32,7 +32,10 @@ ...@@ -32,7 +32,10 @@
}, },
function(data) { function(data) {
$rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()]; $rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()];
// eg id => 'MAPLIST'
$rootScope.lists = data[$rootScope.corpusId.toString()].lists; $rootScope.lists = data[$rootScope.corpusId.toString()].lists;
// inverted 'MAPLIST' => id
$rootScope.listIds = _.invert($rootScope.lists)
$scope.dataLoading = false ; $scope.dataLoading = false ;
}, },
function(data) { function(data) {
......
(function () { (function () {
'use strict'; 'use strict';
var annotationsAppHighlight = angular.module('annotationsAppHighlight', ['annotationsAppHttp']); var annotationsAppHighlight = angular.module('annotationsAppHighlight', ['annotationsAppHttp', 'annotationsAppUtils']);
/* /*
* Controls the mouse selection on the text * Controls the mouse selection on the text
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
// grand parent should be the rootscope // grand parent should be the rootscope
//console.log($scope.$parent.$parent.$id) //console.log($scope.$parent.$parent.$id)
// (prepared once, after highlight) // (prepared once, after highlight)
// (then used when onClick event) // (then used when onClick event)
// retrieve corresponding ngram using element attr uuid in <span uuid="42"> // retrieve corresponding ngram using element attr uuid in <span uuid="42">
...@@ -45,8 +44,8 @@ ...@@ -45,8 +44,8 @@
* Controls the menu over the current mouse selection * Controls the menu over the current mouse selection
*/ */
annotationsAppHighlight.controller('TextSelectionMenuController', annotationsAppHighlight.controller('TextSelectionMenuController',
['$scope', '$rootScope', '$element', '$timeout', 'NgramHttpService', 'NgramListHttpService', ['$scope', '$rootScope', '$element', '$timeout', 'MainApiChangeNgramHttpService', 'NgramListHttpService',
function ($scope, $rootScope, $element, $timeout, NgramHttpService, NgramListHttpService) { function ($scope, $rootScope, $element, $timeout, MainApiChangeNgramHttpService, NgramListHttpService) {
/* /*
* Universal text selection * Universal text selection
*/ */
...@@ -82,14 +81,14 @@ ...@@ -82,14 +81,14 @@
/* /*
* Dynamically construct the selection menu scope * Dynamically construct the selection menu scope
* (actions are then interpreted in onMenuClick)
*/ */
function toggleMenu(context, annotation) { function toggleMenu(context, annotation) {
$timeout(function() { $timeout(function() {
$scope.$apply(function() { $scope.$apply(function() {
// £TODO check var mainlist_id = $rootScope.listIds.MAINLIST;
var miamlist_id = _.invert($rootScope.lists).MAINLIST; var stoplist_id = $rootScope.listIds.STOPLIST;
var stoplist_id = _.invert($rootScope.lists).STOPLIST; var maplist_id = $rootScope.listIds.MAPLIST;
var maplist_id = _.invert($rootScope.lists).MAPLIST;
// if called from highlighted span // if called from highlighted span
// - annotation has full {ngram} // - annotation has full {ngram}
...@@ -105,28 +104,19 @@ ...@@ -105,28 +104,19 @@
// debug // debug
// console.log("toggleMenu with \$scope.selection_text: '" + JSON.stringify($scope.selection_text) +"'") ; // console.log("toggleMenu with \$scope.selection_text: '" + JSON.stringify($scope.selection_text) +"'") ;
if (angular.isObject(annotation) && !$element.hasClass('menu-is-opened')) { if (angular.isObject(annotation) && !$element.hasClass('menu-is-opened')) {
// existing ngram // existing ngram
console.log("toggleMenu.annotation: '" + JSON.stringify(annotation) +"'") // Context menu proposes 2 things for each item of list A
// Delete from the current list
$scope.menuItems = [
{
'action': 'delete',
'listId': annotation.list_id,
'verb': 'Delete from',
'listName': $rootScope.lists[annotation.list_id]
}
];
// Context menu proposes 3 things for each item of list A
// - deletion from A
// - adding/moving to other lists B or C // - adding/moving to other lists B or C
// Because of logical dependencies b/w lists, these
// menu actions will also trigger todo_other_actions // ---------------------------------------------------------------
// cf. forge.iscpif.fr/projects/garg/wiki/Ngram_Lists // Because of logical dependencies b/w lists, user choices are "intentions"
// the real CRUDs actions are deduced from intentions as a list...
// * (see forge.iscpif.fr/projects/garg/wiki/Ngram_Lists)
// * (see also InferCRUDFlags in lib/NGrams_dyna_chart_and_table)
// ---------------------------------------------------------------
// TODO disambiguate annotation.list_id for highlighted MapList items // TODO disambiguate annotation.list_id for highlighted MapList items
// ------------------------------------------------------------- // -------------------------------------------------------------
...@@ -136,39 +126,81 @@ ...@@ -136,39 +126,81 @@
// otherwise the "if" here will propose MiamList's options // otherwise the "if" here will propose MiamList's options
if ($rootScope.lists[annotation.list_id] == "MAPLIST") { if ($rootScope.lists[annotation.list_id] == "MAPLIST") {
// Add to the other lists
$scope.menuItems.push({ $scope.menuItems.push({
'action': 'post', // "tgtListName" is just used to render the GUI explanation
'listId': stoplist_id, 'tgtListName': 'STOPLIST',
'verb': 'Move to', // crudActions is an array of rest/DB actions
'listName': $rootScope.lists[stoplist_id] // (consequences of the intention)
'crudActions':[
["delete", maplist_id],
["delete", mainlist_id],
["put", stoplist_id]
]
}); });
} else if ($rootScope.lists[annotation.list_id] == "STOPLIST") {
// Add to the alternative list
$scope.menuItems.push({ $scope.menuItems.push({
'action': 'post', 'tgtListName': 'MAINLIST',
'listId': miamlist_id, 'crudActions':[
'verb': 'Move to', ["delete", maplist_id]
'listName': $rootScope.lists[miamlist_id] ]
}); });
} }
else if ($rootScope.lists[annotation.list_id] == "MAINLIST") {
$scope.menuItems.push({
'tgtListName': "STOPLIST",
'crudActions':[
["delete", mainlist_id],
["put", stoplist_id]
]
});
$scope.menuItems.push({
'tgtListName': "MAPLIST",
'crudActions':[
["put", maplist_id]
]
});
}
else if ($rootScope.lists[annotation.list_id] == "STOPLIST") {
$scope.menuItems.push({
'tgtListName': "MAINLIST",
'crudActions':[
["delete", stoplist_id],
["put", mainlist_id]
]
});
$scope.menuItems.push({
'tgtListName': "MAPLIST",
'crudActions':[
["delete", stoplist_id],
["put", mainlist_id],
["put", maplist_id]
]
});
}
// show the menu // show the menu
$element.fadeIn(100); $element.fadeIn(100);
$element.addClass('menu-is-opened'); $element.addClass('menu-is-opened');
} else if (annotation.trim() !== "" && !$element.hasClass('menu-is-opened')) { }
// new ngram
$scope.menuItems = [ // -------8<------ "add" actions for non-existing ngram ------
{ // else if (annotation.trim() !== "" && !$element.hasClass('menu-is-opened')) {
'action': 'post', // // new ngram
'listId': miamlist_id, // $scope.menuItems = [
'verb': 'Add to', // {
'listName': $rootScope.lists[miamlist_id] // 'action': 'post',
} // 'listId': miamlist_id,
]; // 'verb': 'Add to',
// show the menu // 'listName': $rootScope.lists[miamlist_id]
$element.fadeIn(100); // }
$element.addClass('menu-is-opened'); // ];
} else { // // show the menu
// $element.fadeIn(100);
// $element.addClass('menu-is-opened');
// }
// -------8<--------------------------------------------------
else {
$scope.menuItems = []; $scope.menuItems = [];
// close the menu // close the menu
$element.fadeOut(100); $element.fadeOut(100);
...@@ -178,80 +210,6 @@ ...@@ -178,80 +210,6 @@
}); });
} }
// £TODO CHECK
// if ($rootScope.lists[annotation.list_id] == "MiamList") {
// // Add to the other lists
// $scope.menuItems.push({
// 'action': 'post',
// 'listId': maplist_id,
// // "Add" because copy into MapList
// 'verb': 'Add to',
// 'listName': $rootScope.lists[maplist_id]
// },
// {
// 'action': 'post',
// 'listId': stoplist_id,
// // "Move"
// // £dbg: TODO for instance pass conditional dependancy as info
// // 'todo_other_actions': 'remove from miam',
// 'verb': 'Move to',
// 'listName': $rootScope.lists[stoplist_id]
// });
// } else if ($rootScope.lists[annotation.list_id] == "StopList") {
// // Move from stop to the "positive" lists
// $scope.menuItems.push({
// 'action': 'post',
// 'listId': miamlist_id,
// // 'todo_other_actions': 'remove from stop',
// 'verb': 'Move to',
// 'listName': $rootScope.lists[miamlist_id]
// },
// {
// 'action': 'post',
// 'listId': maplist_id,
// // 'todo_other_actions': 'remove from stop, add to miam',
// 'verb': 'Move to',
// 'listName': $rootScope.lists[maplist_id]
// });
// } else if ($rootScope.lists[annotation.list_id] == "MapList") {
// // No need to add to miam, just possible to move to stop
// $scope.menuItems.push({
// 'action': 'post',
// 'listId': stoplist_id,
// // 'todo_other_actions': 'remove from miam and from map'
// 'verb': 'Move to',
// 'listName': $rootScope.lists[stoplist_id]
// });
// }
//
//
//
var pos = $(".text-panel").position(); var pos = $(".text-panel").position();
function positionElement(context, x, y) { function positionElement(context, x, y) {
...@@ -296,72 +254,115 @@ ...@@ -296,72 +254,115 @@
$rootScope.$on("positionAnnotationMenu", positionElement); $rootScope.$on("positionAnnotationMenu", positionElement);
$rootScope.$on("toggleAnnotationMenu", toggleMenu); $rootScope.$on("toggleAnnotationMenu", toggleMenu);
/* /*
* Menu click action * Menu click actions
* (1 intention => list of actions => MainApiChangeNgramHttpService CRUDs)
* post/delete
*/ */
$scope.onMenuClick = function($event, action, listId) { $scope.onMenuClick = function($event, crudActions) {
console.warn('in onMenuClick')
// TODO interpret context menu chosen actions console.warn('item.crudActions')
// as implicit API+DB actions console.warn(crudActions)
// ex: add to map (+ add to miam + delete from stop)
if (angular.isObject($scope.selection_text)) { if (angular.isObject($scope.selection_text)) {
console.log("requested action: " + action + "on scope.sel: '" + $scope.selection_text + "'")
var ngramId = $scope.selection_text.uuid
// action on an existing Ngram var ngramText = $scope.selection_text.text
NgramHttpService[action]({
'listId': listId, var lastCallback = function() {
'ngramId': $scope.selection_text.uuid // Refresh the annotationss
}, function(data) { NgramListHttpService.get(
// Refresh the annotationss {'corpusId': $rootScope.corpusId,
NgramListHttpService.get( 'docId': $rootScope.docId},
{ function(data) {
'corpusId': $rootScope.corpusId, $rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()];
'docId': $rootScope.docId $rootScope.refreshDisplay();
}, },
function(data) { function(data) {
$rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()]; console.error("unable to get the list of ngrams");
$rootScope.refreshDisplay(); }
}, );
function(data) {
console.error("unable to get the list of ngrams");
}
);
}, function(data) {
console.error("unable to edit the Ngram " + $scope.selection_text.text);
} }
);
// chained recursion to do several actions then callback (eg refresh)
} else if ($scope.selection_text.trim() !== "") { function makeChainedCalls (i, listOfActions, finalCallback) {
// new annotation from selection // each action couple has 2 elts
NgramHttpService.post( var action = listOfActions[i][0]
{ var listId = listOfActions[i][1]
'listId': listId,
'ngramId': 'create' console.log("===>"+action+"<===")
},
{ MainApiChangeNgramHttpService[action](
'text': $scope.selection_text.trim() {'listId': listId,
}, function(data) { 'ngramIdList': ngramId},
// Refresh the annotationss
NgramListHttpService.get( // on success
{ function(data) {
'corpusId': $rootScope.corpusId, // case NEXT
'docId': $rootScope.docId // ----
}, // when chained actions
function(data) { if (listOfActions.length > i+1) {
$rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()]; console.log("calling next action ("+(i+1)+")")
$rootScope.refreshDisplay();
}, // ==============================================
function(data) { makeChainedCalls(i+1, listOfActions, finalCallback)
console.error("unable to get the list of ngrams"); // ==============================================
}
}
// case LAST
// ------
// when last action
else {
finalCallback()
}
},
// on error
function(data) {
console.error("unable to edit the Ngram \""+ngramText+"\""
+"(ngramId "+ngramId+")"+"at crud no "+i
+" ("+action+" on list "+listId+")");
}
); );
}, function(data) {
console.error("unable to edit the Ngram " + $scope.selection_text);
} }
);
// run the loop by calling the initial recursion step
makeChainedCalls(0, crudActions, lastCallback)
} }
// hide the highlighted text the the menu
// TODO: first action creates then like previous case
// else if ($scope.selection_text.trim() !== "") {
// // new annotation from selection
// NgramHttpService.post(
// {
// 'listId': listId,
// 'ngramId': 'create'
// },
// {
// 'text': $scope.selection_text.trim()
// }, function(data) {
// // Refresh the annotationss
// NgramListHttpService.get(
// {
// 'corpusId': $rootScope.corpusId,
// 'docId': $rootScope.docId
// },
// function(data) {
// $rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()];
// $rootScope.refreshDisplay();
// },
// function(data) {
// console.error("unable to get the list of ngrams");
// }
// );
// }, function(data) {
// console.error("unable to edit the Ngram " + $scope.selection_text);
// }
// );
// }
// hide the highlighted text and the menu element
$(".text-panel").removeClass("selection"); $(".text-panel").removeClass("selection");
$element.fadeOut(100); $element.fadeOut(100);
}; };
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* route: annotations/documents/@d_id * route: annotations/documents/@d_id
* ------ * ------
* * TODO use external: api/nodes/@d_id?fields[]=hyperdata
* exemple: * exemple:
* -------- * --------
* { * {
...@@ -86,13 +86,19 @@ ...@@ -86,13 +86,19 @@
); );
}); });
/* /*
* NgramHttpService: Create, modify or delete 1 Ngram * NgramHttpService: Create, modify or delete 1 Ngram
* ================= * =================
* *
* TODO REACTIVATE IN urls.py * TODO add a create case separately and then remove service
*
* NB : replaced by external api: (MainApiChangeNgramHttpService)
* api/ngramlists/change?list=LISTID&ngrams=ID1,ID2..
* *
* if new ngram: * old logic:
* ----------
* if new ngram
* -> ngram_id will be "create" * -> ngram_id will be "create"
* -> route: annotations/lists/@node_id/ngrams/create * -> route: annotations/lists/@node_id/ngrams/create
* -> will land on views.NgramCreate * -> will land on views.NgramCreate
...@@ -100,24 +106,61 @@ ...@@ -100,24 +106,61 @@
* else: * else:
* -> ngram_id is a real ngram id * -> ngram_id is a real ngram id
* -> route: annotations/lists/@node_id/ngrams/@ngram_id * -> route: annotations/lists/@node_id/ngrams/@ngram_id
* -> will land on views.NgramCreate * -> will land on views.NgramEdit
*
*/
// http.factory('NgramHttpService', function ($resource) {
// return $resource(
// window.ANNOTATION_API_URL + 'lists/:listId/ngrams/:ngramId',
// {
// listId: '@listId',
// ngramId: '@id'
// },
// {
// post: {
// method: 'POST',
// params: {'listId': '@listId', 'ngramId': '@ngramId'}
// },
// delete: {
// method: 'DELETE',
// params: {'listId': '@listId', 'ngramId': '@ngramId'}
// }
// }
// );
// });
/*
* MainApiChangeNgramHttpService: Add/remove ngrams from lists
* =============================
* route: api/ngramlists/change?list=LISTID&ngrams=ID1,ID2...
*
* (same route used in ngrams table)
*
* /!\ for this route we reach out of this annotation module
* and send directly to the gargantext api route for list change
* (cross origin request with http protocol scheme)
* ------
* *
*/ */
http.factory('NgramHttpService', function ($resource) {
http.factory('MainApiChangeNgramHttpService', function($resource) {
return $resource( return $resource(
window.ANNOTATION_API_URL + 'lists/:listId/ngrams/:ngramId', // adding explicit "http://" b/c this a cross origin request
{ 'http://' + window.GARG_ROOT_URL
+ "/api/ngramlists/change?list=:listId&ngrams=:ngramIdList",
{
listId: '@listId', listId: '@listId',
ngramId: '@id' ngramIdList: '@ngramIdList' // list in str form (sep=","): "12,25,30"
// (usually in this app just 1 id): "12"
}, },
{ {
post: { put: {
method: 'POST', method: 'PUT',
params: {'listId': '@listId', 'ngramId': '@ngramId'} params: {listId: '@listId', ngramIdList: '@ngramIdList'}
}, },
delete: { delete: {
method: 'DELETE', method: 'DELETE',
params: {'listId': '@listId', 'ngramId': '@ngramId'} params: {listId: '@listId', ngramIdList: '@ngramIdList'}
} }
} }
); );
......
...@@ -7,39 +7,101 @@ ...@@ -7,39 +7,101 @@
* Controls one Ngram displayed in the flat lists (called "extra-text") * Controls one Ngram displayed in the flat lists (called "extra-text")
*/ */
annotationsAppNgramList.controller('NgramController', annotationsAppNgramList.controller('NgramController',
['$scope', '$rootScope', 'NgramHttpService', 'NgramListHttpService', ['$scope', '$rootScope', 'MainApiChangeNgramHttpService', 'NgramListHttpService',
function ($scope, $rootScope, NgramHttpService, NgramListHttpService) { function ($scope, $rootScope, MainApiChangeNgramHttpService, NgramListHttpService) {
/* /*
* Click on the 'delete' cross button * Click on the 'delete' cross button
* (NB: we have different delete consequences depending on list)
*/ */
$scope.onDeleteClick = function () { $scope.onDeleteClick = function () {
NgramHttpService.delete({ var listName = $scope.keyword.listName
'listId': $scope.keyword.list_id, var thisListId = $scope.keyword.list_id
'ngramId': $scope.keyword.uuid var thisNgramId = $scope.keyword.uuid
}, function(data) { var crudActions = [] ;
// Refresh the annotationss
NgramListHttpService.get( if (listName == 'MAPLIST') {
{ crudActions = [
'corpusId': $rootScope.corpusId, ["delete", thisListId]
'docId': $rootScope.docId ]
}, }
function(data) { else if (listName == 'MAINLIST') {
// $rootScope.annotations crudActions = [
// ---------------------- ["delete", thisListId],
// is the union of all lists, one being later "active" ["put", $rootScope.listIds.STOPLIST],
// (then used for left-side flatlist AND inline annots) ]
$rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()]; }
// TODO £NEW : lookup obj[list_id][term_text] = {terminfo} else if (listName == 'STOPLIST') {
// $rootScope.lookup = crudActions = [
$rootScope.refreshDisplay(); ["delete", thisListId],
}, ["put", $rootScope.listIds.MAINLIST],
function(data) { ]
console.error("unable to refresh the list of ngrams"); }
}
); // using recursion to make chained calls,
}, function(data) { // todo factorize with highlight.js
console.error("unable to remove the Ngram " + $scope.keyword.text);
}); var lastCallback = function() {
// Refresh the annotationss
NgramListHttpService.get(
{'corpusId': $rootScope.corpusId,
'docId': $rootScope.docId},
function(data) {
// $rootScope.annotations
// ----------------------
// is the union of all lists, one being later "active"
// (then used for left-side flatlist AND inline annots)
$rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()];
// TODO £NEW : lookup obj[list_id][term_text] = {terminfo}
// $rootScope.lookup =
$rootScope.refreshDisplay();
},
function(data) {
console.error("unable to refresh the list of ngrams");
}
);
}
// chained recursion to do several actions then callback (eg refresh)
function makeChainedCalls (i, listOfActions, finalCallback) {
// each action couple has 2 elts
var action = listOfActions[i][0]
var listId = listOfActions[i][1]
MainApiChangeNgramHttpService[action](
{'listId': thisListId,
'ngramIdList': thisNgramId},
// on success
function(data) {
// case NEXT
// ----
// when chained actions
if (listOfActions.length > i+1) {
console.log("calling next action ("+(i+1)+")")
// ==============================================
makeChainedCalls(i+1, listOfActions, finalCallback)
// ==============================================
}
// case LAST
// ------
// when last action
else {
finalCallback()
}
},
// on error
function(data) {
console.error("unable to edit the Ngram \""+ngramText+"\""
+"(ngramId "+ngramId+")"+"at crud no "+i
+" ("+action+" on list "+listId+")");
}
);
}
// run the loop by calling the initial recursion step
makeChainedCalls(0, crudActions, lastCallback)
}; };
}]); }]);
...@@ -82,8 +144,8 @@ ...@@ -82,8 +144,8 @@
* new NGram from the user input * new NGram from the user input
*/ */
annotationsAppNgramList.controller('NgramInputController', annotationsAppNgramList.controller('NgramInputController',
['$scope', '$rootScope', '$element', 'NgramHttpService', 'NgramListHttpService', ['$scope', '$rootScope', '$element', 'NgramListHttpService',
function ($scope, $rootScope, $element, NgramHttpService, NgramListHttpService) { function ($scope, $rootScope, $element, NgramListHttpService) {
/* /*
* Add a new NGram from the user input in the extra-text list * Add a new NGram from the user input in the extra-text list
*/ */
...@@ -114,46 +176,47 @@ ...@@ -114,46 +176,47 @@
// --------------------------------------------------------------- // ---------------------------------------------------------------
// will check if there's a preexisting ngramId for this value // will check if there's a preexisting ngramId for this value
// TODO: reconnect separately from list addition
// TODO: if maplist => also add to miam // TODO: if maplist => also add to miam
NgramHttpService.post( // NgramHttpService.post(
{ // {
'listId': listId, // 'listId': listId,
'ngramId': 'create' // 'ngramId': 'create'
}, // },
{ // {
'text': value // 'text': value
}, // },
function(data) { // function(data) {
console.warn("refresh attempt"); // console.warn("refresh attempt");
// on success // // on success
if (data) { // if (data) {
angular.element(inputEltId).val(""); // angular.element(inputEltId).val("");
// Refresh the annotationss // // Refresh the annotationss
NgramListHttpService.get( // NgramListHttpService.get(
{ // {
'corpusId': $rootScope.corpusId, // 'corpusId': $rootScope.corpusId,
'docId': $rootScope.docId // 'docId': $rootScope.docId
}, // },
function(data) { // function(data) {
$rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()]; // $rootScope.annotations = data[$rootScope.corpusId.toString()][$rootScope.docId.toString()];
//
// TODO £NEW : lookup obj[list_id][term_text] = {terminfo} // // TODO £NEW : lookup obj[list_id][term_text] = {terminfo}
// $rootScope.lookup = // // $rootScope.lookup =
//
//
$rootScope.refreshDisplay(); // $rootScope.refreshDisplay();
}, // },
function(data) { // function(data) {
console.error("unable to get the list of ngrams"); // console.error("unable to get the list of ngrams");
} // }
); // );
} // }
}, function(data) { // }, function(data) {
// on error // // on error
angular.element(inputEltId).parent().addClass("has-error"); // angular.element(inputEltId).parent().addClass("has-error");
console.error("error adding Ngram "+ value); // console.error("error adding Ngram "+ value);
} // }
); // );
}; };
}]); }]);
......
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
<!-- this menu is over the text on mouse selection --> <!-- this menu is over the text on mouse selection -->
<div ng-controller="TextSelectionMenuController" id="selection" class="selection-menu"> <div ng-controller="TextSelectionMenuController" id="selection" class="selection-menu">
<ul class="noselection"> <ul class="noselection">
<li ng-repeat="item in menuItems" class="{[{item.listName}]}" ng-click="onMenuClick($event, item.action, item.listId)">{[{item.verb}]} {[{item.listName}]}</li> <li ng-repeat="item in menuItems" class="{[{item.tgtListName}]}" ng-click="onMenuClick($event, item.crudActions)">Move to {[{item.tgtListName}]}</li>
</ul> </ul>
</div> </div>
</div> </div>
......
...@@ -13,13 +13,10 @@ urlpatterns = [ ...@@ -13,13 +13,10 @@ urlpatterns = [
url(r'^documents/(?P<doc_id>[0-9]+)$', views.Document.as_view()), # document view url(r'^documents/(?P<doc_id>[0-9]+)$', views.Document.as_view()), # document view
# GET [NgramListHttpService] # GET [NgramListHttpService]
# was : lists ∩ document (ngram_ids intersection if connected to list node_id and doc node_id) # ngrams from {lists ∩ document}
# fixed 2016-01: just lists (because document doesn't get updated by POST create cf. ngram.lists.DocNgram filter commented)
url(r'^corpora/(?P<corpus_id>[0-9]+)/documents/(?P<doc_id>[0-9]+)$', views.NgramList.as_view()), # the list associated with an ngram url(r'^corpora/(?P<corpus_id>[0-9]+)/documents/(?P<doc_id>[0-9]+)$', views.NgramList.as_view()), # the list associated with an ngram
# 2016-03-24: refactoring, deactivated NgramEdit and NgramCreate # 2016-03-24: refactoring, deactivated NgramEdit and NgramCreate
# # 2016-05-27: removed NgramEdit: replaced the local httpservice by api/ngramlists
# url(r'^lists/(?P<list_id>[0-9]+)/ngrams/(?P<ngram_ids>[0-9,\+]+)+$', views.NgramEdit.as_view()),
# POST (fixed 2015-12-16)
# url(r'^lists/(?P<list_id>[0-9]+)/ngrams/create$', views.NgramCreate.as_view()), # # url(r'^lists/(?P<list_id>[0-9]+)/ngrams/create$', views.NgramCreate.as_view()), #
] ]
...@@ -93,79 +93,8 @@ class NgramList(APIView): ...@@ -93,79 +93,8 @@ class NgramList(APIView):
# 2016-03-24: refactoring, deactivated NgramEdit and NgramCreate # 2016-03-24: refactoring, deactivated NgramEdit and NgramCreate
# 2016-05-27: removed NgramEdit: replaced the local httpservice by api/ngramlists
# ------------------------------------ # ------------------------------------
# class NgramEdit(APIView):
# """
# Actions on one existing Ngram in one list
# """
# renderer_classes = (JSONRenderer,)
# authentication_classes = (SessionAuthentication, BasicAuthentication)
#
# def post(self, request, list_id, ngram_ids):
# """
# Edit an existing NGram in a given list
# """
# # implicit global session
# list_id = int(list_id)
# list_node = session.query(Node).filter(Node.id==list_id).first()
# # TODO add 1 for MapList social score ?
# if list_node.type_id == cache.NodeType['MiamList']:
# weight=1.0
# elif list_node.type_id == cache.NodeType['StopList']:
# weight=-1.0
#
# # TODO remove the node_ngram from another conflicting list
# for ngram_id in ngram_ids.split('+'):
# ngram_id = int(ngram_id)
# node_ngram = NodeNgram(node_id=list_id, ngram_id=ngram_id, weight=weight)
# session.add(node_ngram)
#
# session.commit()
#
# # return the response
# return Response({
# 'uuid': ngram_id,
# 'list_id': list_id,
# } for ngram_id in ngram_ids)
#
# def put(self, request, list_id, ngram_ids):
# return Response(None, 204)
#
# def delete(self, request, list_id, ngram_ids):
# """
# Delete a ngram from a list
# """
# # implicit global session
# print("to del",ngram_ids)
# for ngram_id in ngram_ids.split('+'):
# print('ngram_id', ngram_id)
# ngram_id = int(ngram_id)
# (session.query(NodeNgram)
# .filter(NodeNgram.node_id==list_id)
# .filter(NodeNgram.ngram_id==ngram_id).delete()
# )
#
# session.commit()
#
# # [ = = = = del from map-list = = = = ]
# list_id = session.query(Node).filter(Node.id==list_id).first()
# corpus = session.query(Node).filter(Node.id==list_id.parent_id , Node.type_id==cache.NodeType['Corpus'].id).first()
# node_mapList = get_or_create_node(nodetype='MapList', corpus=corpus )
# results = session.query(NodeNgram).filter(NodeNgram.node_id==node_mapList.id ).all()
# ngram_2del = [int(i) for i in ngram_ids.split('+')]
# ngram_2del_ = session.query(NodeNgram).filter(NodeNgram.node_id==node_mapList.id , NodeNgram.ngram_id.in_(ngram_2del) ).all()
# for map_node in ngram_2del_:
# session.delete(map_node)
# session.commit()
#
# node_stopList = get_or_create_node(nodetype='StopList', corpus=corpus )
# for ngram_id in ngram_2del:
# stop_node = NodeNgram( weight=1.0, ngram_id=ngram_id , node_id=node_stopList.id)
# session.add(stop_node)
# session.commit()
# # [ = = = = / del from map-list = = = = ]
#
# return Response(None, 204)
# #
# class NgramCreate(APIView): # class NgramCreate(APIView):
# """ # """
......
List of garg's own JSON API(s) urls
===================================
2016-05-27
### /api/nodes/2
```
{
"id": 2,
"parent_id": 1,
"name": "abstract:\"evaporation+loss\"",
"typename": "CORPUS"
}
```
------------------------------
### /api/nodes?pagination_limit=-1
```
{
"records": [
{
"id": 9,
"parent_id": 2,
"name": "A recording evaporimeter",
"typename": "DOCUMENT"
},
(...)
{
"id": 119,
"parent_id": 81,
"name": "GRAPH EXPLORER COOC (in:81)",
"typename": "COOCCURRENCES"
}
],
"count": 119,
"parameters": {
"formated": "json","pagination_limit": -1,
"fields": ["id","parent_id","name","typename"],
"pagination_offset": 0
}
}
```
------------------------------
### /api/nodes?types[]=CORPUS
```
{
"records": [
{
"id": 2,
"parent_id": 1,
"name": "abstract:\"evaporation+loss\"",
"typename": "CORPUS"
},
(...)
{
"id": 8181,
"parent_id": 1,
"name": "abstract:(astrogeology+OR ((space OR spatial) AND planetary) AND geology)",
"typename": "CORPUS"
}
],
"count": 2,
"parameters": {
"pagination_limit": 10,
"types": ["CORPUS"],
"formated": "json",
"pagination_offset": 0,
"fields": ["id","parent_id","name","typename"]
}
}
```
------------------------------
### /api/nodes/5?fields[]=ngrams
<5> représente un doc_id ou list_id
```
{
"ngrams": [
[1.0,{"id":2299,"n":1,"terms":designs}],
[1.0,{"id":1917,"n":1,"terms":height}],
[1.0,{"id":1755,"n":2,"terms":higher speeds}],
[1.0,{"id":1940,"n":1,"terms":cylinders}],
[1.0,{"id":2221,"n":3,"terms":other synthesized materials}],
(...)
[2.0,{"id":1970,"n":1,"terms":storms}],
[9.0,{"id":1754,"n":2,"terms":spherical gauges}],
[1.0,{"id":1895,"n":1,"terms":direction}],
[1.0,{"id":2032,"n":1,"terms":testing}],
[1.0,{"id":1981,"n":2,"terms":"wind effects"}]
]
}
```
------------------------------
### api/nodes/3?fields[]=id&fields[]=hyperdata&fields[]=typename
```
{
"id": 3,
"typename": "DOCUMENT",
"hyperdata": {
"language_name": "English",
"language_iso3": "eng",
"language_iso2": "en",
"title": "A blabla analysis of laser treated aluminium blablabla",
"name": "A blabla analysis of laser treated aluminium blablabla",
"authors": "A K. Jain, V.N. Kulkarni, D.K. Sood"
"authorsRAW": [
{"name": "....", "affiliations": ["... Research Centre,.. 085, Country"]},
{"name": "....", "affiliations": ["... Research Centre,.. 086, Country"]}
(...)
],
"abstract": "Laser processing of materials, being a rapid melt quenching process, quite often produces a surface which is far from being ideally smooth for ion beam analysis. (...)",
"genre": ["research-article"],
"doi": "10.1016/0029-554X(81)90998-8",
"journal": "Nuclear Instruments and Methods In Physics Research",
"publication_year": "1981",
"publication_date": "1981-01-01 00:00:00",
"publication_month": "01",
"publication_day": "01",
"publication_hour": "00",
"publication_minute": "00",
"publication_second": "00",
"id": "61076EB1178A97939B1C893904C77FB7DA2276D0",
"source": "elsevier",
"distributor": "istex"
}
}
```
## TODO continuer la liste
...@@ -7,7 +7,7 @@ from django import forms ...@@ -7,7 +7,7 @@ from django import forms
from urllib.parse import quote_plus as urlencode from urllib.parse import quote_plus as urlencode
from gargantext import settings from gargantext import settings
from sqlalchemy.orm.exc import DetachedInstanceError
# authentication # authentication
...@@ -19,7 +19,20 @@ def requires_auth(func): ...@@ -19,7 +19,20 @@ def requires_auth(func):
if not request.user.is_authenticated(): if not request.user.is_authenticated():
url = '/auth/login/?next=%s' % urlencode(request.path) url = '/auth/login/?next=%s' % urlencode(request.path)
return redirect(url) return redirect(url)
return func(request, *args, **kwargs) try:
# normal return the subfunction when user ok
return func(request, *args, **kwargs)
except DetachedInstanceError as die:
print("===\n" * 10)
print(die)
print("===\n" * 10)
# user was authenticated but something made it expire (session.commit ?)
session.rollback()
# and relogin for safety
url = '/auth/login/?next=%s' % urlencode(request.path)
return redirect(url)
return _requires_auth return _requires_auth
......
...@@ -228,7 +228,7 @@ class NodeNgramsQueries(APIView): ...@@ -228,7 +228,7 @@ class NodeNgramsQueries(APIView):
# build result: prepare data # build result: prepare data
date_value_list = query_result.all() date_value_list = query_result.all()
#print(date_value_list) #print(date_value_list)
if date_value_list: if date_value_list:
date_min = date_value_list[0][0].replace(tzinfo=None) date_min = date_value_list[0][0].replace(tzinfo=None)
date_max = date_value_list[-2][0].replace(tzinfo=None) date_max = date_value_list[-2][0].replace(tzinfo=None)
...@@ -265,8 +265,10 @@ class NodeNgramsQueries(APIView): ...@@ -265,8 +265,10 @@ class NodeNgramsQueries(APIView):
return CsvHttpResponse(sorted(result.items()), ('date', 'value'), 201) return CsvHttpResponse(sorted(result.items()), ('date', 'value'), 201)
# ?? TODO put in an ngrams.py file separately ?
class ApiNgrams(APIView): class ApiNgrams(APIView):
def get(self, request): def get(self, request):
# parameters retrieval and validation # parameters retrieval and validation
...@@ -275,10 +277,10 @@ class ApiNgrams(APIView): ...@@ -275,10 +277,10 @@ class ApiNgrams(APIView):
# query ngrams # query ngrams
ParentNode = aliased(Node) ParentNode = aliased(Node)
ngrams_query = (session ngrams_query = (session
.query(Ngram.terms, func.sum(NodeNgram.weight).label('count')) .query(Ngram.id, Ngram.terms, func.sum(NodeNgram.weight).label('count'))
.join(NodeNgram, NodeNgram.ngram_id == Ngram.id) .join(NodeNgram, NodeNgram.ngram_id == Ngram.id)
.join(Node, Node.id == NodeNgram.node_id) .join(Node, Node.id == NodeNgram.node_id)
.group_by(Ngram.terms) .group_by(Ngram.id, Ngram.terms)
# .group_by(Ngram) # .group_by(Ngram)
.order_by(func.sum(NodeNgram.weight).desc(), Ngram.terms) .order_by(func.sum(NodeNgram.weight).desc(), Ngram.terms)
) )
...@@ -287,11 +289,17 @@ class ApiNgrams(APIView): ...@@ -287,11 +289,17 @@ class ApiNgrams(APIView):
if 'startwith' in request.GET: if 'startwith' in request.GET:
ngrams_query = ngrams_query.filter(Ngram.terms.startswith(request.GET['startwith'])) ngrams_query = ngrams_query.filter(Ngram.terms.startswith(request.GET['startwith']))
if 'contain' in request.GET: if 'contain' in request.GET:
print("request.GET['contain']")
print(request.GET['contain'])
ngrams_query = ngrams_query.filter(Ngram.terms.contains(request.GET['contain'])) ngrams_query = ngrams_query.filter(Ngram.terms.contains(request.GET['contain']))
if 'corpus_id' in request.GET: if 'corpus_id' in request.GET:
corpus_id_list = list(map(int, request.GET.get('corpus_id', '').split(','))) corpus_id_list = list(map(int, request.GET.get('corpus_id', '').split(',')))
if corpus_id_list and corpus_id_list[0]: if corpus_id_list and corpus_id_list[0]:
ngrams_query = ngrams_query.filter(Node.parent_id.in_(corpus_id_list)) ngrams_query = ngrams_query.filter(Node.parent_id.in_(corpus_id_list))
if 'ngram_id' in request.GET:
ngram_id_list = list(map(int, request.GET.get('ngram_id', '').split(',')))
if ngram_id_list and ngram_id_list[0]:
ngrams_query = ngrams_query.filter(Ngram.id.in_(ngram_id_list))
# pagination # pagination
offset = int(request.GET.get('offset', 0)) offset = int(request.GET.get('offset', 0))
...@@ -306,6 +314,7 @@ class ApiNgrams(APIView): ...@@ -306,6 +314,7 @@ class ApiNgrams(APIView):
}, },
'data': [ 'data': [
{ {
'id': ngram.id,
'terms': ngram.terms, 'terms': ngram.terms,
'count': ngram.count, 'count': ngram.count,
} }
...@@ -329,7 +338,7 @@ _operators_dict = { ...@@ -329,7 +338,7 @@ _operators_dict = {
od = collections.OrderedDict(sorted(INDEXED_HYPERDATA.items())) od = collections.OrderedDict(sorted(INDEXED_HYPERDATA.items()))
_hyperdata_list = [ { key : value } _hyperdata_list = [ { key : value }
for key, value in od.items() for key, value in od.items()
if key != 'abstract' if key != 'abstract'
] ]
...@@ -403,5 +412,3 @@ class ApiHyperdata(APIView): ...@@ -403,5 +412,3 @@ class ApiHyperdata(APIView):
return JsonHttpResponse({ return JsonHttpResponse({
'data': get_metadata(corpus_id_list), 'data': get_metadata(corpus_id_list),
}) })
...@@ -2243,15 +2243,4 @@ function AfterAjax(sourceUrl) { ...@@ -2243,15 +2243,4 @@ function AfterAjax(sourceUrl) {
$("#content_loader").remove() $("#content_loader").remove()
$(".nav-tabs a").click(function(e){
e.preventDefault();
$(this).tab('show');
});
$('.nav-tabs a').on('shown.bs.tab', function(event){
var x = $(event.target).text(); // active tab
var y = $(event.relatedTarget).text(); // previous tab
$(".act span").text(x);
$(".prev span").text(y);
});
} }
...@@ -111,26 +111,14 @@ ...@@ -111,26 +111,14 @@
</a> </a>
<i class="caret"></i> <i class="caret"></i>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{% if view == "titles" %}
<li> <li>
<a tabindex="-1" <a tabindex="-1"
data-url="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=conditional&amp;bridgeness=5" onclick='gotoexplorer(this)' >With conditional distance </a> data-url="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=conditional&amp;bridgeness=5" onclick='gotoexplorer(this)' >With conditional distance </a>
</li> </li>
<li> <li>
<a tabindex="-1" <a tabindex="-1"
data-url="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=distributional&amp;bridgeness=5" onclick='gotoexplorer(this)' >With distributional distance</a> data-url="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=distributional&amp;bridgeness=5" onclick='gotoexplorer(this)' >With distributional distance</a>
</li> </li>
{% else %}
<li>
<a tabindex="-1"
href="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=conditional&amp;bridgeness=5" >With conditional distance </a>
</li>
<li>
<a tabindex="-1"
href="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=distributional&amp;bridgeness=5">With distributional distance</a>
</li>
{% endif %}
</ul> </ul>
</li> </li>
...@@ -192,7 +180,7 @@ ...@@ -192,7 +180,7 @@
</h3> </h3>
<h3> <h3>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span> <span class="glyphicon glyphicon-user" aria-hidden="true"></span>
Author(s): {{ user.username | truncatechars:15}} Author(s): {{ user.username | truncatechars:15}}
</h3> </h3>
</div> </div>
...@@ -268,16 +256,20 @@ ...@@ -268,16 +256,20 @@
<script type="text/javascript"> <script type="text/javascript">
// constrains the graph request with startdate & enddate if present
function gotoexplorer(elem) { function gotoexplorer(elem) {
var url_ = $(elem).data("url") var url_ = $(elem).data("url")
if (TheBuffer==false) if (TheBuffer==false) {
return window.open(url_,'_blank'); return window.open(url_,'_blank');
}
var current_timerange = TheBuffer var current_timerange = TheBuffer
var time_limits = [new Date(oldest[0],oldest[1]-1,oldest[2]), new Date(latest[0],latest[1]-1,latest[2] ) ]; var time_limits = [new Date(oldest[0],oldest[1]-1,oldest[2]), new Date(latest[0],latest[1]-1,latest[2] ) ];
time_limits[0] = new Date(time_limits[0].setDate(time_limits[0].getDate()-1) ); time_limits[0] = new Date(time_limits[0].setDate(time_limits[0].getDate()-1) );
time_limits[1] = new Date(time_limits[1].setDate(time_limits[1].getDate()+1) ); time_limits[1] = new Date(time_limits[1].setDate(time_limits[1].getDate()+1) );
if( ( +current_timerange[0]===+time_limits[0] ) && ( +current_timerange[1]===+time_limits[1] ) ) { if( ( +current_timerange[0]===+time_limits[0] ) && ( +current_timerange[1]===+time_limits[1] ) ) {
url_ = url_ // rien url_ = url_ // rien
} else { } else {
......
...@@ -134,7 +134,7 @@ ...@@ -134,7 +134,7 @@
{% endif %} {% endif %}
{% endifequal %} {% endifequal %}
{% endfor %} {% endfor %}
</div> </div>
<div class="col-md-3 content"> <div class="col-md-3 content">
{% for state in corpus.hyperdata.statuses %} {% for state in corpus.hyperdata.statuses %}
...@@ -309,7 +309,7 @@ ...@@ -309,7 +309,7 @@
}, },
success: function(data) { success: function(data) {
console.log("in doTheQuery() Ajax.Success:") console.log("in doTheQuery() Ajax.Success:")
console.log(data) // console.log(data)
setTimeout( setTimeout(
function() { function() {
location.reload(); location.reload();
...@@ -382,7 +382,7 @@ ...@@ -382,7 +382,7 @@
success: function(data) { success: function(data) {
console.log("SUCCESS") console.log("SUCCESS")
console.log("in getGlobalResults") console.log("in getGlobalResults")
console.log(data) // console.log(data)
console.log("enabling "+"#"+value.id) console.log("enabling "+"#"+value.id)
$("#"+value.id).attr('onclick','getGlobalResults(this);'); $("#"+value.id).attr('onclick','getGlobalResults(this);');
// $("#submit_thing").prop('disabled' , false) // $("#submit_thing").prop('disabled' , false)
...@@ -553,7 +553,7 @@ ...@@ -553,7 +553,7 @@
}, },
success: function(data) { success: function(data) {
console.log("ajax_success: in testISTEX()") console.log("ajax_success: in testISTEX()")
console.log(data) // console.log(data)
setTimeout( setTimeout(
function() { function() {
location.reload(); location.reload();
......
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