diff --git a/CHANGES.rst b/CHANGES.rst
index 90067c5c..cbe9e04e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,11 @@
+2.1.1 (01-08-2023)
+------------------
+
+- ConceptVisitLog has an integer concept_id in the ConceptVisitLog class #906
+- skosprovider route /expand does not work #903
+- Manual ID text box not writable #902
+
+
2.1.0 (22-07-2023)
------------------
diff --git a/CITATION.cff b/CITATION.cff
index 4997dc38..0a7484f7 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -88,5 +88,5 @@ keywords:
- vocabulary
- python
license: GPL-3.0
-version: 2.1.0
+version: 2.1.1
date-released: '2024-06-20'
diff --git a/atramhasis/__init__.py b/atramhasis/__init__.py
index a74f60df..15cd5a36 100644
--- a/atramhasis/__init__.py
+++ b/atramhasis/__init__.py
@@ -34,6 +34,8 @@ def includeme(config):
for key, value in DEFAULT_SETTINGS.items():
if key not in settings:
settings[key] = value
+ # Regexes in path params clash with this validation.
+ settings["pyramid_openapi3.enable_endpoint_validation"] = False
configure_session(config)
config.include('pyramid_jinja2')
config.include('pyramid_tm')
@@ -44,9 +46,10 @@ def includeme(config):
config.include('pyramid_rewrite')
config.include("pyramid_openapi3")
config.include('atramhasis.routes')
+ # pyramid_skosprovider must be included after the atramhasis routes
+ # because it contains a regex in the path which consumes a lot of routes.
config.include('pyramid_skosprovider')
config.include('atramhasis.cache')
- config.scan('pyramid_skosprovider')
config.add_translation_dirs('atramhasis:locale/')
diff --git a/atramhasis/alembic/versions/29306f749043_alter_conceptvisitlog_concept_id_to_.py b/atramhasis/alembic/versions/29306f749043_alter_conceptvisitlog_concept_id_to_.py
new file mode 100644
index 00000000..6b2059b3
--- /dev/null
+++ b/atramhasis/alembic/versions/29306f749043_alter_conceptvisitlog_concept_id_to_.py
@@ -0,0 +1,30 @@
+"""alter ConceptVisitLog concept_id to string
+
+Revision ID: 29306f749043
+Revises: b2a7d7614973
+Create Date: 2024-07-30 09:12:37.521748
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '29306f749043'
+down_revision = 'b2a7d7614973'
+
+
+def upgrade():
+ with op.batch_alter_table('concept_visit_log') as batch_op:
+ batch_op.alter_column('concept_id', type_=sa.String, existing_type=sa.Integer)
+
+
+def downgrade():
+ # Drop concept_visit_log which have non-integer concept_id
+ op.execute(
+ "DELETE FROM concept_visit_log "
+ "WHERE cast(cast(concept_id AS INTEGER) AS TEXT) != concept_id"
+ )
+ with op.batch_alter_table('concept_visit_log') as batch_op:
+ batch_op.alter_column('concept_id', type_=sa.Integer, existing_type=sa.String)
diff --git a/atramhasis/data/models.py b/atramhasis/data/models.py
index a00bcf84..ca3b3876 100644
--- a/atramhasis/data/models.py
+++ b/atramhasis/data/models.py
@@ -39,7 +39,7 @@ class ConceptschemeVisitLog(Base):
class ConceptVisitLog(Base):
__tablename__ = 'concept_visit_log'
id = Column(Integer, primary_key=True, autoincrement=True)
- concept_id = Column(Integer, nullable=False)
+ concept_id = Column(String, nullable=False)
conceptscheme_id = Column(String(25), nullable=False)
visited_at = Column(DateTime, default=func.now(), nullable=False)
origin = Column(String(25), nullable=False)
diff --git a/atramhasis/openapi.yaml b/atramhasis/openapi.yaml
index 5bb4ef7b..637beb82 100644
--- a/atramhasis/openapi.yaml
+++ b/atramhasis/openapi.yaml
@@ -2,7 +2,7 @@ openapi: 3.0.3
info:
title: Atramhasis API
- version: 2.1.0
+ version: 2.1.1
servers:
- url: '/'
@@ -142,7 +142,7 @@ paths:
description: The identifier for a certain concept or collection.
required: true
schema:
- type: integer
+ type: string
responses:
200:
description: The concept was found in the conceptscheme.
@@ -172,7 +172,7 @@ paths:
description: The identifier for a certain concept or collection.
required: true
schema:
- type: integer
+ type: string
requestBody:
required: true
description: Data to create concept or collection
@@ -222,7 +222,7 @@ paths:
description: The identifier for a certain concept or collection.
required: true
schema:
- type: integer
+ type: string
responses:
200:
@@ -692,7 +692,7 @@ paths:
description: The identifier for a certain concept or collection.
required: true
schema:
- type: integer
+ type: string
- name: language
in: query
description: Returns the label with the corresponding language-tag if present.
@@ -748,7 +748,7 @@ paths:
description: The identifier for a certain concept or collection.
required: true
schema:
- type: integer
+ type: string
responses:
200:
description: The concept/collection was found in the conceptscheme.
@@ -900,7 +900,7 @@ components:
type: object
properties:
id:
- type: integer
+ type: string
Label:
type: object
properties:
@@ -952,7 +952,7 @@ components:
type: object
properties:
id:
- type: integer
+ type: string
type:
type: string
labels:
@@ -990,7 +990,7 @@ components:
- type: object
properties:
id:
- type: integer
+ type: string
uri:
type: string
ConceptTree:
diff --git a/atramhasis/rdf.py b/atramhasis/rdf.py
index ea45d58c..4232b556 100644
--- a/atramhasis/rdf.py
+++ b/atramhasis/rdf.py
@@ -76,12 +76,12 @@ def _add_provider(graph, provider, dataseturi, request):
graph.add((dataseturi, VOID.subset, pd))
graph.add((pd, DCTERMS.identifier, Literal(pid)))
graph.add((pd, VOID.rootResource, URIRef(provider.concept_scheme.uri)))
- graph.add((pd, FOAF.homepage, URIRef(request.route_url('conceptscheme', scheme_id=pid))))
+ graph.add((pd, FOAF.homepage, URIRef(request.route_url('skosprovider.conceptscheme', scheme_id=pid))))
_add_labels(graph, provider.concept_scheme, pd)
_add_metadataset(graph, pd, metadataset)
fmap = [
- ('rdf', FORMATS.RDF_XML, 'atramhasis.rdf_full_export_ext'),
- ('ttl', FORMATS.Turtle, 'atramhasis.rdf_full_export_turtle_ext')
+ ('rdf', FORMATS.RDF_XML, 'skosprovider.conceptscheme.cs.rdf'),
+ ('ttl', FORMATS.Turtle, 'skosprovider.conceptscheme.cs.ttl')
]
for f in fmap:
graph.add((pd, VOID.feature, f[1]))
diff --git a/atramhasis/routes.py b/atramhasis/routes.py
index 7af7751b..f5d98938 100644
--- a/atramhasis/routes.py
+++ b/atramhasis/routes.py
@@ -27,38 +27,22 @@ def includeme(config):
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route("sitemap", "/sitemap_index.xml")
+ # APIs with extensions instead of accept headers
config.add_route('atramhasis.rdf_void_turtle_ext', pattern='/void.ttl', accept='text/turtle')
- config.add_route('atramhasis.rdf_full_export_ext', pattern='/conceptschemes/{scheme_id}/c.rdf')
- config.add_route('atramhasis.rdf_full_export_turtle_ext', pattern='/conceptschemes/{scheme_id}/c.ttl')
- config.add_route('atramhasis.rdf_conceptscheme_export_ext', pattern='/conceptschemes/{scheme_id}.rdf')
- config.add_route('atramhasis.rdf_conceptscheme_export_turtle_ext', pattern='/conceptschemes/{scheme_id}.ttl')
- config.add_route('atramhasis.rdf_individual_export_ext', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}.rdf')
- config.add_route('atramhasis.rdf_individual_export_turtle_ext', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}.ttl')
- config.add_route('atramhasis.rdf_conceptscheme_jsonld_ext', pattern='/conceptschemes/{scheme_id}.jsonld')
- config.add_route('atramhasis.rdf_individual_jsonld_ext', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}.jsonld')
+ # The routes below extend the existing skosprovider routes with extensions
+ config.add_route('skosprovider.conceptscheme.cs.rdf', pattern='/conceptschemes/{scheme_id}/c.rdf')
+ config.add_route('skosprovider.conceptscheme.cs.ttl', pattern='/conceptschemes/{scheme_id}/c.ttl')
+ config.add_route('skosprovider.conceptscheme.rdf', pattern='/conceptschemes/{scheme_id}.rdf')
+ config.add_route('skosprovider.conceptscheme.ttl', pattern='/conceptschemes/{scheme_id}.ttl')
+ config.add_route('skosprovider.conceptscheme.csv', pattern='/conceptschemes/{scheme_id}/c.csv')
+ config.add_route('skosprovider.c.rdf', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}.rdf')
+ config.add_route('skosprovider.c.ttl', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}.ttl')
- config.add_route('conceptschemes', pattern='/conceptschemes', accept='text/html', request_method="GET")
- config.add_route('conceptscheme', pattern='/conceptschemes/{scheme_id}', accept='text/html', request_method="GET")
- config.add_route('concept', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}', accept='text/html',
- request_method="GET")
- config.add_route('search_result', pattern='/conceptschemes/{scheme_id}/c', accept='text/html')
- config.add_route('scheme_root', pattern='/conceptschemes/{scheme_id}/c/', accept='text/html')
+ # tree
config.add_route('scheme_tree_html', pattern='/conceptschemes/{scheme_id}/tree', accept='text/html')
config.add_route('scheme_tree', pattern='/conceptschemes/{scheme_id}/tree', accept='application/json')
- config.add_route('search_result_export', pattern='/conceptschemes/{scheme_id}/c.csv')
- config.add_route('atramhasis.edit_conceptscheme', pattern='/conceptschemes/{scheme_id}',
- accept='application/json', request_method='PUT')
- config.add_route('atramhasis.get_conceptscheme', pattern='/conceptschemes/{scheme_id}', accept='application/json')
- config.add_route('atramhasis.get_conceptschemes', pattern='/conceptschemes', accept='application/json')
- config.add_route('atramhasis.get_concept', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='application/json', request_method="GET")
- config.add_route('atramhasis.add_concept', pattern='/conceptschemes/{scheme_id}/c', accept='application/json',
- request_method="POST")
- config.add_route('atramhasis.edit_concept', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='application/json', request_method="PUT")
- config.add_route('atramhasis.delete_concept', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='application/json', request_method="DELETE")
+ # language
config.add_route('atramhasis.list_languages', pattern='/languages', accept='application/json',
request_method="GET")
config.add_route('atramhasis.get_language', pattern='/languages/{l_id}', accept='application/json',
@@ -68,33 +52,16 @@ def includeme(config):
config.add_route('atramhasis.delete_language', pattern='/languages/{l_id}', accept='application/json',
request_method="DELETE")
config.add_route('locale', '/locale')
- config.add_route('labeltypes', '/labeltypes', accept='application/json', request_method="GET")
- config.add_route('notetypes', '/notetypes', accept='application/json', request_method="GET")
+ # admin
config.add_route('admin', '/admin')
config.add_route('scheme_tree_invalidate', pattern='/admin/tree/invalidate/{scheme_id}', accept='application/json')
config.add_route('tree_invalidate', pattern='/admin/tree/invalidate', accept='application/json')
- config.add_route('atramhasis.rdf_full_export_turtle', pattern='/conceptschemes/{scheme_id}/c', accept='text/turtle')
- config.add_route('atramhasis.rdf_full_export_turtle_x', pattern='/conceptschemes/{scheme_id}/c',
- accept='application/x-turtle')
- config.add_route('atramhasis.rdf_full_export', pattern='/conceptschemes/{scheme_id}/c',
- accept='application/rdf+xml')
- config.add_route('atramhasis.rdf_conceptscheme_export', pattern='/conceptschemes/{scheme_id}',
- accept='application/rdf+xml')
- config.add_route('atramhasis.rdf_conceptscheme_export_turtle', pattern='/conceptschemes/{scheme_id}',
- accept='text/turtle')
- config.add_route('atramhasis.rdf_conceptscheme_export_turtle_x', pattern='/conceptschemes/{scheme_id}',
- accept='application/x-turtle')
- config.add_route('atramhasis.rdf_individual_export', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='application/rdf+xml')
- config.add_route('atramhasis.rdf_individual_export_turtle', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='text/turtle')
- config.add_route('atramhasis.rdf_individual_export_turtle_x', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='application/x-turtle')
- config.add_route('atramhasis.rdf_conceptscheme_jsonld', pattern='/conceptschemes/{scheme_id}',
- accept='application/ld+json')
- config.add_route('atramhasis.rdf_individual_jsonld', pattern='/conceptschemes/{scheme_id}/c/{c_id:.*}',
- accept='application/ld+json')
+ # providers
config.add_route('atramhasis.providers', pattern='/providers')
config.add_route('atramhasis.provider', pattern='/providers/{id}')
+
+ # other
+ config.add_route('labeltypes', '/labeltypes', accept='application/json', request_method="GET")
+ config.add_route('notetypes', '/notetypes', accept='application/json', request_method="GET")
diff --git a/atramhasis/static/admin/package-lock.json b/atramhasis/static/admin/package-lock.json
index d53b031c..fc2ab86a 100644
--- a/atramhasis/static/admin/package-lock.json
+++ b/atramhasis/static/admin/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "atramhasis",
- "version": "2.1.0",
+ "version": "2.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "atramhasis",
- "version": "2.1.0",
+ "version": "2.1.1",
"dependencies": {
"dgrid": "~1.2.1",
"dGrowl": "https://github.com/stratease/dGrowl#0.1.3",
diff --git a/atramhasis/static/admin/package.json b/atramhasis/static/admin/package.json
index 2ec1da6f..4913e87a 100644
--- a/atramhasis/static/admin/package.json
+++ b/atramhasis/static/admin/package.json
@@ -1,6 +1,6 @@
{
"name": "atramhasis",
- "version": "2.1.0",
+ "version": "2.1.1",
"description": "Node packages for building Atramhasis.",
"repository": {
"type": "git",
diff --git a/atramhasis/static/admin/src/app/ui/dialogs/ManageProvidersDialog.js b/atramhasis/static/admin/src/app/ui/dialogs/ManageProvidersDialog.js
index ad1c2945..1993f8ce 100644
--- a/atramhasis/static/admin/src/app/ui/dialogs/ManageProvidersDialog.js
+++ b/atramhasis/static/admin/src/app/ui/dialogs/ManageProvidersDialog.js
@@ -349,8 +349,18 @@ define([
'sticky': false,
'channel': 'info'
});
- this._reset(true);
- this.parentNode.refresh_conceptschemes();
+ // Update the provider lists with the new data
+ this.providerController.loadProviders().then(lang.hitch(this, function() {
+ this._reset(true);
+ this.parentNode.refresh_conceptschemes();
+ }), lang.hitch(this, function (error) {
+ var message = this._parseError(error);
+ topic.publish('dGrowl', message, {
+ 'title': 'Error updating provider list',
+ 'sticky': true,
+ 'channel': 'error'
+ });
+ }));
}),
lang.hitch(this, function (error) {
var message = this._parseError(error);
@@ -372,7 +382,17 @@ define([
'sticky': false,
'channel': 'info'
});
- this._reset();
+ // Update the provider lists with the updated data
+ this.providerController.loadProviders().then(lang.hitch(this, function() {
+ this._reset();
+ }), lang.hitch(this, function (error) {
+ var message = this._parseError(error);
+ topic.publish('dGrowl', message, {
+ 'title': 'Error updating provider list',
+ 'sticky': true,
+ 'channel': 'error'
+ });
+ }));
}),
lang.hitch(this, function (error) {
var message = this._parseError(error);
diff --git a/atramhasis/static/package-lock.json b/atramhasis/static/package-lock.json
index 835a6c60..655ebb1e 100644
--- a/atramhasis/static/package-lock.json
+++ b/atramhasis/static/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "atramhasis",
- "version": "2.1.0",
+ "version": "2.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "atramhasis",
- "version": "2.1.0",
+ "version": "2.1.1",
"dependencies": {
"d3": "~3.5.17",
"font-awesome": "~4.7.0",
diff --git a/atramhasis/static/package.json b/atramhasis/static/package.json
index da9683a4..2f2cad79 100644
--- a/atramhasis/static/package.json
+++ b/atramhasis/static/package.json
@@ -1,6 +1,6 @@
{
"name": "atramhasis",
- "version": "2.1.0",
+ "version": "2.1.1",
"description": "Node packages for public part of Atramhasis.",
"repository": {
"type": "git",
diff --git a/atramhasis/templates/concept.jinja2 b/atramhasis/templates/concept.jinja2
index eac6df5e..53db291d 100644
--- a/atramhasis/templates/concept.jinja2
+++ b/atramhasis/templates/concept.jinja2
@@ -2,7 +2,7 @@
{% block head %}
{{ super() }}
-
+
{% if concept.notes|length > 0 %}
@@ -13,7 +13,7 @@
{% if concept.notes|length > 0 %}
{% endif %}
-
+
{% endblock %}
{% block html_title %}{{ concept.label(locale).label|title }}{% endblock %}
@@ -31,9 +31,9 @@
{% if concept %}
@@ -53,7 +53,7 @@
{{ concept.uri }}
{% endif %}
schema
- {{ get_conceptscheme_label(concept.conceptscheme, request.locale_name) }}
+ {{ get_conceptscheme_label(concept.conceptscheme, request.locale_name) }}
{% if concept.labels %}
{{ print_labels(concept.labels) }}
{% endif %}
diff --git a/atramhasis/templates/conceptscheme.jinja2 b/atramhasis/templates/conceptscheme.jinja2
index 27625ab5..f0591c06 100644
--- a/atramhasis/templates/conceptscheme.jinja2
+++ b/atramhasis/templates/conceptscheme.jinja2
@@ -2,7 +2,7 @@
{% block head %}
{{ super() }}
-
+
{% if conceptscheme.notes|length > 0 %}
@@ -13,7 +13,7 @@
{% if conceptscheme.notes|length > 0 %}
{% endif %}
-
+
{% endblock %}
{% block html_title %}{{ conceptscheme.title }}{% endblock %}
@@ -29,11 +29,11 @@
diff --git a/atramhasis/templates/conceptschemes.jinja2 b/atramhasis/templates/conceptschemes.jinja2
index 493de4db..b1626b39 100644
--- a/atramhasis/templates/conceptschemes.jinja2
+++ b/atramhasis/templates/conceptschemes.jinja2
@@ -12,7 +12,7 @@
{% trans %}select_scheme{% endtrans %}
{% for item in conceptschemes %}
-
+
{% endfor %}
diff --git a/atramhasis/templates/conceptschemes_overview.jinja2 b/atramhasis/templates/conceptschemes_overview.jinja2
index 7da99264..481f701c 100644
--- a/atramhasis/templates/conceptschemes_overview.jinja2
+++ b/atramhasis/templates/conceptschemes_overview.jinja2
@@ -6,7 +6,7 @@
{% for item in conceptschemes %}
-
+
{% endfor %}
\ No newline at end of file
diff --git a/atramhasis/templates/header-page.jinja2 b/atramhasis/templates/header-page.jinja2
index f0fefa0e..e3b6436e 100644
--- a/atramhasis/templates/header-page.jinja2
+++ b/atramhasis/templates/header-page.jinja2
@@ -22,7 +22,7 @@
{% trans %}select_scheme{% endtrans %}
{% for item in conceptschemes %}
-
+
{{ get_conceptscheme_label(item.conceptscheme, request.locale_name) }}
{% endfor %}
diff --git a/atramhasis/templates/macros.jinja2 b/atramhasis/templates/macros.jinja2
index 4f3bbfcc..54e84033 100644
--- a/atramhasis/templates/macros.jinja2
+++ b/atramhasis/templates/macros.jinja2
@@ -5,7 +5,7 @@
{%- for c in relaties|label_sort(language=locale) %}
{%- set counter = counter + 1 %}
{%- endfor %}
@@ -127,7 +127,7 @@
{%- set counter = 0 %}
{%- for concept in concepts|label_sort(language=request.locale_name) %}
{%- set counter = counter + 1 %}
-
+
{%- endfor %}
{% endmacro %}
@@ -136,7 +136,7 @@
{% set conceptLabel = request.skos_registry.get_provider(scheme_id).get_by_id(c['concept_id']) %}
{% if conceptLabel and conceptLabel.label() %}
diff --git a/atramhasis/templates/search_form.jinja2 b/atramhasis/templates/search_form.jinja2
index 5d7b4ae1..60a2019f 100644
--- a/atramhasis/templates/search_form.jinja2
+++ b/atramhasis/templates/search_form.jinja2
@@ -10,7 +10,7 @@
{% trans %}select_scheme{% endtrans %}
{% for item in conceptschemes %}
-
+
{{ get_conceptscheme_label(item.conceptscheme, request.locale_name) }}
{% endfor %}
diff --git a/atramhasis/templates/search_result.jinja2 b/atramhasis/templates/search_result.jinja2
index 39d9b58e..bcd1ec81 100644
--- a/atramhasis/templates/search_result.jinja2
+++ b/atramhasis/templates/search_result.jinja2
@@ -15,7 +15,7 @@
{%- for c in concepts %}
-
+
{%- endfor %}
diff --git a/atramhasis/templates/subfooter-page.jinja2 b/atramhasis/templates/subfooter-page.jinja2
index 81393169..2705abd5 100644
--- a/atramhasis/templates/subfooter-page.jinja2
+++ b/atramhasis/templates/subfooter-page.jinja2
@@ -22,7 +22,7 @@
{% trans %}select_scheme{% endtrans %}
diff --git a/atramhasis/templates/tree.jinja2 b/atramhasis/templates/tree.jinja2
index c9a1a9b5..0ac83d76 100644
--- a/atramhasis/templates/tree.jinja2
+++ b/atramhasis/templates/tree.jinja2
@@ -213,7 +213,7 @@
function openConcept(d) {
d3.event.preventDefault();
if (d.concept_id) {
- var basepath = '{{ request.route_path('concept', scheme_id= scheme_id, c_id = '') }}';
+ var basepath = '{{ request.route_path('skosprovider.c', scheme_id= scheme_id, c_id = '') }}';
window.location.href = basepath + d.concept_id +'?view_tree';
}
else {
diff --git a/atramhasis/views/crud.py b/atramhasis/views/crud.py
index 94eab295..cee2b94e 100644
--- a/atramhasis/views/crud.py
+++ b/atramhasis/views/crud.py
@@ -104,14 +104,12 @@ def _validate_conceptscheme(self, json_conceptscheme):
)
@audit
- @view_config(route_name='atramhasis.get_conceptscheme', permission='view')
+ @view_config(route_name='skosprovider.conceptscheme', permission='view', request_method='GET')
def get_conceptscheme(self):
- if self.request.method == 'DELETE':
- raise HTTPMethodNotAllowed
- # is the same as the pyramid_skosprovider get_conceptscheme function, but wrapped with the audit function
+ # is the same as pyramid_skosprovider but wrapped with the audit decorator
return ProviderView(self.request).get_conceptscheme()
- @view_config(route_name='atramhasis.edit_conceptscheme', permission='edit')
+ @view_config(route_name='skosprovider.conceptscheme', permission='edit', request_method='PUT')
def edit_conceptscheme(self):
"""
Edit an existing concept
@@ -125,16 +123,8 @@ def edit_conceptscheme(self):
self.request.response.status = '200'
return conceptscheme
- @view_config(route_name='atramhasis.get_conceptschemes', permission='view')
- def get_conceptschemes(self):
- if self.request.method == 'POST':
- raise HTTPMethodNotAllowed
- # is the same as the pyramid_skosprovider get_conceptscheme function, method not allowed included
- from pyramid_skosprovider.views import ProviderView
- return ProviderView(self.request).get_conceptschemes()
-
@audit
- @view_config(route_name='atramhasis.get_concept', permission='view')
+ @view_config(route_name='skosprovider.c', permission='view', request_method='GET')
def get_concept(self):
"""
Get an existing concept
@@ -156,7 +146,7 @@ def get_concept(self):
return concept
@internal_providers_only
- @view_config(route_name='atramhasis.add_concept', permission='edit')
+ @view_config(route_name='skosprovider.conceptscheme.cs', permission='edit', request_method='POST')
def add_concept(self):
"""
Add a new concept to a conceptscheme
@@ -217,7 +207,7 @@ def add_concept(self):
return from_thing(concept)
@internal_providers_only
- @view_config(route_name='atramhasis.edit_concept', permission='edit')
+ @view_config(route_name='skosprovider.c', permission='edit', request_method='PUT')
def edit_concept(self):
"""
Edit an existing concept
@@ -242,7 +232,7 @@ def edit_concept(self):
@internal_providers_only
@protected_operation
- @view_config(route_name='atramhasis.delete_concept', permission='delete')
+ @view_config(route_name='skosprovider.c', permission='delete', request_method='DELETE')
def delete_concept(self):
"""
Delete an existing concept
diff --git a/atramhasis/views/rdf.py b/atramhasis/views/rdf.py
index f68b6d14..826e9429 100644
--- a/atramhasis/views/rdf.py
+++ b/atramhasis/views/rdf.py
@@ -53,8 +53,8 @@ def __init__(self, request):
raise ConceptNotFoundException(self.c_id)
@audit
- @view_config(route_name='atramhasis.rdf_full_export')
- @view_config(route_name='atramhasis.rdf_full_export_ext')
+ @view_config(route_name='skosprovider.conceptscheme.cs', accept='application/rdf+xml')
+ @view_config(route_name='skosprovider.conceptscheme.cs.rdf')
def rdf_full_export(self):
dump_location = self.request.registry.settings['atramhasis.dump_location']
filename = os.path.join(dump_location, '%s-full.rdf' % self.scheme_id)
@@ -66,9 +66,9 @@ def rdf_full_export(self):
)
@audit
- @view_config(route_name='atramhasis.rdf_full_export_turtle')
- @view_config(route_name='atramhasis.rdf_full_export_turtle_x')
- @view_config(route_name='atramhasis.rdf_full_export_turtle_ext')
+ @view_config(route_name='skosprovider.conceptscheme.cs', accept='text/turtle')
+ @view_config(route_name='skosprovider.conceptscheme.cs', accept='application/x-turtle')
+ @view_config(route_name='skosprovider.conceptscheme.cs.ttl')
def rdf_full_export_turtle(self):
dump_location = self.request.registry.settings['atramhasis.dump_location']
filename = os.path.join(dump_location, '%s-full.ttl' % self.scheme_id)
@@ -80,8 +80,8 @@ def rdf_full_export_turtle(self):
)
@audit
- @view_config(route_name='atramhasis.rdf_conceptscheme_export')
- @view_config(route_name='atramhasis.rdf_conceptscheme_export_ext')
+ @view_config(route_name='skosprovider.conceptscheme', accept='application/rdf+xml')
+ @view_config(route_name='skosprovider.conceptscheme.rdf')
def rdf_conceptscheme_export(self):
graph = utils.rdf_conceptscheme_dumper(self.provider)
response = Response(content_type='application/rdf+xml')
@@ -89,9 +89,9 @@ def rdf_conceptscheme_export(self):
response.content_disposition = 'attachment; filename="{}.rdf"'.format(str(self.scheme_id))
return response
- @view_config(route_name='atramhasis.rdf_conceptscheme_export_turtle')
- @view_config(route_name='atramhasis.rdf_conceptscheme_export_turtle_x')
- @view_config(route_name='atramhasis.rdf_conceptscheme_export_turtle_ext')
+ @view_config(route_name='skosprovider.conceptscheme', accept='text/turtle')
+ @view_config(route_name='skosprovider.conceptscheme', accept='application/x-turtle')
+ @view_config(route_name='skosprovider.conceptscheme.ttl')
def rdf_conceptscheme_export_turtle(self):
graph = utils.rdf_conceptscheme_dumper(self.provider)
response = Response(content_type='text/turtle')
@@ -100,8 +100,8 @@ def rdf_conceptscheme_export_turtle(self):
return response
@audit
- @view_config(route_name='atramhasis.rdf_individual_export')
- @view_config(route_name='atramhasis.rdf_individual_export_ext')
+ @view_config(route_name='skosprovider.c', accept='application/rdf+xml')
+ @view_config(route_name='skosprovider.c.rdf')
def rdf_individual_export(self):
graph = utils.rdf_c_dumper(self.provider, self.c_id)
response = Response(content_type='application/rdf+xml')
@@ -110,9 +110,9 @@ def rdf_individual_export(self):
return response
@audit
- @view_config(route_name='atramhasis.rdf_individual_export_turtle')
- @view_config(route_name='atramhasis.rdf_individual_export_turtle_x')
- @view_config(route_name='atramhasis.rdf_individual_export_turtle_ext')
+ @view_config(route_name='skosprovider.c', accept='text/turtle')
+ @view_config(route_name='skosprovider.c', accept='application/x-turtle')
+ @view_config(route_name='skosprovider.c.ttl')
def rdf_individual_export_turtle(self):
graph = utils.rdf_c_dumper(self.provider, self.c_id)
response = Response(content_type='text/turtle')
@@ -121,8 +121,8 @@ def rdf_individual_export_turtle(self):
return response
@audit
- @view_config(route_name='atramhasis.rdf_conceptscheme_jsonld', permission='view')
- @view_config(route_name='atramhasis.rdf_conceptscheme_jsonld_ext', permission='view')
+ @view_config(route_name='skosprovider.conceptscheme', permission='view', accept='application/ld+json')
+ @view_config(route_name='skosprovider.conceptscheme.jsonld', permission='view')
def get_conceptscheme_jsonld(self):
conceptscheme = ProviderView(self.request).get_conceptscheme_jsonld()
response = Response(content_type='application/ld+json')
@@ -131,8 +131,8 @@ def get_conceptscheme_jsonld(self):
return response
@audit
- @view_config(route_name='atramhasis.rdf_individual_jsonld', permission='view')
- @view_config(route_name='atramhasis.rdf_individual_jsonld_ext', permission='view')
+ @view_config(route_name='skosprovider.c', permission='view', accept='application/ld+json')
+ @view_config(route_name='skosprovider.c.jsonld', permission='view')
def get_concept(self):
concept = ProviderView(self.request).get_concept()
response = Response(content_type='application/ld+json')
diff --git a/atramhasis/views/views.py b/atramhasis/views/views.py
index 7ab2d789..1d0f30ee 100644
--- a/atramhasis/views/views.py
+++ b/atramhasis/views/views.py
@@ -57,7 +57,8 @@ def get_public_conceptschemes(skos_registry):
return conceptschemes
-@view_defaults(accept='text/html')
+
+@view_defaults(accept='text/html', request_method='GET')
class AtramhasisView:
"""
This object groups HTML views part of the public user interface.
@@ -102,7 +103,7 @@ def home_view(self):
"""
return {'conceptschemes': get_public_conceptschemes(self.skos_registry)}
- @view_config(route_name='conceptschemes', renderer='atramhasis:templates/conceptschemes.jinja2')
+ @view_config(route_name='skosprovider.conceptschemes', renderer='atramhasis:templates/conceptschemes.jinja2')
def conceptschemes_view(self):
"""
Display a list of available conceptschemes.
@@ -110,7 +111,7 @@ def conceptschemes_view(self):
return {'conceptschemes': get_public_conceptschemes(self.skos_registry)}
@audit
- @view_config(route_name='conceptscheme', renderer='atramhasis:templates/conceptscheme.jinja2')
+ @view_config(route_name='skosprovider.conceptscheme', renderer='atramhasis:templates/conceptscheme.jinja2')
def conceptscheme_view(self):
"""
Display a single conceptscheme.
@@ -141,7 +142,7 @@ def conceptscheme_view(self):
'locale': locale}
@audit
- @view_config(route_name='concept', renderer='atramhasis:templates/concept.jinja2')
+ @view_config(route_name='skosprovider.c', renderer='atramhasis:templates/concept.jinja2')
def concept_view(self):
"""
Display all about a single concept or collection.
@@ -173,7 +174,7 @@ def concept_view(self):
concept_type = "Collection"
else:
return Response('Thing without type: ' + str(c_id), status_int=500)
- url = self.request.route_url('concept', scheme_id=scheme_id, c_id=c_id)
+ url = self.request.route_url('skosprovider.c', scheme_id=scheme_id, c_id=c_id)
update_last_visited_concepts(self.request, {'label': c.label(locale).label, 'url': url})
return {'concept': c, 'conceptType': concept_type, 'scheme_id': scheme_id,
'conceptschemes': conceptschemes, 'provider': provider,
@@ -181,7 +182,7 @@ def concept_view(self):
except NoResultFound:
raise ConceptNotFoundException(c_id)
- @view_config(route_name='search_result', renderer='atramhasis:templates/search_result.jinja2')
+ @view_config(route_name='skosprovider.conceptscheme.cs', renderer='atramhasis:templates/search_result.jinja2')
def search_result(self):
"""
Display search results
@@ -248,7 +249,7 @@ def set_locale_cookie(self):
return response
@audit
- @view_config(route_name='search_result_export', renderer='csv')
+ @view_config(route_name='skosprovider.conceptscheme.csv', renderer='csv')
def results_csv(self):
"""
Download search results in CSV format, allowing further processing.
@@ -353,11 +354,6 @@ def create_treeid(parent_tree_id, concept_id):
else:
return parent_tree_id + "|" + urllib.parse.quote(str(concept_id), safe="")
- @view_config(route_name='scheme_root', renderer='atramhasis:templates/concept.jinja2')
- def results_tree_html(self):
- scheme_id = self.request.matchdict['scheme_id']
- return {'concept': None, 'conceptType': None, 'scheme_id': scheme_id}
-
@view_defaults(accept='application/json', renderer='json')
class AtramhasisListView:
diff --git a/docs/source/conf.py b/docs/source/conf.py
index d9719bc0..90bf6bed 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -58,7 +58,7 @@
# The short X.Y version.
version = '2.1'
# The full version, including alpha/beta/rc tags.
-release = '2.1.0'
+release = '2.1.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/source/customisation.rst b/docs/source/customisation.rst
index dcb1a131..380bd030 100644
--- a/docs/source/customisation.rst
+++ b/docs/source/customisation.rst
@@ -1053,14 +1053,18 @@ expanded and edited.
SessionFactory
==============
-You can change the default session factory in the __init__.py file.
+If you don't provide a session factory in your Pyramid application, Atramhasis will use its default session factory,
+which is a SignedCookieSessionFactory.
-.. code-block:: python
+You can change the default session factory in the __init__.py file within the load_app function. To do this,
+ensure you pass the settings variable to the load_app function from within the main() function.
- # set default session factory
- from pyramid.session import SignedCookieSessionFactory
- atramhasis_session_factory = SignedCookieSessionFactory(settings['atramhasis.session_factory.secret'])
- config.set_session_factory(atramhasis_session_factory)
+.. code-block:: python
+ def load_app(config, settings):
+ # Override default session factory
+ from pyramid.session import SignedCookieSessionFactory
+ atramhasis_session_factory = SignedCookieSessionFactory(settings['atramhasis.session_factory.secret'])
+ config.set_session_factory(atramhasis_session_factory)
.. _upgrading_providers:
diff --git a/pyproject.toml b/pyproject.toml
index 0c00bc77..059181bd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,7 @@ requires = ["hatchling", "hatch-fancy-pypi-readme"]
build-backend = "hatchling.build"
[project]
-version = "2.1.0"
+version = "2.1.1"
name = "atramhasis"
dynamic = ["readme"]
authors = [
@@ -33,7 +33,7 @@ dependencies = [
"skosprovider_sqlalchemy>=2.1.1",
"skosprovider_rdf",
"skosprovider_getty",
- "pyramid_skosprovider",
+ "pyramid_skosprovider>=1.2.2",
"language_tags",
"jinja2 >= 3.0.0",
"markupsafe",
diff --git a/requirements-dev.txt b/requirements-dev.txt
index f915485d..442684e2 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -175,7 +175,7 @@ pyramid-openapi3==0.19
# via atramhasis (pyproject.toml)
pyramid-rewrite==0.2
# via atramhasis (pyproject.toml)
-pyramid-skosprovider==1.2.1
+pyramid-skosprovider==1.2.2
# via atramhasis (pyproject.toml)
pyramid-tm==2.5
# via atramhasis (pyproject.toml)
diff --git a/requirements.txt b/requirements.txt
index 7e768c63..40e9e22d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -120,7 +120,7 @@ pyramid-openapi3==0.19
# via atramhasis (pyproject.toml)
pyramid-rewrite==0.2
# via atramhasis (pyproject.toml)
-pyramid-skosprovider==1.2.1
+pyramid-skosprovider==1.2.2
# via atramhasis (pyproject.toml)
pyramid-tm==2.5
# via atramhasis (pyproject.toml)
diff --git a/tests/test_datamanagers.py b/tests/test_datamanagers.py
index b06d57b2..ec70fc17 100644
--- a/tests/test_datamanagers.py
+++ b/tests/test_datamanagers.py
@@ -178,36 +178,34 @@ def test_get_first_day(self):
@patch('atramhasis.data.datamanagers.date', Mock(today=Mock(return_value=date(2015, 9, 15))))
def test_get_most_popular_concepts_for_conceptscheme(self):
self.session.add(
- ConceptVisitLog(concept_id=1, conceptscheme_id='1', origin='REST',
+ ConceptVisitLog(concept_id='1', conceptscheme_id='1', origin='REST',
visited_at=datetime(2015, 8, 27, 10, 58, 3))
)
self.session.add(
- ConceptVisitLog(concept_id=1, conceptscheme_id='1', origin='REST',
+ ConceptVisitLog(concept_id='1', conceptscheme_id='1', origin='REST',
visited_at=datetime(2015, 8, 27, 11, 58, 3))
)
self.session.add(
- ConceptVisitLog(concept_id=2, conceptscheme_id='1', origin='REST',
+ ConceptVisitLog(concept_id='2', conceptscheme_id='1', origin='REST',
visited_at=datetime(2015, 8, 27, 10, 58, 3))
)
self.session.add(
- ConceptVisitLog(concept_id=2, conceptscheme_id='2', origin='REST',
+ ConceptVisitLog(concept_id='2', conceptscheme_id='2', origin='REST',
visited_at=datetime(2015, 8, 27, 10, 58, 3))
)
- self.assertListEqual(
- [
- {'concept_id': 1, 'scheme_id': 1},
- {'concept_id': 2, 'scheme_id': 1}
- ],
- self.audit_manager.get_most_popular_concepts_for_conceptscheme(
- 1, 5, 'last_month'
- )
- )
- self.assertListEqual([{'concept_id': 2, 'scheme_id': 2}],
- self.audit_manager.get_most_popular_concepts_for_conceptscheme(2, 5, 'last_month'))
- self.assertListEqual([{'concept_id': 1, 'scheme_id': 1}],
- self.audit_manager.get_most_popular_concepts_for_conceptscheme(1, 1, 'last_month'))
- self.assertListEqual([],
- self.audit_manager.get_most_popular_concepts_for_conceptscheme(1, 5, 'last_day'))
+
+ manager = self.audit_manager
+ result = manager.get_most_popular_concepts_for_conceptscheme(1, 5, 'last_month')
+ expected = [
+ {'concept_id': '1', 'scheme_id': 1}, {'concept_id': '2', 'scheme_id': 1}
+ ]
+ self.assertListEqual(expected, result)
+ result = manager.get_most_popular_concepts_for_conceptscheme(2, 5, 'last_month')
+ self.assertListEqual([{'concept_id': '2', 'scheme_id': 2}], result)
+ result = manager.get_most_popular_concepts_for_conceptscheme(1, 1, 'last_month')
+ self.assertListEqual([{'concept_id': '1', 'scheme_id': 1}], result)
+ result = manager.get_most_popular_concepts_for_conceptscheme(1, 5, 'last_day')
+ self.assertListEqual([], result)
class CountsManagerTest(DbTest):
diff --git a/tests/test_functional.py b/tests/test_functional.py
index 5ea779c5..4258f442 100644
--- a/tests/test_functional.py
+++ b/tests/test_functional.py
@@ -380,9 +380,6 @@ def test_delete_concept(self):
self.assertEqual('200 OK', res.status)
self.assertIsNotNone(res.json['id'])
self.assertEqual(new_id, res.json['id'])
- from skosprovider_sqlalchemy.models import Concept
- concepten = self.session.query(Concept).all()
- print()
def test_delete_concept_not_found(self):
res = self.testapp.delete('/conceptschemes/TREES/c/7895',
@@ -572,12 +569,6 @@ def mock_event_handler(event):
"referenced_in": ["urn:someobject", "http://test.test.org/object/2"]
})
- def test_method_not_allowed(self):
- self.testapp.delete('/conceptschemes/TREES', headers=self._get_default_headers(),
- status=405)
- self.testapp.post('/conceptschemes', headers=self._get_default_headers(),
- status=405)
-
def test_get_conceptschemes(self):
self.testapp.get('/conceptschemes', headers=self._get_default_headers(),
status=200)
@@ -836,6 +827,13 @@ def test_get_provider(self):
response.json
)
+ def test_expand_concept(self):
+ res = self.testapp.get(
+ '/conceptschemes/TREES/c/1/expand', headers=self._get_default_headers(),
+ status=200,
+ )
+ self.assertEqual(res.json, ['1'])
+
class TestCookieView(FunctionalTests):
def _get_default_headers(self):
diff --git a/tests/test_views.py b/tests/test_views.py
index 5d79157b..45dd9dc6 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -249,7 +249,7 @@ class TestConceptView(unittest.TestCase):
def setUp(self):
self.config = testing.setUp()
self.config.add_route(
- "concept",
+ "skosprovider.c",
pattern="/conceptschemes/{scheme_id}/c/{c_id}",
accept="text/html",
request_method="GET",
@@ -532,15 +532,6 @@ def setUp(self):
def tearDown(self):
testing.tearDown()
- def test_passing_view(self):
- self.request.skos_registry = self.regis
- self.request.matchdict["scheme_id"] = "TREES"
- atramhasisview = AtramhasisView(self.request)
- response = atramhasisview.results_tree_html()
- self.assertEqual(response["conceptType"], None)
- self.assertEqual(response["concept"], None)
- self.assertEqual(response["scheme_id"], "TREES")
-
class TestAdminView(unittest.TestCase):
def setUp(self):