Skip to content
GitLab
Explore
Sign in
Hide whitespace changes
Inline
Side-by-side
app/javascript/packs/controllers/viewer_controller.js
View file @
036a8957
...
...
@@ -5,7 +5,7 @@ import Sortable from 'sortablejs'
export
default
class
extends
Controller
{
static
targets
=
[
'
currentPage
'
,
'
articleOverlay
'
,
'
selectedArticlePanel
'
,
'
addArticleButton
'
,
'
addCompoundArticleButton
'
,
'
compoundArticlePanel
'
]
static
values
=
{
currentPage
:
Number
,
nb
p
ages
:
Number
,
pages
:
Array
,
articles
:
Array
,
selectedArticles
:
Array
,
issueId
:
String
,
compoundMode
:
Boolean
}
static
values
=
{
currentPage
:
Number
,
nb
P
ages
:
Number
,
pages
:
Array
,
articles
:
Array
,
selectedArticles
:
Array
,
issueId
:
String
,
compoundMode
:
Boolean
}
isDragged
=
false
viewer
=
null
...
...
@@ -18,15 +18,20 @@ export default class extends Controller {
this
.
selectedArticlesValue
=
[]
if
(
selectedCompoundParam
!=
null
)
{
const
compoundParts
=
$
(
`#compound-articles-panel li[data-compound-id="
${
selectedCompoundParam
}
"]`
).
data
(
'
parts
'
)
this
.
selectedCompound
=
{
id
:
selectedCompoundParam
,
parts
:
compoundParts
}
const
compoundTitle
=
$
(
`#compound-articles-panel li[data-compound-id="
${
selectedCompoundParam
}
"]`
).
data
(
'
title
'
)
this
.
selectedCompound
=
{
id
:
selectedCompoundParam
,
parts
:
compoundParts
,
title
:
compoundTitle
}
$
(
`#compound-articles-panel li[data-compound-id="
${
selectedCompoundParam
}
"]`
).
addClass
(
"
active
"
)
this
.
load_named_entities
(
this
.
selectedCompound
.
parts
)
}
else
{
this
.
load_named_entities
([
this
.
issueIdValue
])
}
}
else
{
this
.
selectedArticlesValue
=
[
selectedParam
]
this
.
load_named_entities
([
selectedParam
])
}
this
.
setup_viewer
()
this
.
load_named_entities
([
this
.
issueIdValue
])
this
.
setup_mention_click
()
this
.
setup_compound
()
this
.
sortable
=
new
Sortable
(
document
.
getElementById
(
"
compound_list
"
),
{
...
...
@@ -110,7 +115,7 @@ export default class extends Controller {
})
// Compound article selection
$
(
"
#compound_articles_list
"
).
on
(
"
click
"
,
"
li
"
,
(
event
)
=>
{
const
elt
=
$
(
event
.
t
arget
)
const
elt
=
$
(
event
.
currentT
arget
)
if
(
elt
.
hasClass
(
"
active
"
))
this
.
unselect_compound_article
(
elt
.
data
(
'
compoundId
'
))
else
...
...
@@ -121,7 +126,8 @@ export default class extends Controller {
select_compound_article
(
compoundId
)
{
const
compoundParts
=
$
(
`#compound-articles-panel li[data-compound-id="
${
compoundId
}
"]`
).
data
(
'
parts
'
)
this
.
selectedCompound
=
{
id
:
compoundId
,
parts
:
compoundParts
}
const
compoundTitle
=
$
(
`#compound-articles-panel li[data-compound-id="
${
compoundId
}
"]`
).
data
(
'
title
'
)
this
.
selectedCompound
=
{
id
:
compoundId
,
parts
:
compoundParts
,
title
:
compoundTitle
}
$
(
"
#compound-articles-panel li
"
).
removeClass
(
"
active
"
)
$
(
`#compound-articles-panel li[data-compound-id="
${
compoundId
}
"]`
).
addClass
(
"
active
"
)
this
.
unselectArticles
()
...
...
@@ -163,7 +169,7 @@ export default class extends Controller {
// Go to article page and select it
let
article
=
this
.
articlesValue
.
filter
((
obj
)
=>
{
return
obj
[
"
id
"
]
==
articleId
})[
0
]
let
pagenum
=
article
.
canvases_parts
[
0
]
pagenum
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
_
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
pagenum
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
/
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
// this.viewer.goToPage(pagenum)
// this.viewer.viewport.zoomTo(2)
// this.viewer.viewport.panTo(new OpenSeadragon.Point(loc.x+loc.width/2, loc.y+loc.height/2))
...
...
@@ -262,7 +268,7 @@ export default class extends Controller {
const
art
=
this
.
articlesValue
.
filter
(
elt
=>
elt
.
id
==
article_id
)[
0
]
return
art
.
all_text
.
replaceAll
(
"
\"
"
,
""
).
replaceAll
(
"
\\
n
"
,
"
<br/>
"
)
}).
join
(
"
\n
"
)
$
(
this
.
selectedArticlePanelTarget
).
find
(
'
h5
'
)[
0
].
innerHTML
=
""
$
(
this
.
selectedArticlePanelTarget
).
find
(
'
h5
'
)[
0
].
innerHTML
=
this
.
selectedCompound
.
title
$
(
this
.
selectedArticlePanelTarget
).
find
(
'
p
'
)[
0
].
innerHTML
=
text
}
else
{
...
...
@@ -359,7 +365,7 @@ export default class extends Controller {
$
(
this
.
addArticleButtonTarget
).
addClass
(
"
d-none
"
)
const
first_article_part
=
this
.
articlesValue
.
filter
((
elt
)
=>
{
return
elt
.
id
==
this
.
selectedCompound
.
parts
[
0
]})[
0
]
const
pagenum
=
first_article_part
.
canvases_parts
[
0
]
initialPage
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
_
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
-
1
initialPage
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
/
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
-
1
}
else
{
initialPage
=
0
...
...
@@ -370,11 +376,11 @@ export default class extends Controller {
else
{
$
(
this
.
addArticleButtonTarget
).
removeClass
(
"
d-none
"
)
const
pagenum
=
selectedArticleObject
.
canvases_parts
[
0
]
initialPage
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
_
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
-
1
initialPage
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
/
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
-
1
}
this
.
viewer
=
OpenSeadragon
({
id
:
"
openseadragon_view
"
,
prefixUrl
:
"
/openseadragon/images/feathericons/
"
,
prefixUrl
:
"
/
static/js/
openseadragon/images/feathericons/
"
,
sequenceMode
:
true
,
initialPage
:
initialPage
,
tileSources
:
this
.
pagesValue
,
...
...
@@ -405,7 +411,7 @@ export default class extends Controller {
this
.
viewer
.
addHandler
(
"
open
"
,
(
data
)
=>
{
for
(
let
article
of
this
.
articlesValue
)
{
let
pagenum
=
article
.
canvases_parts
[
0
]
pagenum
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
_
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
pagenum
=
parseInt
(
pagenum
.
substring
(
pagenum
.
lastIndexOf
(
'
/
'
)
+
1
,
pagenum
.
lastIndexOf
(
"
#xywh
"
)))
if
(
pagenum
===
this
.
currentPageValue
)
{
let
bbox
=
article
.
bbox
let
loc
=
this
.
viewer
.
viewport
.
imageToViewportRectangle
(
bbox
[
0
],
bbox
[
1
],
bbox
[
2
],
bbox
[
3
])
...
...
app/javascript/packs/stylesheets/catalog.scss
View file @
036a8957
////////////////// General //////////////////
html
,
body
{
height
:
100%
;
}
body
.container-fluid
{
height
:
100%
;
}
#navigation
{
height
:
8%
;
}
#main-content
{
height
:
92%
;
}
//
html, body {
//
height: 100%;
//
}
//
body .container-fluid {
//
height:100%;
//
}
//
#navigation {
//
height: 8%;
//
}
//
#main-content {
//
height: 92%;
//
}
/////////////////////////////////////////////
////////////////// Catalog index //////////////////
...
...
@@ -21,7 +21,7 @@ body .container-fluid {
background-color
:
#EEE
;
}
.search_result.selected
{
border
:
2px
solid
#32a1ce
;
border
:
2px
solid
darken
(
hsl
(
180
,
15%
,
30%
)
,
10%
)
;
padding
:
calc
(
0
.5em
-
2px
);
}
#canvas_wide_dates_histogram
{
...
...
@@ -31,11 +31,19 @@ body .container-fluid {
////////////////// Facets //////////////////
#facets
.constrained
{
background
:
lightgreen
;
background
:
lighten
(
hsl
(
180
,
15%
,
30%
)
,
45%
);
}
.accordion-button
:not
(
.collapsed
)
{
color
:
hsl
(
180
,
15%
,
30%
);
}
.accordion-button
:not
(
.collapsed
)
::after
{
background-image
:
url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")
;
}
li
.selected_constraint
{
color
:
green
;
color
:
darken
(
hsl
(
180
,
15%
,
30%
)
,
10%
)
;
}
////////////////////////////////////////////
...
...
@@ -43,9 +51,11 @@ li.selected_constraint {
#openseadragon_view
{
width
:
auto
;
height
:
85vh
;
border-color
:
hsl
(
180
,
15%
,
30%
);
border-style
:
solid
;
border-width
:
2px
;
background-color
:
#AAAAAA
;
border-width
:
1px
;
border-radius
:
6px
;
background-color
:
#b3c3c7
;
}
#viewer_container
{
position
:
relative
;
...
...
@@ -57,11 +67,11 @@ li.selected_constraint {
#page_counter
{
position
:
absolute
;
background-color
:
#
8AF
;
background-color
:
#
7397a0
;
border-color
:
#000
;
border-style
:
solid
;
font-weight
:
bold
;
border-
width
:
2
px
;
border-width
:
1px
;
border-
radius
:
6
px
;
top
:
1vh
;
right
:
3
.5vh
;
padding
:
0px
2px
;
...
...
@@ -109,66 +119,66 @@ li.selected_constraint {
///////////////////////////////////////////////
////////////////// Show Experiment /////////////////////
.tool
:hover
{
cursor
:
grab
;
}
.tf-nc.tool-slot
{
border-style
:
dashed
;
width
:
8vw
;
height
:
10vh
;
padding
:
0
;
}
.tf-nc.possible-tool-slot
{
border-color
:
cornflowerblue
;
border-width
:
3px
;
}
.tf-nc.tool-slot-hover
{
border
:
1em
solid
blue
!
important
;
}
//
.tool:hover {
//
cursor: grab;
//
}
//
.tf-nc.tool-slot {
//
border-style: dashed;
//
width:8vw;
//
height:10vh;
//
padding: 0;
//
}
//
.tf-nc.possible-tool-slot {
//
border-color: cornflowerblue;
//
border-width: 3px;
//
}
//
.tf-nc.tool-slot-hover {
//
border: 1em solid blue !important;
//
}
.tool-status
{
height
:
1em
;
width
:
1em
;
border-radius
:
50%
;
border-color
:
black
;
border-width
:
1px
;
border-style
:
solid
;
display
:
inline-block
;
}
.tool-status-created
{
background-color
:
gray
;
}
.tool-status-configured
{
background-color
:
white
;
}
.tool-status-error
{
background-color
:
red
;
}
.tool-status-running
{
background-color
:
gold
;
}
.tool-status-finished
{
background-color
:
green
;
}
//
.tool-status {
//
height: 1em;
//
width: 1em;
//
border-radius: 50%;
//
border-color: black;
//
border-width: 1px;
//
border-style: solid;
//
display: inline-block;
//
}
//
.tool-status-created {
//
background-color: gray;
//
}
//
.tool-status-configured {
//
background-color: white;
//
}
//
.tool-status-error {
//
background-color: red;
//
}
//
.tool-status-running {
//
background-color: gold;
//
}
//
.tool-status-finished {
//
background-color: green;
//
}
.tool-slot-occupied
{
width
:
15vw
;
height
:
15vh
;
padding
:
0
;
}
#experiment_area
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
#experiment_canvas
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
height
:
100%
;
width
:
100%
;
overflow
:
visible
;
}
//
.tool-slot-occupied {
//
width:15vw;
//
height:15vh;
//
padding: 0;
//
}
//
#experiment_area {
//
display: flex;
//
align-items: center;
//
justify-content: center;
//
}
//
#experiment_canvas {
//
display: flex;
//
align-items: center;
//
justify-content: center;
//
height: 100%;
//
width: 100%;
//
overflow: visible;
//
}
////////////////////////////////////////////////////////
////////////////////// Index Datasets ////////////////////
...
...
@@ -182,10 +192,10 @@ li.selected_constraint {
padding
:
0
.5em
;
}
.dataset_document
:hover
{
background-color
:
#
FBFBFB
;
background-color
:
#
EEE
;
}
.dataset_document.selected
{
border
:
2px
solid
#32a1ce
;
border
:
2px
solid
darken
(
hsl
(
180
,
15%
,
30%
)
,
10%
)
;
padding
:
calc
(
0
.5em
-
2px
);
}
////////////////////////////////////////////////////////
\ No newline at end of file
app/javascript/packs/utils/dataset_api.js
View file @
036a8957
import
{
addPrefixURL
}
from
"
../application.js
"
export
class
DatasetAPI
{
static
create_dataset
(
title
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/dataset/create
"
,
data
:
{
title
:
title
},
url
:
addPrefixURL
()
+
"
/dataset/create
"
,
data
:
{
title
:
title
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -18,8 +20,8 @@ export class DatasetAPI {
static
rename_dataset
(
id
,
title
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/dataset/rename
"
,
data
:
{
id
:
id
,
title
:
title
},
url
:
addPrefixURL
()
+
"
/dataset/rename
"
,
data
:
{
id
:
id
,
title
:
title
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -34,8 +36,8 @@ export class DatasetAPI {
static
import_dataset
(
id
,
title
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/dataset/import
"
,
data
:
{
original_dataset_id
:
id
,
title
:
title
},
url
:
addPrefixURL
()
+
"
/dataset/import
"
,
data
:
{
original_dataset_id
:
id
,
title
:
title
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -51,8 +53,8 @@ export class DatasetAPI {
static
delete_dataset
(
datasetId
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/dataset/delete
"
,
data
:
{
dataset_id
:
datasetId
},
url
:
addPrefixURL
()
+
"
/dataset/delete
"
,
data
:
{
dataset_id
:
datasetId
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -68,7 +70,7 @@ export class DatasetAPI {
static
update_datasets_list
(
callback
)
{
$
.
ajax
({
type
:
"
GET
"
,
url
:
"
/datasets/update
"
,
url
:
addPrefixURL
()
+
"
/datasets/update
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -85,7 +87,7 @@ export class DatasetAPI {
static
setCurrentWorkingDataset
(
datasetId
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/datasets/working_dataset
"
,
url
:
addPrefixURL
()
+
"
/datasets/working_dataset
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -101,7 +103,7 @@ export class DatasetAPI {
static
addSelectedDocumentsToWorkingDataset
(
documentsIds
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/datasets/add_selected_documents
"
,
url
:
addPrefixURL
()
+
"
/datasets/add_selected_documents
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -117,7 +119,7 @@ export class DatasetAPI {
static
addSelectedCompoundToWorkingDataset
(
compoundId
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/datasets/add_compound
"
,
url
:
addPrefixURL
()
+
"
/datasets/add_compound
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -133,7 +135,7 @@ export class DatasetAPI {
static
removeSelectedDocumentsToWorkingDataset
(
documentsIds
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/datasets/remove_selected_documents
"
,
url
:
addPrefixURL
()
+
"
/datasets/remove_selected_documents
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -149,7 +151,7 @@ export class DatasetAPI {
static
addAllDocumentsToWorkingDataset
(
searchParams
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/datasets/add_all_documents
"
,
url
:
addPrefixURL
()
+
"
/datasets/add_all_documents
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -165,7 +167,7 @@ export class DatasetAPI {
static
exportDataset
(
datasetId
,
exportType
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/datasets/export_dataset
"
,
url
:
addPrefixURL
()
+
"
/datasets/export_dataset
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -182,7 +184,7 @@ export class DatasetAPI {
static
paginateDataset
(
datasetId
,
page
,
per_page
,
sort
,
sort_order
,
type
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
`/dataset/
${
datasetId
}
/paginate`
,
url
:
addPrefixURL
()
+
`/dataset/
${
datasetId
}
/paginate`
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -199,7 +201,7 @@ export class DatasetAPI {
static
getDatasets
(
callback
)
{
$
.
ajax
({
type
:
"
GET
"
,
url
:
`
/datasets/list
`
,
url
:
addPrefixURL
()
+
"
/datasets/list
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -213,7 +215,7 @@ export class DatasetAPI {
static
toggleSharingStatus
(
dataset_id
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
`
/dataset/toggle_sharing_status
`
,
url
:
addPrefixURL
()
+
"
/dataset/toggle_sharing_status
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
app/javascript/packs/utils/search_api.js
View file @
036a8957
import
{
addPrefixURL
}
from
"
../application.js
"
export
class
SearchAPI
{
static
load_dataset_named_entities
(
dataset_id
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/dataset_named_entities
"
,
data
:
{
dataset_id
:
dataset_id
},
url
:
addPrefixURL
()
+
"
/dataset_named_entities
"
,
data
:
{
dataset_id
:
dataset_id
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -20,8 +22,8 @@ export class SearchAPI {
static
load_named_entities
(
docs_ids
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/named_entities
"
,
data
:
{
docs_ids
:
docs_ids
},
url
:
addPrefixURL
()
+
"
/named_entities
"
,
data
:
{
docs_ids
:
docs_ids
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -37,8 +39,8 @@ export class SearchAPI {
static
facetPagination
(
fieldName
,
nbPages
,
currentPage
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/catalog/facet_pagination
"
,
data
:
{
field_name
:
fieldName
,
nb_pages
:
nbPages
,
current_page
:
currentPage
},
url
:
addPrefixURL
()
+
"
/catalog/facet_pagination
"
,
data
:
{
field_name
:
fieldName
,
nb_pages
:
nbPages
,
current_page
:
currentPage
},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -54,7 +56,7 @@ export class SearchAPI {
static
wideDatesHistogram
(
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
"
/catalog/wide_dates_histogram
"
,
url
:
addPrefixURL
()
+
"
/catalog/wide_dates_histogram
"
,
data
:
{},
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
...
...
@@ -71,7 +73,7 @@ export class SearchAPI {
static
confirm_compond_creation
(
article_parts
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
`
/catalog/confirm_compound_creation
`
,
url
:
addPrefixURL
()
+
"
/catalog/confirm_compound_creation
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -87,7 +89,7 @@ export class SearchAPI {
static
create_compound
(
title
,
all_text
,
issue_id
,
article_parts_ids
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
`
/catalog/create_compound
`
,
url
:
addPrefixURL
()
+
"
/catalog/create_compound
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -106,7 +108,7 @@ export class SearchAPI {
static
delete_compound_article
(
compound_id
,
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
`
/catalog/delete_compound
`
,
url
:
addPrefixURL
()
+
"
/catalog/delete_compound
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
@@ -122,7 +124,7 @@ export class SearchAPI {
static
random_sample
(
callback
)
{
$
.
ajax
({
type
:
"
POST
"
,
url
:
`
/catalog/random_sample
`
,
url
:
addPrefixURL
()
+
"
/catalog/random_sample
"
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
)
},
...
...
app/mailers/application_mailer.rb
View file @
036a8957
class
ApplicationMailer
<
ActionMailer
::
Base
default
from:
'
from@example.com
'
layout
'
mailer
'
default
from:
"
from@example.com
"
layout
"
mailer
"
end
app/models/article.rb
View file @
036a8957
class
Article
attr_accessor
:id
,
:title
,
:all_text
,
:date_created
,
:language
,
:canvases_parts
,
:newspaper
,
:issue_id
,
:thumbnail_url
,
:bbox
attr_accessor
:id
,
:title
,
:all_text
,
:date_created
,
:language
,
:canvases_parts
,
:newspaper
,
:issue_id
,
:thumbnail_url
,
:bbox
def
self
.
from_solr
(
id
)
solr_doc
=
SolrSearcher
.
get_doc_by_id
id
Article
.
from_solr_doc
solr_doc
end
def
self
.
from_solr
id
solr_doc
=
SolrSearcher
.
get_doc_by_id
id
Article
.
from_solr_doc
solr_doc
end
def
self
.
from_solr_doc
(
solr_doc
)
a
=
Article
.
new
a
.
id
=
solr_doc
[
"id"
]
a
.
title
=
solr_doc
[
"title_ssi"
]
a
.
language
=
solr_doc
[
"language_ssi"
]
a
.
all_text
=
solr_doc
[
"all_text_t
#{
a
.
language
}
_siv"
]
a
.
date_created
=
solr_doc
[
"date_created_ssi"
]
a
.
issue_id
=
solr_doc
[
"from_issue_ssi"
]
a
.
newspaper
=
solr_doc
[
"member_of_collection_ids_ssim"
].
first
a
.
thumbnail_url
=
solr_doc
[
"thumbnail_url_ss"
]
a
.
canvases_parts
=
solr_doc
[
"canvases_parts_ssm"
]
a
.
bbox
=
a
.
get_location
a
end
def
self
.
from_solr_doc
solr_doc
a
=
Article
.
new
a
.
id
=
solr_doc
[
'id'
]
a
.
title
=
solr_doc
[
'title_ssi'
]
a
.
language
=
solr_doc
[
'language_ssi'
]
a
.
all_text
=
solr_doc
[
"all_text_t
#{
a
.
language
}
_siv"
]
a
.
date_created
=
solr_doc
[
'date_created_ssi'
]
a
.
issue_id
=
solr_doc
[
'from_issue_ssi'
]
a
.
newspaper
=
solr_doc
[
'member_of_collection_ids_ssim'
].
first
a
.
thumbnail_url
=
solr_doc
[
'thumbnail_url_ss'
]
a
.
canvases_parts
=
solr_doc
[
'canvases_parts_ssm'
]
a
.
bbox
=
a
.
get_location
a
end
def
to_solr
(
page_iiif_url
)
solr_doc
=
{}
solr_doc
[
"id"
]
=
self
.
id
solr_doc
[
"title_ssi"
]
=
self
.
title
solr_doc
[
"language_ssi"
]
=
self
.
language
solr_doc
[
"all_text_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
[
"all_text_unstemmed_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
[
"date_created_ssi"
]
=
self
.
date_created
solr_doc
[
"date_created_dtsi"
]
=
DateTime
.
parse
(
self
.
date_created
).
strftime
(
"%Y-%m-%dT%H:%M:%SZ"
)
solr_doc
[
"year_isi"
]
=
solr_doc
[
"date_created_ssi"
][
0
..
3
].
to_i
d
=
DateTime
.
parse
solr_doc
[
"date_created_dtsi"
]
solr_doc
[
"month_isi"
]
=
d
.
month
solr_doc
[
"day_isi"
]
=
d
.
wday
solr_doc
[
"from_issue_ssi"
]
=
self
.
issue_id
solr_doc
[
"member_of_collection_ids_ssim"
]
=
self
.
newspaper
solr_doc
[
"canvases_parts_ssm"
]
=
self
.
canvases_parts
solr_doc
[
"thumbnail_url_ss"
]
=
self
.
get_iiif_url
(
page_iiif_url
)
solr_doc
[
"has_model_ssim"
]
=
"Article"
solr_doc
end
def
to_solr
(
page_iiif_url
)
solr_doc
=
{}
solr_doc
[
'id'
]
=
self
.
id
solr_doc
[
'title_ssi'
]
=
self
.
title
solr_doc
[
"language_ssi"
]
=
self
.
language
solr_doc
[
"all_text_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
[
"all_text_unstemmed_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
[
'date_created_ssi'
]
=
self
.
date_created
solr_doc
[
'date_created_dtsi'
]
=
DateTime
.
parse
(
self
.
date_created
).
strftime
(
'%Y-%m-%dT%H:%M:%SZ'
)
solr_doc
[
'year_isi'
]
=
solr_doc
[
'date_created_ssi'
][
0
..
3
].
to_i
d
=
DateTime
.
parse
solr_doc
[
"date_created_dtsi"
]
solr_doc
[
'month_isi'
]
=
d
.
month
solr_doc
[
'day_isi'
]
=
d
.
wday
solr_doc
[
'from_issue_ssi'
]
=
self
.
issue_id
solr_doc
[
'member_of_collection_ids_ssim'
]
=
self
.
newspaper
solr_doc
[
'canvases_parts_ssm'
]
=
self
.
canvases_parts
solr_doc
[
'thumbnail_url_ss'
]
=
self
.
get_iiif_url
(
page_iiif_url
)
solr_doc
[
'has_model_ssim'
]
=
'Article'
solr_doc
def
get_thumbnail
if
Rails
.
configuration
.
iiif_sources
[
:local
].
include?
self
.
newspaper
pagenum
=
self
.
canvases_parts
[
0
][
self
.
canvases_parts
[
0
].
rindex
(
"_"
)
+
1
...
self
.
canvases_parts
[
0
].
rindex
(
"#"
)].
to_i
self
.
get_iiif_url
(
"https://iiif.newseye.eu/iiif/
#{
self
.
newspaper
}
/
#{
self
.
issue_id
}
_page_
#{
pagenum
}
.ptif"
)
elsif
Rails
.
configuration
.
iiif_sources
[
:external
].
include?
self
.
newspaper
self
.
thumbnail_url
elsif
Rails
.
configuration
.
iiif_sources
[
:external_onb
].
include?
self
.
newspaper
self
.
thumbnail_url
end
end
def
get_
thumbnail
if
Rails
.
configuration
.
iiif_sources
[
:local
].
include?
self
.
newspaper
pagenum
=
self
.
canvases_parts
[
0
][
self
.
canvases_parts
[
0
].
rindex
(
'_'
)
+
1
...
self
.
canvases_parts
[
0
].
rindex
(
'#'
)].
to_i
self
.
get_iiif_url
(
"https://iiif.newseye.eu/iiif/
#{
self
.
newspaper
}
/
#{
self
.
issue_id
}
_page_
#{
pagenum
}
.ptif"
)
elsif
Rails
.
configuration
.
iiif_sources
[
:external
].
include?
self
.
newspaper
self
.
thumbnail_url
elsif
Rails
.
configuration
.
iiif_sources
[
:external_onb
].
include?
self
.
newspaper
self
.
thumbnail_url
end
end
def
get_
location
coords
=
self
.
canvases_parts
.
map
{
|
c
|
c
[
c
.
rindex
(
"#xywh="
)
+
6
..-
1
].
split
(
","
).
map
(
&
:to_i
)
}
min_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
}.
min
max_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
+
coord
[
2
]
}.
max
min_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
}.
min
max_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
+
coord
[
3
]
}.
max
canvas_coords
=
[
min_x
,
max_x
,
min_y
,
max_y
]
canvas_size
=
[
canvas_coords
[
1
]
-
canvas_coords
[
0
],
canvas_coords
[
3
]
-
canvas_coords
[
2
]]
[
min_x
,
min_y
,
canvas_size
[
0
],
canvas_size
[
1
]]
end
def
get_
location
c
oords
=
self
.
canvases_parts
.
map
{
|
c
|
c
[
c
.
rindex
(
'#xywh='
)
+
6
..-
1
].
split
(
','
).
map
(
&
:to_i
)
}
min_x
=
coord
s
.
map
{
|
c
oord
|
coord
[
0
]
}.
min
m
ax
_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
+
coord
[
2
]
}.
m
ax
m
in_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
}.
m
in
m
ax
_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
+
coord
[
3
]
}.
m
ax
canvas_coords
=
[
min_x
,
max_x
,
min_y
,
max_y
]
canvas_size
=
[
canvas_
coords
[
1
]
-
canvas_coords
[
0
],
canvas_coords
[
3
]
-
canvas_coords
[
2
]]
[
min_x
,
min_y
,
canvas_size
[
0
],
canvas_size
[
1
]]
end
def
get_
iiif_url
(
page_iiif_url
)
c
anvas_url
=
self
.
canvases_parts
[
0
]
coords
=
self
.
canvases_part
s
.
map
{
|
c
|
c
[
c
.
rindex
(
"#xywh="
)
+
6
..-
1
].
split
(
","
).
map
(
&
:to_i
)
}
m
in
_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
}.
m
in
m
ax_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
+
coord
[
2
]
}.
m
ax
m
in
_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
}.
m
in
max_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
+
coord
[
3
]
}.
max
pagenum
=
canvas_
url
[
canvas_url
.
rindex
(
"_"
)
+
1
...
canvas_url
.
rindex
(
"#"
)].
to_i
"
#{
page_iiif_url
}
/
#{
min_x
}
,
#{
min_y
}
,
#{
max_x
-
min_x
}
,
#{
max_y
-
min_y
}
/full/0/default.jpg"
end
def
get_iiif_url
(
page_iiif_url
)
canvas_url
=
self
.
canvases_parts
[
0
]
coords
=
self
.
canvases_parts
.
map
{
|
c
|
c
[
c
.
rindex
(
'#xywh='
)
+
6
..-
1
].
split
(
','
).
map
(
&
:to_i
)
}
min_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
}.
min
max_x
=
coords
.
map
{
|
coord
|
coord
[
0
]
+
coord
[
2
]
}.
max
min_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
}.
min
max_y
=
coords
.
map
{
|
coord
|
coord
[
1
]
+
coord
[
3
]
}.
max
pagenum
=
canvas_url
[
canvas_url
.
rindex
(
'_'
)
+
1
...
canvas_url
.
rindex
(
'#'
)].
to_i
"
#{
page_iiif_url
}
/
#{
min_x
}
,
#{
min_y
}
,
#{
max_x
-
min_x
}
,
#{
max_y
-
min_y
}
/full/0/default.jpg"
def
self
.
named_entities
(
article_id
)
nems
=
SolrSearcher
.
query
({
q:
"article_id_ssi:
#{
article_id
}
"
,
rows:
1000000
})[
"response"
][
"docs"
]
output
=
{
LOC
:
{},
PER
:
{},
ORG
:
{},
HumanProd
:
{}
}
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"LOC"
}.
each
do
|
ne_solr
|
output
[
:LOC
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:LOC
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:LOC
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
def
self
.
named_entities
(
article_id
)
nems
=
SolrSearcher
.
query
({
q
:"article_id_ssi:
#{
article_id
}
"
,
rows:
1000000
})[
'response'
][
'docs'
]
output
=
{
LOC
:
{},
PER
:
{},
ORG
:
{},
HumanProd
:
{}}
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"LOC"
}.
each
do
|
ne_solr
|
output
[
:LOC
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:LOC
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:LOC
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"PER"
}.
each
do
|
ne_solr
|
output
[
:PER
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:PER
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:PER
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"ORG"
}.
each
do
|
ne_solr
|
output
[
:ORG
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:ORG
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:ORG
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"HumanProd"
}.
each
do
|
ne_solr
|
output
[
:HumanProd
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:HumanProd
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:HumanProd
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
output
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"PER"
}.
each
do
|
ne_solr
|
output
[
:PER
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:PER
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:PER
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"ORG"
}.
each
do
|
ne_solr
|
output
[
:ORG
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:ORG
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:ORG
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"HumanProd"
}.
each
do
|
ne_solr
|
output
[
:HumanProd
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:HumanProd
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:HumanProd
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
end
\ No newline at end of file
output
end
end
app/models/compound_article.rb
View file @
036a8957
class
CompoundArticle
<
ActiveRecord
::
Base
belongs_to
:user
,
optional:
false
validates
:title
,
length:
{
minimum:
1
}
end
\ No newline at end of file
belongs_to
:user
,
optional:
false
validates
:title
,
length:
{
minimum:
1
}
end
app/models/concerns/abstract_searcher.rb
View file @
036a8957
module
AbstractSearcher
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
def
self
.
query
raise
NotImplementedError
,
"Subclasses must define `query`."
end
def
self
.
query
raise
NotImplementedError
,
"Subclasses must define `query`."
end
def
self
.
get_doc_by_id
(
id
)
raise
NotImplementedError
,
"Subclasses must define `get_doc_by_id`."
end
end
\ No newline at end of file
def
self
.
get_doc_by_id
(
id
)
raise
NotImplementedError
,
"Subclasses must define `get_doc_by_id`."
end
end
app/models/current.rb
0 → 100644
View file @
036a8957
class
Current
<
ActiveSupport
::
CurrentAttributes
attribute
:user
end
app/models/dataset.rb
View file @
036a8957
class
Dataset
<
ActiveRecord
::
Base
# after_find :nb_issues, :nb_articles
belongs_to
:user
,
optional:
false
validates
:title
,
length:
{
minimum:
1
}
# after_find :nb_issues, :nb_articles
belongs_to
:user
,
optional:
false
validates
:title
,
length:
{
minimum:
1
}
def
add_documents
(
documents_ids
)
existing
=
[]
documents_ids
.
each
do
|
doc_id
|
if
self
.
documents
.
any?
{
|
doc
|
doc
[
'id'
]
==
doc_id
}
existing
<<
doc_id
else
doc_type
=
doc_id
.
index
(
"_article_"
).
nil?
?
"issue"
:
"article"
self
.
documents
<<
{
id:
doc_id
,
type:
doc_type
}
end
end
self
.
save
return
existing
end
def
add_compound
(
compound_id
)
existing
=
[]
if
self
.
documents
.
any?
{
|
doc
|
doc
[
'id'
]
==
compound_id
}
existing
<<
compound_id
else
doc_type
=
"compound"
self
.
documents
<<
{
id:
compound_id
,
type:
doc_type
}
end
self
.
save
return
existing
def
add_documents
(
documents_ids
)
existing
=
[]
documents_ids
.
each
do
|
doc_id
|
if
self
.
documents
.
any?
{
|
doc
|
doc
[
"id"
]
==
doc_id
}
existing
<<
doc_id
else
doc_type
=
doc_id
.
index
(
"_article_"
).
nil?
?
"issue"
:
"article"
self
.
documents
<<
{
id:
doc_id
,
type:
doc_type
}
end
end
self
.
save
return
existing
end
def
remove_documents
(
documents_ids
)
self
.
documents
.
delete_if
{
|
elt
|
documents_ids
.
include?
elt
[
'id'
]
}
self
.
save
def
add_compound
(
compound_id
)
existing
=
[]
if
self
.
documents
.
any?
{
|
doc
|
doc
[
"id"
]
==
compound_id
}
existing
<<
compound_id
else
doc_type
=
"compound"
self
.
documents
<<
{
id:
compound_id
,
type:
doc_type
}
end
self
.
save
return
existing
end
def
contains
doc_id
self
.
documents
.
index
{
|
doc
|
doc
[
'id'
]
==
doc_id
}.
nil?
?
false
:
true
end
def
remove_documents
(
documents_ids
)
self
.
documents
.
delete_if
{
|
elt
|
documents_ids
.
include?
elt
[
"id"
]
}
self
.
save
end
def
nb_issues
self
.
documents
.
select
do
|
doc
|
doc
[
'type'
]
==
'issue'
end
.
size
end
def
contains
(
doc_id
)
self
.
documents
.
index
{
|
doc
|
doc
[
"id"
]
==
doc_id
}.
nil?
?
false
:
true
end
def
nb_
articl
es
self
.
documents
.
select
do
|
doc
|
doc
[
'
type
'
]
==
'article'
end
.
size
end
def
nb_
issu
es
self
.
documents
.
select
do
|
doc
|
doc
[
"
type
"
]
==
"issue"
end
.
size
end
def
nb_
compound_
articles
self
.
documents
.
select
do
|
doc
|
doc
[
'
type
'
]
==
'compound'
end
.
size
end
def
nb_articles
self
.
documents
.
select
do
|
doc
|
doc
[
"
type
"
]
==
"article"
end
.
size
end
def
fetch_paginated_documents
(
page
,
per_page
,
sort
,
sort_order
,
type
,
recursive
=
false
)
docs
=
self
.
documents
.
select
{
|
doc
|
type
==
"all"
||
doc
[
'type'
]
==
type
}
def
nb_compound_articles
self
.
documents
.
select
do
|
doc
|
doc
[
"type"
]
==
"compound"
end
.
size
end
nb_pages
=
(
docs
.
size
/
per_page
.
to_f
).
ceil
nb_pages
=
1
if
nb_pages
==
0
sort
=
(
sort
==
"default"
)
?
"score"
:
sort
solr_docs
=
nil
def
fetch_paginated_documents
(
page
,
per_page
,
sort
,
sort_order
,
type
,
recursive
=
false
)
docs
=
self
.
documents
.
select
{
|
doc
|
type
==
"all"
||
doc
[
"type"
]
==
type
}
compounds_ids
=
docs
.
select
{
|
d
|
d
[
'type'
]
==
"compound"
}.
map
{
|
d
|
d
[
'id'
]
}
compound_articles
=
CompoundArticle
.
find
(
compounds_ids
)
nb_pages
=
(
docs
.
size
/
per_page
.
to_f
).
ceil
nb_pages
=
1
if
nb_pages
==
0
sort
=
(
sort
==
"default"
)
?
"score"
:
sort
solr_docs
=
nil
compounds_ids
=
docs
.
select
{
|
d
|
d
[
"type"
]
==
"compound"
}.
map
{
|
d
|
d
[
"id"
]
}
compound_articles
=
CompoundArticle
.
find
(
compounds_ids
)
solr_ids
=
docs
.
select
{
|
d
|
d
[
'
type
'
]
!=
"compound"
}.
map
{
|
d
|
d
[
'
id
'
]
}
unless
solr_ids
.
empty?
solr_docs
=
SolrSearcher
.
query
({
solr_ids
=
docs
.
select
{
|
d
|
d
[
"
type
"
]
!=
"compound"
}.
map
{
|
d
|
d
[
"
id
"
]
}
unless
solr_ids
.
empty?
solr_docs
=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"id:(
#{
solr_ids
.
join
(
' '
)
}
)"
,
fq:
"id:(
#{
solr_ids
.
join
(
" "
)
}
)"
,
rows:
per_page
,
sort:
"
#{
sort
}
#{
sort_order
}
"
,
start:
(
page
-
1
)
*
per_page
})[
'response'
][
'docs'
]
solr_docs
.
map!
do
|
solr_doc
|
if
solr_doc
[
'id'
].
index
(
"_article_"
).
nil?
Issue
.
from_solr_doc
solr_doc
else
Article
.
from_solr_doc
solr_doc
end
end
end
if
recursive
and
page
<
nb_pages
and
!
solr_docs
.
nil?
solr_docs
=
solr_docs
.
concat
fetch_paginated_documents
(
page
+
1
,
per_page
,
sort
,
sort_order
,
type
,
true
)[
:docs
]
start:
(
page
-
1
)
*
per_page
,
})[
"response"
][
"docs"
]
solr_docs
.
map!
do
|
solr_doc
|
if
solr_doc
[
"id"
].
index
(
"_article_"
).
nil?
Issue
.
from_solr_doc
solr_doc
else
Article
.
from_solr_doc
solr_doc
end
return
{
docs:
solr_docs
.
nil?
?
compound_articles
:
solr_docs
+
compound_articles
,
nb_pages:
nb_pages
}
end
end
if
recursive
and
page
<
nb_pages
and
!
solr_docs
.
nil?
solr_docs
=
solr_docs
.
concat
fetch_paginated_documents
(
page
+
1
,
per_page
,
sort
,
sort_order
,
type
,
true
)[
:docs
]
end
return
{
docs:
solr_docs
.
nil?
?
compound_articles
:
solr_docs
+
compound_articles
,
nb_pages:
nb_pages
}
end
def
named_entities
article_ids
=
self
.
documents
.
select
{
|
d
|
d
[
'type'
]
==
'article'
}.
map
{
|
d
|
d
[
'id'
]}
issue_ids
=
self
.
documents
.
select
{
|
d
|
d
[
'type'
]
==
'issue'
}.
map
{
|
d
|
d
[
'id'
]}
parts_ids
=
self
.
documents
.
select
{
|
d
|
d
[
'type'
]
==
'compound'
}.
map
{
|
d
|
CompoundArticle
.
find
(
d
[
'id'
]).
parts
}.
flatten
.
uniq
nems
=
[]
nems
=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"article_id_ssi:(
#{
article_ids
.
join
(
' OR '
)
}
)"
,
rows:
1000000
})[
'response'
][
'docs'
]
unless
article_ids
.
empty?
nems
+=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"article_id_ssi:(
#{
parts_ids
.
join
(
' OR '
)
}
)"
,
rows:
1000000
})[
'response'
][
'docs'
]
unless
parts_ids
.
empty?
nems
+=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"issue_id_ssi:(
#{
issue_ids
.
join
(
' OR '
)
}
)"
,
rows:
1000000
})[
'response'
][
'docs'
]
unless
issue_ids
.
empty?
output
=
{
LOC
:
{},
PER
:
{},
ORG
:
{},
HumanProd
:
{}}
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"LOC"
}.
each
do
|
ne_solr
|
output
[
:LOC
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:LOC
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:LOC
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"PER"
}.
each
do
|
ne_solr
|
output
[
:PER
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:PER
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:PER
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"ORG"
}.
each
do
|
ne_solr
|
output
[
:ORG
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:ORG
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:ORG
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"HumanProd"
}.
each
do
|
ne_solr
|
output
[
:HumanProd
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:HumanProd
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:HumanProd
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
output
def
named_entities
article_ids
=
self
.
documents
.
select
{
|
d
|
d
[
"type"
]
==
"article"
}.
map
{
|
d
|
d
[
"id"
]
}
issue_ids
=
self
.
documents
.
select
{
|
d
|
d
[
"type"
]
==
"issue"
}.
map
{
|
d
|
d
[
"id"
]
}
parts_ids
=
self
.
documents
.
select
{
|
d
|
d
[
"type"
]
==
"compound"
}.
map
{
|
d
|
CompoundArticle
.
find
(
d
[
"id"
]).
parts
}.
flatten
.
uniq
nems
=
[]
nems
=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"article_id_ssi:(
#{
article_ids
.
join
(
" OR "
)
}
)"
,
rows:
1000000
})[
"response"
][
"docs"
]
unless
article_ids
.
empty?
nems
+=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"article_id_ssi:(
#{
parts_ids
.
join
(
" OR "
)
}
)"
,
rows:
1000000
})[
"response"
][
"docs"
]
unless
parts_ids
.
empty?
nems
+=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
"issue_id_ssi:(
#{
issue_ids
.
join
(
" OR "
)
}
)"
,
rows:
1000000
})[
"response"
][
"docs"
]
unless
issue_ids
.
empty?
output
=
{
LOC
:
{},
PER
:
{},
ORG
:
{},
HumanProd
:
{}
}
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"LOC"
}.
each
do
|
ne_solr
|
output
[
:LOC
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:LOC
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:LOC
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"PER"
}.
each
do
|
ne_solr
|
output
[
:PER
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:PER
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:PER
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"ORG"
}.
each
do
|
ne_solr
|
output
[
:ORG
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:ORG
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:ORG
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"HumanProd"
}.
each
do
|
ne_solr
|
output
[
:HumanProd
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:HumanProd
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:HumanProd
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
output
end
end
app/models/experiment.rb
View file @
036a8957
class
Experiment
<
ActiveRecord
::
Base
belongs_to
:user
,
optional:
false
validates
:title
,
length:
{
minimum:
1
}
belongs_to
:user
,
optional:
false
validates
:title
,
length:
{
minimum:
1
}
def
add_tool
(
parent_id
,
tool
)
if
parent_id
!=
0
self
.
locate_tool
(
self
.
description
,
parent_id
)
do
|
t
|
t
[
'children'
]
<<
tool
.
to_h
end
else
self
.
description
[
'children'
]
<<
tool
.
to_h
end
def
add_tool
(
parent_id
,
tool
)
if
parent_id
!=
0
self
.
locate_tool
(
self
.
description
,
parent_id
)
do
|
t
|
t
[
"children"
]
<<
tool
.
to_h
end
else
self
.
description
[
"children"
]
<<
tool
.
to_h
end
end
def
delete_tool
(
tool_id
)
ids
=
detach_tool
(
self
.
description
,
nil
,
tool_id
)
end
def
delete_tool
(
tool_id
)
ids
=
detach_tool
(
self
.
description
,
nil
,
tool_id
)
end
def
load_tools
ids
=
gather_ids
self
.
description
Tool
.
where
(
id:
ids
).
pluck
(
:id
,
:status
,
:tool_type
,
:input_type
,
:output_type
,
:parent_id
).
map
do
|
t
|
[
t
[
0
],
{
id:
t
[
0
],
status:
t
[
1
],
type:
t
[
2
],
input_type:
t
[
3
],
output_type:
t
[
4
],
parent_id:
t
[
5
]}]
end
.
to_h
end
def
load_tools
ids
=
gather_ids
self
.
description
Tool
.
where
(
id:
ids
).
pluck
(
:id
,
:status
,
:tool_type
,
:input_type
,
:output_type
,
:parent_id
).
map
do
|
t
|
[
t
[
0
],
{
id:
t
[
0
],
status:
t
[
1
],
type:
t
[
2
],
input_type:
t
[
3
],
output_type:
t
[
4
],
parent_id:
t
[
5
]
}]
end
.
to_h
end
def
finished?
tools
=
self
.
load_tools
tools
.
values
.
all?
{
|
t
|
t
[
:status
]
==
"finished"
}
end
def
finished?
tools
=
self
.
load_tools
tools
.
values
.
all?
{
|
t
|
t
[
:status
]
==
"finished"
}
end
def
running?
tools
=
self
.
load_tools
tools
.
values
.
any?
{
|
t
|
t
[
:status
]
==
"running"
}
end
def
running?
tools
=
self
.
load_tools
tools
.
values
.
any?
{
|
t
|
t
[
:status
]
==
"running"
}
end
def
get_tool_ids
gather_ids
self
.
description
end
def
get_tool_ids
gather_ids
self
.
description
end
def
continue_from
(
tool_id
)
locate_tool
(
self
.
description
,
tool_id
)
do
|
t
|
tools_to_start
=
t
[
'children'
].
map
{
|
c
|
c
[
'tool'
][
'id'
]
}
tools_to_start
.
each
do
|
tool_id
|
tool
=
Tool
.
find
(
tool_id
)
tool
.
run
(
true
)
if
tool
.
runnable?
end
end
def
continue_from
(
tool_id
)
locate_tool
(
self
.
description
,
tool_id
)
do
|
t
|
tools_to_start
=
t
[
"children"
].
map
{
|
c
|
c
[
"tool"
][
"id"
]
}
tools_to_start
.
each
do
|
tool_id
|
tool
=
Tool
.
find
(
tool_id
)
tool
.
run
(
true
)
if
tool
.
runnable?
end
end
end
private
private
def
locate_tool
(
tree_part
,
tool_id
,
&
block
)
if
tree_part
.
has_key?
(
'tool'
)
if
tree_part
[
'tool'
][
'id'
]
==
tool_id
yield
tree_part
return
true
else
tree_part
[
'children'
].
each
do
|
subtree
|
return
true
if
locate_tool
(
subtree
,
tool_id
,
&
block
)
end
end
else
if
tree_part
[
'children'
].
empty?
yield
tree_part
end
tree_part
[
'children'
].
each
do
|
subtree
|
return
true
if
locate_tool
(
subtree
,
tool_id
,
&
block
)
end
def
locate_tool
(
tree_part
,
tool_id
,
&
block
)
if
tree_part
.
has_key?
(
"tool"
)
if
tree_part
[
"tool"
][
"id"
]
==
tool_id
yield
tree_part
return
true
else
tree_part
[
"children"
].
each
do
|
subtree
|
return
true
if
locate_tool
(
subtree
,
tool_id
,
&
block
)
end
false
end
else
if
tree_part
[
"children"
].
empty?
yield
tree_part
end
tree_part
[
"children"
].
each
do
|
subtree
|
return
true
if
locate_tool
(
subtree
,
tool_id
,
&
block
)
end
end
false
end
def
detach_tool
(
tree
,
parent_array
,
tool_id
,
&
block
)
if
tree
.
has_key?
(
'tool'
)
if
tree
[
'tool'
][
'id'
]
==
tool_id
ids
=
gather_ids
(
tree
)
parent_array
.
delete
(
tree
)
unless
parent_array
.
nil?
return
ids
else
tree
[
'children'
].
each
do
|
subtree
|
res
=
detach_tool
(
subtree
,
tree
[
'children'
],
tool_id
,
&
block
)
return
res
unless
res
.
nil?
end
end
else
tree
[
'children'
].
each
do
|
subtree
|
res
=
detach_tool
(
subtree
,
tree
[
'children'
],
tool_id
,
&
block
)
return
res
unless
res
.
nil?
end
def
detach_tool
(
tree
,
parent_array
,
tool_id
,
&
block
)
if
tree
.
has_key?
(
"tool"
)
if
tree
[
"tool"
][
"id"
]
==
tool_id
ids
=
gather_ids
(
tree
)
parent_array
.
delete
(
tree
)
unless
parent_array
.
nil?
return
ids
else
tree
[
"children"
].
each
do
|
subtree
|
res
=
detach_tool
(
subtree
,
tree
[
"children"
],
tool_id
,
&
block
)
return
res
unless
res
.
nil?
end
nil
end
else
tree
[
"children"
].
each
do
|
subtree
|
res
=
detach_tool
(
subtree
,
tree
[
"children"
],
tool_id
,
&
block
)
return
res
unless
res
.
nil?
end
end
nil
end
def
gather_ids
(
tree
,
ids
=
[])
tree
[
'children'
].
each
do
|
subtree
|
ids
.
concat
(
gather_ids
(
subtree
))
end
if
tree
.
has_key?
(
'tool'
)
ids
<<
tree
[
'tool'
][
'id'
]
end
return
ids
def
gather_ids
(
tree
,
ids
=
[])
tree
[
"children"
].
each
do
|
subtree
|
ids
.
concat
(
gather_ids
(
subtree
))
end
if
tree
.
has_key?
(
"tool"
)
ids
<<
tree
[
"tool"
][
"id"
]
end
return
ids
end
end
app/models/issue.rb
View file @
036a8957
class
Issue
attr_accessor
:id
,
:title
,
:date_created
,
:language
,
:original_uri
,
:nb_pages
,
:all_text
,
:thumbnail_url
,
:newspaper
,
:pages
,
:articles
attr_accessor
:id
,
:title
,
:date_created
,
:language
,
:original_uri
,
:nb_pages
,
:all_text
,
:thumbnail_url
,
:newspaper
,
:pages
,
:articles
def
self
.
from_solr
(
id
,
with_pages
=
false
,
with_articles
=
false
)
solr_doc
=
SolrSearcher
.
get_doc_by_id
id
Issue
.
from_solr_doc
(
solr_doc
,
with_pages
,
with_articles
)
end
def
self
.
from_solr
(
id
,
with_pages
=
false
,
with_articles
=
false
)
solr_doc
=
SolrSearcher
.
get_doc_by_id
id
Issue
.
from_solr_doc
(
solr_doc
,
with_pages
,
with_articles
)
def
self
.
from_solr_doc
(
solr_doc
,
with_pages
=
false
,
with_articles
=
false
)
i
=
Issue
.
new
i
.
id
=
solr_doc
[
"id"
]
i
.
language
=
solr_doc
[
"language_ssi"
]
i
.
newspaper
=
solr_doc
[
"member_of_collection_ids_ssim"
][
0
]
i
.
title
=
solr_doc
[
"title_ssi"
]
i
.
date_created
=
solr_doc
[
"date_created_ssi"
]
i
.
original_uri
=
solr_doc
[
"original_uri_ss"
]
i
.
nb_pages
=
solr_doc
[
"member_ids_ssim"
].
size
i
.
thumbnail_url
=
solr_doc
[
"thumbnail_url_ss"
]
i
.
all_text
=
solr_doc
[
"all_text_t
#{
i
.
language
}
_siv"
]
if
with_pages
i
.
pages
=
[]
solr_doc
[
"member_ids_ssim"
].
each
do
|
pageid
|
i
.
pages
<<
Page
.
from_solr
(
pageid
)
end
end
def
self
.
from_solr_doc
(
solr_doc
,
with_pages
=
false
,
with_articles
=
false
)
i
=
Issue
.
new
i
.
id
=
solr_doc
[
'id'
]
i
.
language
=
solr_doc
[
'language_ssi'
]
i
.
newspaper
=
solr_doc
[
'member_of_collection_ids_ssim'
][
0
]
i
.
title
=
solr_doc
[
'title_ssi'
]
i
.
date_created
=
solr_doc
[
'date_created_ssi'
]
i
.
original_uri
=
solr_doc
[
'original_uri_ss'
]
i
.
nb_pages
=
solr_doc
[
'member_ids_ssim'
].
size
i
.
thumbnail_url
=
solr_doc
[
'thumbnail_url_ss'
]
i
.
all_text
=
solr_doc
[
"all_text_t
#{
i
.
language
}
_siv"
]
if
with_pages
i
.
pages
=
[]
solr_doc
[
'member_ids_ssim'
].
each
do
|
pageid
|
i
.
pages
<<
Page
.
from_solr
(
pageid
)
end
end
if
with_articles
i
.
articles
=
[]
articles_docs
=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
[
"from_issue_ssi:
#{
i
.
id
}
"
,
"has_model_ssim:Article"
],
fl
:"*"
,
rows
:
10000
})[
'response'
][
'docs'
]
articles_docs
.
each
do
|
articles_doc
|
i
.
articles
<<
Article
.
from_solr_doc
(
articles_doc
)
end
end
i
if
with_articles
i
.
articles
=
[]
articles_docs
=
SolrSearcher
.
query
({
q:
"*:*"
,
fq:
[
"from_issue_ssi:
#{
i
.
id
}
"
,
"has_model_ssim:Article"
],
fl:
"*"
,
rows:
10000
})[
"response"
][
"docs"
]
articles_docs
.
each
do
|
articles_doc
|
i
.
articles
<<
Article
.
from_solr_doc
(
articles_doc
)
end
end
i
end
def
to_solr
solr_doc
=
{}
solr_doc
[
'
id
'
]
=
self
.
id
solr_doc
[
'
has_model_ssim
'
]
=
'
Issue
'
solr_doc
[
'
title_ssi
'
]
=
self
.
title
solr_doc
[
'
date_created_ssi
'
]
=
self
.
date_created
solr_doc
[
'
date_created_dtsi
'
]
=
DateTime
.
parse
(
self
.
date_created
).
strftime
(
'
%Y-%m-%dT%H:%M:%SZ
'
)
solr_doc
[
'
language_ssi
'
]
=
self
.
language
solr_doc
[
'
original_uri_ss
'
]
=
self
.
original_uri
solr_doc
[
'
nb_pages_isi
'
]
=
self
.
nb_pages
solr_doc
[
'
thumbnail_url_ss
'
]
=
self
.
thumbnail_url
solr_doc
[
'
member_ids_ssim
'
]
=
self
.
pages
.
map
(
&
:id
)
solr_doc
[
'
year_isi
'
]
=
solr_doc
[
'
date_created_ssi
'
][
0
..
3
].
to_i
d
=
DateTime
.
parse
solr_doc
[
"date_created_dtsi"
]
solr_doc
[
'
month_isi
'
]
=
d
.
month
solr_doc
[
'
day_isi
'
]
=
d
.
wday
solr_doc
[
"member_of_collection_ids_ssim"
]
=
self
.
newspaper
solr_doc
[
"all_text_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
[
"all_text_unstemmed_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
end
def
to_solr
solr_doc
=
{}
solr_doc
[
"
id
"
]
=
self
.
id
solr_doc
[
"
has_model_ssim
"
]
=
"
Issue
"
solr_doc
[
"
title_ssi
"
]
=
self
.
title
solr_doc
[
"
date_created_ssi
"
]
=
self
.
date_created
solr_doc
[
"
date_created_dtsi
"
]
=
DateTime
.
parse
(
self
.
date_created
).
strftime
(
"
%Y-%m-%dT%H:%M:%SZ
"
)
solr_doc
[
"
language_ssi
"
]
=
self
.
language
solr_doc
[
"
original_uri_ss
"
]
=
self
.
original_uri
solr_doc
[
"
nb_pages_isi
"
]
=
self
.
nb_pages
solr_doc
[
"
thumbnail_url_ss
"
]
=
self
.
thumbnail_url
solr_doc
[
"
member_ids_ssim
"
]
=
self
.
pages
.
map
(
&
:id
)
solr_doc
[
"
year_isi
"
]
=
solr_doc
[
"
date_created_ssi
"
][
0
..
3
].
to_i
d
=
DateTime
.
parse
solr_doc
[
"date_created_dtsi"
]
solr_doc
[
"
month_isi
"
]
=
d
.
month
solr_doc
[
"
day_isi
"
]
=
d
.
wday
solr_doc
[
"member_of_collection_ids_ssim"
]
=
self
.
newspaper
solr_doc
[
"all_text_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
[
"all_text_unstemmed_t
#{
self
.
language
}
_siv"
]
=
self
.
all_text
solr_doc
end
def
get_thumbnail
if
Rails
.
configuration
.
iiif_sources
[
:local
].
include?
self
.
newspaper
"https://iiif.newseye.eu/iiif/
#{
self
.
newspaper
}
/
#{
self
.
id
}
_page_1.ptif/full/200,/0/default.jpg"
elsif
Rails
.
configuration
.
iiif_sources
[
:external
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
# to change
elsif
Rails
.
configuration
.
iiif_sources
[
:external_onb
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
# to change
end
def
get_thumbnail
if
Rails
.
configuration
.
iiif_sources
[
:local
].
include?
self
.
newspaper
"https://iiif.newseye.eu/iiif/
#{
self
.
newspaper
}
/
#{
self
.
id
}
_page_1.ptif/full/200,/0/default.jpg"
elsif
Rails
.
configuration
.
iiif_sources
[
:external
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
# to change
elsif
Rails
.
configuration
.
iiif_sources
[
:external_onb
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
# to change
end
end
def
get_iiif_urls
if
Rails
.
configuration
.
iiif_sources
[
:local
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
do
|
p
|
"https://iiif.newseye.eu/iiif/
#{
self
.
newspaper
}
/
#{
self
.
id
}
_page_
#{
p
.
page_number
}
.ptif/info.json"
end
elsif
Rails
.
configuration
.
iiif_sources
[
:external
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
elsif
Rails
.
configuration
.
iiif_sources
[
:external_onb
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
end
iiif_pages
def
get_iiif_urls
if
Rails
.
configuration
.
iiif_sources
[
:local
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
do
|
p
|
"https://iiif.newseye.eu/iiif/
#{
self
.
newspaper
}
/
#{
self
.
id
}
_page_
#{
p
.
page_number
}
.ptif/info.json"
end
elsif
Rails
.
configuration
.
iiif_sources
[
:external
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
elsif
Rails
.
configuration
.
iiif_sources
[
:external_onb
].
include?
self
.
newspaper
iiif_pages
=
self
.
pages
.
map
{
|
p
|
"
#{
p
.
iiif_url
}
/info.json"
}
end
iiif_pages
end
def
self
.
named_entities
(
issue_id
)
nems
=
SolrSearcher
.
query
({
q
:"issue_id_ssi:
#{
issue_id
}
"
,
rows:
1000000
})[
'response'
][
'docs'
]
output
=
{
LOC
:
{},
PER
:
{},
ORG
:
{},
HumanProd
:
{}}
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"LOC"
}.
each
do
|
ne_solr
|
output
[
:LOC
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:LOC
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:LOC
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"PER"
}.
each
do
|
ne_solr
|
output
[
:PER
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:PER
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:PER
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"ORG"
}.
each
do
|
ne_solr
|
output
[
:ORG
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:ORG
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:ORG
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
'type_ssi'
]
==
"HumanProd"
}.
each
do
|
ne_solr
|
output
[
:HumanProd
][
ne_solr
[
'linked_entity_ssi'
]]
=
[]
unless
output
[
:HumanProd
].
has_key?
ne_solr
[
'linked_entity_ssi'
]
output
[
:HumanProd
][
ne_solr
[
'linked_entity_ssi'
]].
append
(
ne_solr
)
end
output
def
self
.
named_entities
(
issue_id
)
nems
=
SolrSearcher
.
query
({
q:
"issue_id_ssi:
#{
issue_id
}
"
,
rows:
1000000
})[
"response"
][
"docs"
]
output
=
{
LOC
:
{},
PER
:
{},
ORG
:
{},
HumanProd
:
{}
}
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"LOC"
}.
each
do
|
ne_solr
|
output
[
:LOC
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:LOC
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:LOC
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"PER"
}.
each
do
|
ne_solr
|
output
[
:PER
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:PER
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:PER
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"ORG"
}.
each
do
|
ne_solr
|
output
[
:ORG
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:ORG
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:ORG
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
nems
.
select
{
|
ne_solr
|
ne_solr
[
"type_ssi"
]
==
"HumanProd"
}.
each
do
|
ne_solr
|
output
[
:HumanProd
][
ne_solr
[
"linked_entity_ssi"
]]
=
[]
unless
output
[
:HumanProd
].
has_key?
ne_solr
[
"linked_entity_ssi"
]
output
[
:HumanProd
][
ne_solr
[
"linked_entity_ssi"
]].
append
(
ne_solr
)
end
end
\ No newline at end of file
output
end
end
app/models/notification.rb
View file @
036a8957
class
Notification
<
ActiveRecord
::
Base
belongs_to
:user
,
optional:
false
end
\ No newline at end of file
belongs_to
:user
,
optional:
false
end
app/models/page.rb
View file @
036a8957
class
Page
attr_accessor
:id
,
:page_number
,
:width
,
:height
,
:mime_type
,
:iiif_url
,
:ocr_path
,
:image_path
attr_accessor
:id
,
:page_number
,
:width
,
:height
,
:mime_type
,
:iiif_url
,
:ocr_path
,
:image_path
def
self
.
from_solr
(
id
)
attrs
=
SolrSearcher
.
get_doc_by_id
id
p
=
Page
.
new
p
.
id
=
attrs
[
"id"
]
p
.
page_number
=
attrs
[
"page_number_isi"
]
p
.
width
=
attrs
[
"width_isi"
]
p
.
height
=
attrs
[
"height_isi"
]
p
.
mime_type
=
attrs
[
"mime_type_ssi"
]
p
.
iiif_url
=
attrs
[
"iiif_url_ss"
]
p
.
ocr_path
=
attrs
[
"ocr_path_ss"
]
p
.
image_path
=
attrs
[
"image_path_ss"
]
if
attrs
[
"image_path_ss"
]
p
end
def
self
.
from_solr
id
attrs
=
SolrSearcher
.
get_doc_by_id
id
p
=
Page
.
new
p
.
id
=
attrs
[
'id'
]
p
.
page_number
=
attrs
[
'page_number_isi'
]
p
.
width
=
attrs
[
'width_isi'
]
p
.
height
=
attrs
[
'height_isi'
]
p
.
mime_type
=
attrs
[
'mime_type_ssi'
]
p
.
iiif_url
=
attrs
[
'iiif_url_ss'
]
p
.
ocr_path
=
attrs
[
'ocr_path_ss'
]
p
.
image_path
=
attrs
[
'image_path_ss'
]
if
attrs
[
'image_path_ss'
]
p
end
def
to_solr
solr_doc
=
{}
solr_doc
[
'id'
]
=
self
.
id
solr_doc
[
'has_model_ssim'
]
=
'PageFileSet'
solr_doc
[
'page_number_isi'
]
=
self
.
page_number
solr_doc
[
'width_isi'
]
=
self
.
width
solr_doc
[
'height_isi'
]
=
self
.
height
solr_doc
[
'mime_type_ssi'
]
=
self
.
mime_type
solr_doc
[
'iiif_url_ss'
]
=
self
.
iiif_url
solr_doc
[
'ocr_path_ss'
]
=
self
.
ocr_path
solr_doc
end
end
\ No newline at end of file
def
to_solr
solr_doc
=
{}
solr_doc
[
"id"
]
=
self
.
id
solr_doc
[
"has_model_ssim"
]
=
"PageFileSet"
solr_doc
[
"page_number_isi"
]
=
self
.
page_number
solr_doc
[
"width_isi"
]
=
self
.
width
solr_doc
[
"height_isi"
]
=
self
.
height
solr_doc
[
"mime_type_ssi"
]
=
self
.
mime_type
solr_doc
[
"iiif_url_ss"
]
=
self
.
iiif_url
solr_doc
[
"ocr_path_ss"
]
=
self
.
ocr_path
solr_doc
end
end
app/models/solr_query.rb
View file @
036a8957
class
SolrQuery
attr_accessor
:defType
,
:sort
,
:start
,
:rows
,
:fq
,
:fl
,
# common parameters
:q
,
:q_dot_alt
,
:qf
,
:mm
,
:pf
,
:ps
,
:qs
,
:tie
,
:bq
,
:bf
,
# Dismax parameters
:sow
,
:mm_dot_autorelax
,
:boost
,
:lowercaseOperators
,
:pf2
,
:ps2
,
:pf3
,
:ps3
,
:stopwords
,
:uf
,
# Edismax parameters
:facet
,
:facet_dot_field
,
:facet_dot_threads
,
:hl
,
:mlt
attr_accessor
:defType
,
:sort
,
:start
,
:rows
,
:fq
,
:fl
,
# common parameters
:q
,
:q_dot_alt
,
:qf
,
:mm
,
:pf
,
:ps
,
:qs
,
:tie
,
:bq
,
:bf
,
# Dismax parameters
:sow
,
:mm_dot_autorelax
,
:boost
,
:lowercaseOperators
,
:pf2
,
:ps2
,
:pf3
,
:ps3
,
:stopwords
,
:uf
,
# Edismax parameters
:facet
,
:facet_dot_field
,
:facet_dot_threads
,
:hl
,
:mlt
def
initialize
(
search_type
)
@defType
=
"edismax"
@sort
=
"score desc"
@start
=
0
@rows
=
10
# @fq = ["has_model_ssim:(Article OR Issue)"]
@fq
=
[
"has_model_ssim:(Article)"
]
@fl
=
"*,score"
@q
=
"*:*"
@q_dot_alt
=
"*:*"
@qf
=
I18n
.
t
(
"newspapers.solr_fields"
).
select
{
|
k
,
v
|
k
.
start_with?
(
search_type
==
"stemmed"
?
"text_stemmed"
:
"text_exact"
)
}.
values
# or text_stemmed
@mm
=
1
@pf
=
""
@ps
=
""
@qs
=
""
@tie
=
0.1
@bq
=
""
@bf
=
""
@hl
=
true
@hl_dot_fl
=
@qf
def
initialize
search_type
@defType
=
'edismax'
@sort
=
'score desc'
@start
=
0
@rows
=
10
# @fq = ["has_model_ssim:(Article OR Issue)"]
@fq
=
[
"has_model_ssim:(Article)"
]
@fl
=
'*,score'
@q
=
'*:*'
@q_dot_alt
=
'*:*'
@qf
=
I18n
.
t
(
"newspapers.solr_fields"
).
select
{
|
k
,
v
|
k
.
start_with?
(
search_type
==
"stemmed"
?
"text_stemmed"
:
"text_exact"
)
}.
values
# or text_stemmed
@mm
=
1
@pf
=
""
@ps
=
""
@qs
=
""
@tie
=
0.1
@bq
=
""
@bf
=
""
@hl
=
true
@hl_dot_fl
=
@qf
@json_dot_facet
=
{}
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:language
,
:newspaper
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
15
,
numBuckets:
true
}
}
end
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:date
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
-
1
,
numBuckets:
true
}
}
end
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:month
,
:day
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
15
,
numBuckets:
true
,
sort:
{
index:
"asc"
}}
}
end
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:persons
,
:locations
,
:organisations
,
:human_productions
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
15
,
numBuckets:
true
}
}
end
@json_dot_facet
[
"min_date"
]
=
"min(date_created_dtsi)"
@json_dot_facet
[
"max_date"
]
=
"max(date_created_dtsi)"
@json_dot_facet
=
{}
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:language
,
:newspaper
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
15
,
numBuckets:
true
}
}
end
def
to_params
p
=
self
.
instance_values
.
select
{
|
k
,
v
|
v
!=
""
and
!
v
.
nil?
}.
transform_keys
{
|
k
|
k
.
gsub
(
'_dot_'
,
'.'
)}.
with_indifferent_access
p
[
"json.facet"
]
=
p
[
"json.facet"
].
to_json
p
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:date
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
-
1
,
numBuckets:
true
}
}
end
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:month
,
:day
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
15
,
numBuckets:
true
,
sort:
{
index:
"asc"
}
}
}
end
I18n
.
t
(
"newspapers.solr_fields"
).
values_at
(
:persons
,
:locations
,
:organisations
,
:human_productions
).
each
do
|
f
|
@json_dot_facet
[
f
]
=
{
terms:
{
field:
f
,
limit:
15
,
numBuckets:
true
}
}
end
@json_dot_facet
[
"min_date"
]
=
"min(date_created_dtsi)"
@json_dot_facet
[
"max_date"
]
=
"max(date_created_dtsi)"
end
end
\ No newline at end of file
def
to_params
p
=
self
.
instance_values
.
select
{
|
k
,
v
|
v
!=
""
and
!
v
.
nil?
}.
transform_keys
{
|
k
|
k
.
gsub
(
"_dot_"
,
"."
)
}.
with_indifferent_access
p
[
"json.facet"
]
=
p
[
"json.facet"
].
to_json
p
end
end
app/models/solr_searcher.rb
View file @
036a8957
class
SolrSearcher
include
AbstractSearcher
include
AbstractSearcher
@@connection
=
false
@@connection
=
false
def
self
.
query
params
connect
unless
@@connection
puts
"[SolrSearcher.Query]
#{
params
.
to_json
}
\n
"
if
Rails
.
env
==
"development"
@@connection
.
send_and_receive
(
"select"
,
data:
params
,
method: :post
)
end
def
self
.
query
(
params
)
connect
unless
@@connection
#
puts "[SolrSearcher.Query] #{params.to_json}\n" if Rails.env == "development"
@@connection
.
send_and_receive
(
"select"
,
data:
params
,
method: :post
)
end
def
self
.
connect
@@connection
=
RSolr
.
connect
(
url:
Rails
.
configuration
.
solr
[
'
url
'
])
unless
@@connection
end
def
self
.
connect
@@connection
=
RSolr
.
connect
(
url:
Rails
.
configuration
.
solr
[
"
url
"
])
unless
@@connection
end
def
self
.
get_doc_by_id
(
id
)
connect
unless
@@connection
docs
=
@@connection
.
send_and_receive
(
"select"
,
data:
{
q:
"id:
#{
id
}
"
},
method: :post
)[
'response'
][
'docs'
]
if
docs
.
empty?
nil
else
docs
[
0
]
end
def
self
.
get_doc_by_id
(
id
)
connect
unless
@@connection
docs
=
@@connection
.
send_and_receive
(
"select"
,
data:
{
q:
"id:
#{
id
}
"
},
method: :post
)[
"response"
][
"docs"
]
if
docs
.
empty?
nil
else
docs
[
0
]
end
end
\ No newline at end of file
end
end
app/models/tool.rb
View file @
036a8957
class
Tool
<
ActiveRecord
::
Base
belongs_to
:experiment
,
optional:
false
belongs_to
:experiment
,
optional:
false
def
to_h
{
def
to_h
{
"tool"
:
{
"id"
:
self
.
id
"id"
:
self
.
id
,
},
"children"
:
[]
"children"
:
[]
,
}
end
def
runnable?
self
.
status
==
"configured"
&&
(
self
.
parent_id
.
nil?
||
Tool
.
find
(
self
.
parent_id
).
status
==
"finished"
)
end
end
def
run
(
continue
=
false
)
"
#{
self
.
tool_type
}
_worker"
.
camelize
.
constantize
.
perform_async
(
self
.
id
,
self
.
experiment
.
user
.
id
,
self
.
experim
ent
.
id
,
self
.
tool_type
,
self
.
parameters
,
continue
)
end
def
run
nable?
self
.
status
==
"configured"
&&
(
self
.
parent_id
.
nil?
||
Tool
.
find
(
self
.
par
ent
_
id
).
status
==
"finished"
)
end
def
run
(
continue
=
false
)
"
#{
self
.
tool_type
}
_worker"
.
camelize
.
constantize
.
perform_async
(
self
.
id
,
self
.
experiment
.
user
.
id
,
self
.
experiment
.
id
,
self
.
tool_type
,
self
.
parameters
,
continue
)
end
end
app/models/user.rb
View file @
036a8957
class
User
<
ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise
:database_authenticatable
,
:registerable
,
:recoverable
,
:rememberable
,
:validatable
attribute
:labs_user_id
,
presence:
true
,
unique:
true
attribute
:labs_user_name
,
presence:
true
,
unique:
true
has_many
:experiments
has_many
:datasets
has_many
:notifications
has_many
:compound_articles
has_many
:experiments
has_many
:datasets
has_many
:notifications
has_many
:compound_articles
has_many
:active_sessions
def
datasets_with_doc
doc_id
self
.
datasets
.
map
do
|
dataset
|
[
dataset
.
id
,
dataset
.
title
]
if
dataset
.
contains
doc_id
.
to_s
end
.
delete_if
(
&
:nil?
)
end
def
compounds_by_issue
out
=
{}
self
.
compound_articles
.
each
do
|
compound_article
|
out
[
compound_article
.
issue_id
]
=
[]
unless
out
.
has_key?
compound_article
.
issue_id
out
[
compound_article
.
issue_id
]
<<
compound_article
end
out
end
def
datasets_with_doc
(
doc_id
)
self
.
datasets
.
map
do
|
dataset
|
[
dataset
.
id
,
dataset
.
title
]
if
dataset
.
contains
doc_id
.
to_s
end
.
delete_if
(
&
:nil?
)
end
def
researcher?
Rails
.
configuration
.
auths
[
'emails'
].
include?
self
.
email
def
compounds_by_issue
out
=
{}
self
.
compound_articles
.
each
do
|
compound_article
|
out
[
compound_article
.
issue_id
]
=
[]
unless
out
.
has_key?
compound_article
.
issue_id
out
[
compound_article
.
issue_id
]
<<
compound_article
end
out
end
def
researcher?
Rails
.
configuration
.
auths
[
"emails"
].
include?
self
.
email
end
end
app/views/catalog/_compound_articles_panel.html.erb
View file @
036a8957
...
...
@@ -7,9 +7,9 @@
<div
class=
"p-0 card-body d-flex align-items-center justify-content-center flex-column"
>
<ul
class=
"list-group w-100"
>
<%
compound_articles
.
each
do
|
compound_article
|
%>
<li
class=
"list-group-item cmpnd-article"
data-compound-id=
"
<%=
compound_article
.
id
%>
"
data-parts=
"
<%=
compound_article
.
parts
.
to_json
%>
"
>
<li
class=
"list-group-item cmpnd-article"
data-compound-id=
"
<%=
compound_article
.
id
%>
"
data-parts=
"
<%=
compound_article
.
parts
.
to_json
%>
"
data-title=
"
<%=
compound_article
.
title
%>
"
>
<div
class=
"text_part d-inline"
>
<%=
compound_article
.
title
%>
</div>
<a
class=
"delete_compound_article text-danger float-end"
href=
"#"
><span
class=
"fas fa-t
imes
"
></span></a>
<a
class=
"delete_compound_article text-danger float-end"
href=
"#"
><span
class=
"fas fa-t
rash
"
></span></a>
</li>
<%
end
%>
</ul>
...
...
app/views/catalog/_date_facet.html.erb
View file @
036a8957
...
...
@@ -15,7 +15,7 @@
<div
class=
"accordion-body"
data-controller=
"date-facets"
data-date-facets-max-date-value=
"
<%=
datepicker_max_date
%>
"
data-date-facets-min-date-value=
"
<%=
datepicker_min_date
%>
"
>
<form
action=
"/search"
method=
"get"
>
<form
action=
"
.
/search"
method=
"get"
>
<div
class=
"input-group mb-2"
>
<span
class=
"input-group-text"
>
From
</span>
<input
class=
"form-control"
type=
"date"
id=
"date_facet_from"
name=
"f[date_created_dtsi][from]"
...
...
Prev
1
2
3
4
5
Next