tg-prepare 2.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tg_prepare-2.2.2.dist-info/METADATA +20 -0
- tg_prepare-2.2.2.dist-info/RECORD +82 -0
- tg_prepare-2.2.2.dist-info/WHEEL +5 -0
- tg_prepare-2.2.2.dist-info/entry_points.txt +4 -0
- tg_prepare-2.2.2.dist-info/licenses/LICENSE +202 -0
- tg_prepare-2.2.2.dist-info/projects/.secret_key +1 -0
- tg_prepare-2.2.2.dist-info/top_level.txt +2 -0
- tgp_backend/__init__.py +17 -0
- tgp_backend/auth.py +71 -0
- tgp_backend/cli.py +95 -0
- tgp_backend/config.py +35 -0
- tgp_backend/directories.py +79 -0
- tgp_backend/interfaces.py +3 -0
- tgp_backend/nextcloud.py +146 -0
- tgp_backend/project.py +468 -0
- tgp_backend/session_manager.py +47 -0
- tgp_backend/tgclient.py +187 -0
- tgp_backend/user.py +137 -0
- tgp_backend/util.py +131 -0
- tgp_ui/__init__.py +0 -0
- tgp_ui/app.py +150 -0
- tgp_ui/routes/__init__.py +0 -0
- tgp_ui/routes/auth.py +72 -0
- tgp_ui/routes/collection.py +319 -0
- tgp_ui/routes/data.py +229 -0
- tgp_ui/routes/project.py +103 -0
- tgp_ui/routes/publication.py +229 -0
- tgp_ui/routes/tabs.py +34 -0
- tgp_ui/routes/views.py +66 -0
- tgp_ui/static/css/bootstrap-icons.min.css +5 -0
- tgp_ui/static/css/bootstrap.min.css +6 -0
- tgp_ui/static/css/bootstrap.min.css.map +1 -0
- tgp_ui/static/css/main.css +141 -0
- tgp_ui/static/css/navbar.css +92 -0
- tgp_ui/static/css/simpleXML.css +67 -0
- tgp_ui/static/img/favicon.ico +0 -0
- tgp_ui/static/img/textgrid-logo.svg +1 -0
- tgp_ui/static/js/bootstrap.bundle.min.js +7 -0
- tgp_ui/static/js/collectionManager.js +60 -0
- tgp_ui/static/js/fileManager.js +153 -0
- tgp_ui/static/js/jquery.min.js +2 -0
- tgp_ui/static/js/main.js +36 -0
- tgp_ui/static/js/modalManager.js +105 -0
- tgp_ui/static/js/navbarManager.js +151 -0
- tgp_ui/static/js/projectManager.js +60 -0
- tgp_ui/static/js/require.js +5 -0
- tgp_ui/static/js/sidebarManager.js +44 -0
- tgp_ui/static/js/simpleXML.js +193 -0
- tgp_ui/static/js/tabManager.js +83 -0
- tgp_ui/templates/auth/login.html +42 -0
- tgp_ui/templates/details/empty_container.html +16 -0
- tgp_ui/templates/details/manage_collection.html +209 -0
- tgp_ui/templates/file_tree.html +39 -0
- tgp_ui/templates/includes/get_sessionid.html +29 -0
- tgp_ui/templates/includes/publish_form.html +55 -0
- tgp_ui/templates/includes/set_sessionid.html +26 -0
- tgp_ui/templates/includes/upload_form.html +258 -0
- tgp_ui/templates/layout.html +74 -0
- tgp_ui/templates/macros.html +101 -0
- tgp_ui/templates/modal/delete_project.html +25 -0
- tgp_ui/templates/modal/empty_container.html +9 -0
- tgp_ui/templates/modal/file_explorer_content.html +34 -0
- tgp_ui/templates/modal/file_explorer_main.html +22 -0
- tgp_ui/templates/modal/file_explorer_nextcloud.html +27 -0
- tgp_ui/templates/modal/github_modal.html +29 -0
- tgp_ui/templates/modal/nextcloud_login.html +48 -0
- tgp_ui/templates/modal/tei_explorer.html +58 -0
- tgp_ui/templates/modal/xpath_parser.html +52 -0
- tgp_ui/templates/nxc_login.html +25 -0
- tgp_ui/templates/nxc_tab.html +15 -0
- tgp_ui/templates/project_main.html +36 -0
- tgp_ui/templates/project_navbar.html +81 -0
- tgp_ui/templates/projects_main.html +58 -0
- tgp_ui/templates/tabs/check_upload.html +87 -0
- tgp_ui/templates/tabs/edit_project.html +113 -0
- tgp_ui/templates/tabs/empty_container.html +12 -0
- tgp_ui/templates/tabs/import_data.html +122 -0
- tgp_ui/templates/tabs/manage_collections.html +107 -0
- tgp_ui/templates/tabs/publication.html +42 -0
- tgp_ui/templates/tabs/select_directories.html +68 -0
- tgp_ui/templates/tabs/upload.html +42 -0
- tgp_ui/templates/tabs/validate_metadata.html +227 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
7
|
+
<meta name="description" content="" />
|
|
8
|
+
<meta name="author" content="" />
|
|
9
|
+
<title>{{ title }}</title>
|
|
10
|
+
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='img/favicon.ico') }}" />
|
|
11
|
+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" />
|
|
12
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|
13
|
+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/simpleXML.css') }}" />
|
|
14
|
+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/main.css') }}" />
|
|
15
|
+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/navbar.css') }}" />
|
|
16
|
+
</head>
|
|
17
|
+
|
|
18
|
+
<body>
|
|
19
|
+
<div class="wrapper">
|
|
20
|
+
<aside id="sidebar" class="expand d-flex flex-column">
|
|
21
|
+
<div class="d-flex">
|
|
22
|
+
<button class="toggle-btn" type="button">
|
|
23
|
+
<i class="bi bi-grid"></i>
|
|
24
|
+
</button>
|
|
25
|
+
<div class="sidebar-logo">
|
|
26
|
+
<a href="#">{{ title }}</a>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{% if current_user.is_authenticated %}
|
|
30
|
+
<ul class="p-0 flex-grow-1 overflow-y-auto">
|
|
31
|
+
<li class="sidebar-item">
|
|
32
|
+
<div class="d-flex align-items-center px-3 py-0 text-light">
|
|
33
|
+
<a href="{{ url_for('views.overview') }}" class="sidebar-link px-0 hover-none" title="Overview">
|
|
34
|
+
<i class="bi bi-view-list"></i>
|
|
35
|
+
<span>Overview</span>
|
|
36
|
+
</a>
|
|
37
|
+
</div>
|
|
38
|
+
</li>
|
|
39
|
+
{% for project in get_projects() %}
|
|
40
|
+
<li class="sidebar-item project-btn">
|
|
41
|
+
<a href="{{ url_for('views.project_view', projectname=project.name) }}" class="sidebar-link"
|
|
42
|
+
data-bs-target="#project_{{ loop.index }}" aria-expanded="false"
|
|
43
|
+
aria-controls="project_{{ loop.index }}">
|
|
44
|
+
{% if current_project == project.name %}
|
|
45
|
+
<i class="bi bi-circle-fill"></i>
|
|
46
|
+
{% else %}
|
|
47
|
+
<i class="bi bi-circle"></i>
|
|
48
|
+
{% endif %}
|
|
49
|
+
<span class="projectname">{{ project.name }}</span>
|
|
50
|
+
</a>
|
|
51
|
+
</li>
|
|
52
|
+
{% endfor %}
|
|
53
|
+
</ul>
|
|
54
|
+
<div class="p-3 pt-2 border-top">
|
|
55
|
+
<div class="d-flex align-items-center mb-2 text-light">
|
|
56
|
+
<i class="bi bi-person-circle me-2"></i>
|
|
57
|
+
<small>{{ current_user.username }}</small>
|
|
58
|
+
</div>
|
|
59
|
+
<a href="{{ url_for('auth.logout') }}" class="btn btn-danger btn-sm w-100 logout-btn">
|
|
60
|
+
<i class="bi bi-box-arrow-right me-2"></i>
|
|
61
|
+
<span class="text">Logout</span>
|
|
62
|
+
</a>
|
|
63
|
+
</div>
|
|
64
|
+
{% endif %}
|
|
65
|
+
</aside>
|
|
66
|
+
<div class="main p-3">
|
|
67
|
+
{% block content %}{% endblock content %}
|
|
68
|
+
{% include 'modal/empty_container.html' %}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<script data-main="/static/js/main" src="{{ url_for('static', filename='js/require.js') }}"></script>
|
|
72
|
+
</body>
|
|
73
|
+
|
|
74
|
+
</html>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{% macro multi_input(_items, input_name) %}
|
|
2
|
+
{% set items = _items or [None] %}
|
|
3
|
+
{% for item in items %}
|
|
4
|
+
<div class="input-group mb-2">
|
|
5
|
+
<input type="text" class="form-control" title="Name" name="{{input_name}}_name" placeholder="e.g.: Jane Doe"
|
|
6
|
+
value="{{ item.fullname or item.name }}" required>
|
|
7
|
+
<input type="url" class="form-control" title="URL" name="{{input_name}}_url" value="{{ item.url or '' }}"
|
|
8
|
+
placeholder="e.g.: https://orcid.org/0000-0001-2345-6789">
|
|
9
|
+
{% if loop.first %}
|
|
10
|
+
<button class="input-group-text add-multi-input">
|
|
11
|
+
<i class="bi bi-plus-circle-dotted"></i>
|
|
12
|
+
</button>
|
|
13
|
+
{% else %}
|
|
14
|
+
<button class="input-group-text remove-multi-input">
|
|
15
|
+
<i class="bi bi-dash-circle-dotted"></i>
|
|
16
|
+
</button>
|
|
17
|
+
{% endif %}
|
|
18
|
+
</div>
|
|
19
|
+
{% endfor %}
|
|
20
|
+
{% endmacro %}
|
|
21
|
+
|
|
22
|
+
{% macro form_field_with_xpath(type, label, field_key, elem, delete_button=False) %}
|
|
23
|
+
<div class="mb-2 row">
|
|
24
|
+
<div class="col-12 d-flex justify-content-between align-items-center">
|
|
25
|
+
<label class="form-label mb-0">
|
|
26
|
+
{{ label }}
|
|
27
|
+
</label>
|
|
28
|
+
{% if delete_button %}
|
|
29
|
+
<a href="#" class="badge text-dark remove-multi-field-classification ms-3">
|
|
30
|
+
<span class="bi bi-trash"></span>
|
|
31
|
+
</a>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
<div class="col-12">
|
|
35
|
+
<div class="input-group">
|
|
36
|
+
<input type="text" class="form-control" data-key="{{ field_key }}" data-type="value" placeholder="Value"
|
|
37
|
+
value="{{ elem['value'] if elem and elem.get('value') }}" name="{{ type }}-{{ field_key }}-value">
|
|
38
|
+
<input type="text" class="form-control" data-key="{{ field_key }}" data-type="xpath" placeholder="XPath"
|
|
39
|
+
value="{{ elem['xpath'] if elem and elem.get('xpath') }}" name="{{ type }}-{{ field_key }}-xpath">
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
{% endmacro %}
|
|
44
|
+
|
|
45
|
+
{% macro classification_input(type, heading, elements) %}
|
|
46
|
+
<div class="border-bottom mb-3 row">
|
|
47
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
48
|
+
<label class="form-label text-center flex-grow-1 mb-0">
|
|
49
|
+
<i>{{ heading }}</i>
|
|
50
|
+
</label>
|
|
51
|
+
<a href="#" class="add-multi-input-classifications btn btn-md ms-3" title="Add {{ heading }}">
|
|
52
|
+
<span class="bi bi-plus-circle"></span>
|
|
53
|
+
</a>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
{% for item in elements or [None] %}
|
|
57
|
+
<div class="multi-input {{'mb-3 pb-3 border-bottom' if loop.nextitem }}" data-name="{{ type }}">
|
|
58
|
+
{{ form_field_with_xpath(type, 'ID', 'id', item.get('id') if item, delete_button=True) }}
|
|
59
|
+
{{ form_field_with_xpath(type, 'URL', 'url', item.get('url') if item) }}
|
|
60
|
+
{{ form_field_with_xpath(type, 'Value', 'value', item.get('value') if item) }}
|
|
61
|
+
</div>
|
|
62
|
+
{% endfor %}
|
|
63
|
+
{% endmacro %}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
{% macro xpath_or_value_input(heading, input_name, item, collection_parser, required=False) %}
|
|
67
|
+
<div class="mb-3">
|
|
68
|
+
<label class="form-label">
|
|
69
|
+
<span>{{ heading }}</span>
|
|
70
|
+
{% if required %}<span class="text-danger">*</span>{% endif %}
|
|
71
|
+
</label>
|
|
72
|
+
<div class="row g-2">
|
|
73
|
+
<!-- Value Input -->
|
|
74
|
+
<div class="col-lg-6">
|
|
75
|
+
<input type="text" class="form-control" id="valueInput_{{ input_name }}" name="{{ input_name }}_value"
|
|
76
|
+
value="{{ item['value'] if item['value'] }}" placeholder="Value">
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- XPath Input -->
|
|
80
|
+
<div class="col-lg-6 position-relative">
|
|
81
|
+
<input type="text" class="form-control" id="xpathInput_{{ input_name }}" name="{{ input_name }}_xpath"
|
|
82
|
+
value="{{ item['xpath'] if item['xpath'] }}" placeholder="XPath">
|
|
83
|
+
<a href="#" class="load-modal" title="Hitrate of xpath (in %) - CLICK to see results"
|
|
84
|
+
data-args_xpath="{{ item['xpath'] }}"
|
|
85
|
+
data-url="{{ url_for('collection.modal_xpath_parser', projectname=project.name, collectionname=collectionname) }}">
|
|
86
|
+
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-success"
|
|
87
|
+
data-bs-placement="top" title="Hitrate of XPath">
|
|
88
|
+
{{ '%s%%' % collection_parser.test_xpath(item['xpath'])['count']['percentage'] if item['xpath']
|
|
89
|
+
else '-' }}
|
|
90
|
+
</span>
|
|
91
|
+
</a>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
{% endmacro %}
|
|
96
|
+
|
|
97
|
+
{% macro required_fields_disclaimer() %}
|
|
98
|
+
<div class="mb-3 mt-3">
|
|
99
|
+
<small class="text-muted"><span class="text-danger">*</span> indicates required fields</small>
|
|
100
|
+
</div>
|
|
101
|
+
{% endmacro %}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="modal fade" id="deleteProject" tabindex="-1" aria-labelledby="deleteProjectLabel" aria-hidden="true">
|
|
2
|
+
<div class="modal-dialog">
|
|
3
|
+
<div class="modal-content">
|
|
4
|
+
<form action="{{ url_for('project.delete_project', projectname=projectname) }}" method="POST"
|
|
5
|
+
data-reload-location="1">
|
|
6
|
+
<div class="modal-header">
|
|
7
|
+
<h5 class="modal-title" id="deleteProjectLabel">
|
|
8
|
+
<span>Delete Project</span>
|
|
9
|
+
</h5>
|
|
10
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="modal-body">
|
|
13
|
+
<p>Are you sure you want to delete the project
|
|
14
|
+
<p><strong>{{ projectname }}</strong>?</p>
|
|
15
|
+
This action cannot be undone.</p>
|
|
16
|
+
<p>All associated data will be permanently removed.</p>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="modal-footer">
|
|
19
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
20
|
+
<button type="submit" class="btn btn-danger">Delete</button>
|
|
21
|
+
</div>
|
|
22
|
+
</form>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="modal fade" id="genericModalContainer" tabindex="-1" aria-hidden="true">
|
|
2
|
+
<div class="modal-dialog modal-dialog-centered">
|
|
3
|
+
<div class="modal-body text-center bg-transparent border-0">
|
|
4
|
+
<div class="spinner-border text-white" style="width: 4rem; height: 4rem;" role="status">
|
|
5
|
+
<span class="visually-hidden">Loading...</span>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{% for item in items %}
|
|
2
|
+
<div class="list-group-item border-0">
|
|
3
|
+
<div class="d-flex align-items-center">
|
|
4
|
+
<div style="width: {{ item.depth * 1.2 }}rem"></div>
|
|
5
|
+
{% if item.type == 'folder' %}
|
|
6
|
+
<div class="form-check me-1">
|
|
7
|
+
{% if item.contains_xml or show_all_folders %}
|
|
8
|
+
{% if show_checkbox %}
|
|
9
|
+
<input class="form-check-input nextcloud-folder" type="checkbox" name="selected_folder"
|
|
10
|
+
value="{{ item.path }}" {{'checked' if item.path in selected_directories else '' }}>
|
|
11
|
+
{% endif %}
|
|
12
|
+
<label class="form-check-label">
|
|
13
|
+
<i class="bi bi-folder-fill text-warning me-1"></i>
|
|
14
|
+
{{ item.name }}
|
|
15
|
+
</label>
|
|
16
|
+
{% else %}
|
|
17
|
+
<i class="bi bi-folder-fill text-warning me-1"></i>
|
|
18
|
+
<span>{{ item.name }}</span>
|
|
19
|
+
{% endif %}
|
|
20
|
+
</div>
|
|
21
|
+
{% else %}
|
|
22
|
+
<i class="bi bi-file-text me-1 small"></i>
|
|
23
|
+
<span style="font-size: 0.7rem;">{{ item.name }}</span>
|
|
24
|
+
{% endif %}
|
|
25
|
+
</div>
|
|
26
|
+
{% if item.type == 'folder' and item.children.count > 0 %}
|
|
27
|
+
<div class="mt-1">
|
|
28
|
+
{% with items=item.children.list %}
|
|
29
|
+
{% include 'modal/file_explorer_content.html' %}
|
|
30
|
+
{% endwith %}
|
|
31
|
+
</div>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
{% endfor %}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="modal fade" id="folderModal{{ index }}" tabindex="-1">
|
|
2
|
+
<div class="modal-dialog modal-lg">
|
|
3
|
+
<div class="modal-content">
|
|
4
|
+
<div class="modal-header">
|
|
5
|
+
<h5 class="modal-title">
|
|
6
|
+
<i class="bi bi-folder2-open text-warning me-2"></i>
|
|
7
|
+
{{ folder.name }}
|
|
8
|
+
</h5>
|
|
9
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
{% if folder.children.count > 0 %}
|
|
13
|
+
{% with items=folder.children.list %}
|
|
14
|
+
{% include 'modal/file_explorer_content.html' %}
|
|
15
|
+
{% endwith %}
|
|
16
|
+
{% else %}
|
|
17
|
+
<p class="text-muted text-center py-3">Dieser Ordner ist leer</p>
|
|
18
|
+
{% endif %}
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<!-- Nextcloud <tree> Modal -->
|
|
3
|
+
<div class="modal-dialog modal-dialog-scrollable modal-lg">
|
|
4
|
+
<form class="modal-content js-modal-submit" data-reload-location="true"
|
|
5
|
+
action="{{ url_for('data.download_nextcloud', projectname=project.name) }}" method="POST"
|
|
6
|
+
id="nextcloudUploadForm">
|
|
7
|
+
<div class="modal-header">
|
|
8
|
+
<h5 class="modal-title" id="nextcloudModalLabel">Nextcloud Folders</h5>
|
|
9
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
{% for item in items %}
|
|
13
|
+
{% if item.type == 'folder' %}
|
|
14
|
+
{% with folder=item, index=loop.index %}
|
|
15
|
+
{% include 'modal/file_explorer_content.html' %}
|
|
16
|
+
{% endwith %}
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% endfor %}
|
|
19
|
+
</div>
|
|
20
|
+
<div class="modal-footer">
|
|
21
|
+
<button type="submit" class="btn btn-success">Download selected</button>
|
|
22
|
+
<button type="button" name="form_type" value="logout"
|
|
23
|
+
data-url="{{ url_for('data.modal_nextcloud', projectname=project.name, logout=True) }}"
|
|
24
|
+
class="load-modal btn btn-danger">Logout</button>
|
|
25
|
+
</div>
|
|
26
|
+
</form>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<div class="modal fade" id="githubModal" tabindex="-1">
|
|
2
|
+
<div class="modal-dialog">
|
|
3
|
+
<div class="modal-content">
|
|
4
|
+
<div class="modal-header">
|
|
5
|
+
<h5 class="modal-title">Clone from GitHub</h5>
|
|
6
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="modal-body">
|
|
9
|
+
<form class="reloadModal" action="{{ url_for('data.clone_git_project', projectname=project.name) }}"
|
|
10
|
+
method="POST" id="cloneFromGit">
|
|
11
|
+
<div class="mb-3">
|
|
12
|
+
<input type="text" class="form-control" name="github_repo" placeholder="GitHub Repository URL">
|
|
13
|
+
</div>
|
|
14
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
15
|
+
<small class="text-muted">
|
|
16
|
+
<i>Please be aware, that this can take a while (depending on the size of the git
|
|
17
|
+
project)!</i>
|
|
18
|
+
</small>
|
|
19
|
+
</div>
|
|
20
|
+
<button type="submit" class="btn btn-primary mt-3">
|
|
21
|
+
<span class="spinner-border spinner-border-sm me-2 d-none" role="status"
|
|
22
|
+
aria-hidden="true"></span>
|
|
23
|
+
<span>Clone Repository</span>
|
|
24
|
+
</button>
|
|
25
|
+
</form>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<!-- Nextcloud Upload Modal -->
|
|
3
|
+
<div class="modal-dialog modal-sm">
|
|
4
|
+
<div class="modal-content">
|
|
5
|
+
<form class="js-modal-submit" action="{{ url_for('data.modal_nextcloud', projectname=projectname) }}"
|
|
6
|
+
method="POST" id="nextcloudUploadForm">
|
|
7
|
+
<div class="modal-header">
|
|
8
|
+
<h5 class="modal-title">Login to Nextcloud</h5>
|
|
9
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
<div class="mb-3">
|
|
13
|
+
<label for="nextcloudUrl" class="form-label">Endpoint/URL *</label>
|
|
14
|
+
<input type="url" class="form-control" id="nextcloudUrl" name="nextcloud_url"
|
|
15
|
+
placeholder="https://cloud.example.com" required>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="mb-3">
|
|
18
|
+
<label for="nextcloudUser" class="form-label">Username *</label>
|
|
19
|
+
<input type="text" class="form-control" id="nextcloudUser" name="nextcloud_user" required>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="mb-3">
|
|
22
|
+
<label for="nextcloudPassword" class="form-label">Password *</label>
|
|
23
|
+
<input type="password" class="form-control" id="nextcloudPassword" name="nextcloud_password"
|
|
24
|
+
required>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="mb-3">
|
|
27
|
+
<label for="nextcloudFolder" class="form-label">Folder</label>
|
|
28
|
+
<input type="text" class="form-control" id="nextcloudFolder" name="nextcloud_folder"
|
|
29
|
+
placeholder="/path/to/folder">
|
|
30
|
+
</div>
|
|
31
|
+
<div class="alert alert-info" role="alert">
|
|
32
|
+
<small>* Required fields</small>
|
|
33
|
+
</div>
|
|
34
|
+
{% if message %}
|
|
35
|
+
<div class="alert text-center alert-warning" role="alert">
|
|
36
|
+
{{ message }}
|
|
37
|
+
</div>
|
|
38
|
+
{% endif %}
|
|
39
|
+
</div>
|
|
40
|
+
<div class="modal-footer d-flex justify-content-center">
|
|
41
|
+
<button type="submit" class="btn btn-primary">
|
|
42
|
+
<span class="spinner-border spinner-border-sm me-2 d-none" role="status" aria-hidden="true"></span>
|
|
43
|
+
<span>Login</span>
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
</form>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<div class="modal-dialog modal-xl">
|
|
2
|
+
<div class="modal-content">
|
|
3
|
+
<div class="modal-header align-items-center">
|
|
4
|
+
<h5 id="teiExplorerModalLabel" class="mb-0">TEI Explorer</h5>
|
|
5
|
+
<button type="button" class="btn-close ms-auto" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="modal-body">
|
|
8
|
+
<!-- Tabs Navigation -->
|
|
9
|
+
<ul class="nav nav-tabs" id="teiExplorerTabs" role="tablist">
|
|
10
|
+
<li class="nav-item" role="presentation">
|
|
11
|
+
<button class="nav-link active" id="filesTab" data-bs-toggle="tab" data-bs-target="#files"
|
|
12
|
+
type="button" role="tab" aria-controls="files" aria-selected="true">
|
|
13
|
+
TEI Files
|
|
14
|
+
</button>
|
|
15
|
+
</li>
|
|
16
|
+
<li class="nav-item" role="presentation">
|
|
17
|
+
<button class="nav-link" id="contentTab" data-bs-toggle="tab" data-bs-target="#content"
|
|
18
|
+
type="button" role="tab" aria-controls="content" aria-selected="false">
|
|
19
|
+
TEI Content
|
|
20
|
+
</button>
|
|
21
|
+
</li>
|
|
22
|
+
</ul>
|
|
23
|
+
|
|
24
|
+
<!-- Tabs Content -->
|
|
25
|
+
<div class="tab-content" id="teiExplorerTabsContent" style="height: 70vh; overflow-y: auto;">
|
|
26
|
+
<!-- Tab: TEI Files -->
|
|
27
|
+
<div class="tab-pane fade show active" id="files" role="tabpanel" aria-labelledby="filesTab">
|
|
28
|
+
<ul class="list-group">
|
|
29
|
+
{% for file in file_list %}
|
|
30
|
+
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
31
|
+
<span class="text-truncate">{{ file.name_stripped }}</span>
|
|
32
|
+
<div class="btn-group">
|
|
33
|
+
<button class="btn btn-sm btn-outline-secondary load-tei-content"
|
|
34
|
+
data-url="{{ url_for('collection.load_tei_content') }}"
|
|
35
|
+
data-path="{{ file['fullpath'] }}" data-type="header" data-heading="TEI Header">
|
|
36
|
+
Header
|
|
37
|
+
</button>
|
|
38
|
+
<button class="btn btn-sm btn-outline-secondary load-tei-content"
|
|
39
|
+
data-url="{{ url_for('collection.load_tei_content') }}"
|
|
40
|
+
data-path="{{ file['fullpath'] }}" data-type="text" data-heading="TEI Text">
|
|
41
|
+
Text
|
|
42
|
+
</button>
|
|
43
|
+
</div>
|
|
44
|
+
</li>
|
|
45
|
+
{% endfor %}
|
|
46
|
+
</ul>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Tab: TEI Content -->
|
|
50
|
+
<div class="tab-pane fade" id="content" role="tabpanel" aria-labelledby="contentTab">
|
|
51
|
+
<div id="teiContentOutput" class="m-3">
|
|
52
|
+
<p class="text-muted">Select a file to view its content.</p>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<div class="modal-dialog modal-xl">
|
|
2
|
+
<div class="modal-content">
|
|
3
|
+
<div class="modal-header align-items-center">
|
|
4
|
+
<h5 id="xpathParserModalLabel" class="mb-0">Parse XPath:</h5>
|
|
5
|
+
<button type="button" class="btn-close ms-auto" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="modal-body">
|
|
8
|
+
<form class="js-modal-submit mb-4" id="parseXPath"
|
|
9
|
+
action="{{ url_for('collection.modal_xpath_parser', projectname=projectname, collectionname=collectionname) }}">
|
|
10
|
+
<div class="input-group">
|
|
11
|
+
<input type="text" class="form-control" placeholder="Enter XPath query" name="xpath"
|
|
12
|
+
value="{{ xpath }}">
|
|
13
|
+
<button type="submit" class="btn btn-secondary">Parse</button>
|
|
14
|
+
</div>
|
|
15
|
+
</form>
|
|
16
|
+
{% set elements = collection_parser.elements %}
|
|
17
|
+
<div class="row">
|
|
18
|
+
{% if elements %}
|
|
19
|
+
{% for element in elements %}
|
|
20
|
+
{% set result = element['tei_parser'].find(xpath) if xpath else None %}
|
|
21
|
+
<div class="col mb-3">
|
|
22
|
+
<div class="card shadow-sm">
|
|
23
|
+
<div class="card-header bg-light">
|
|
24
|
+
<h6 class="mb-0 text-truncate">
|
|
25
|
+
<i class="bi bi-file-earmark-text"></i> {{ element['file']['filename'] }}
|
|
26
|
+
</h6>
|
|
27
|
+
</div>
|
|
28
|
+
{% if xpath %}
|
|
29
|
+
<div class="card-body border border-2 {{'border-success' if result else 'border-danger'}}">
|
|
30
|
+
{% else %}
|
|
31
|
+
<div class="card-body">
|
|
32
|
+
{% endif %}
|
|
33
|
+
{% if xpath %}
|
|
34
|
+
<p class="mb-0 text-muted small">
|
|
35
|
+
<b>XPath Result:</b>
|
|
36
|
+
<br>
|
|
37
|
+
{{ result }}
|
|
38
|
+
</p>
|
|
39
|
+
{% endif %}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
{% endfor %}
|
|
44
|
+
{% else %}
|
|
45
|
+
<div class="col-12">
|
|
46
|
+
<p class="text-center text-muted">No files available for parsing.</p>
|
|
47
|
+
</div>
|
|
48
|
+
{% endif %}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="h2">Nextcloud Login</div>
|
|
2
|
+
<form class="form-group login" method="POST" action="" id="nextcloud_login">
|
|
3
|
+
<div class="col-6">
|
|
4
|
+
<small class="form-text text-muted">Url</small>
|
|
5
|
+
<input required type="text" class="form-control" name="nextcloud_url" placeholder="Enter Nextcloud URL">
|
|
6
|
+
</div>
|
|
7
|
+
<div class="form-group col-3">
|
|
8
|
+
<small class="form-text text-muted">Username</small>
|
|
9
|
+
<input required type="text" class="form-control" name="username" id="username" placeholder="Enter Username">
|
|
10
|
+
</div>
|
|
11
|
+
<div class="form-group col-3">
|
|
12
|
+
<small class="form-text text-muted">Password</small>
|
|
13
|
+
<input required type="password" class="form-control" name="password" id="password" placeholder="Password">
|
|
14
|
+
</div>
|
|
15
|
+
<div class="form-group col-3">
|
|
16
|
+
<small class="form-text text-muted">Directory</small>
|
|
17
|
+
<input type="text" class="form-control" name="root_dir" id="root_dir" placeholder="(e.g.) TextGrid">
|
|
18
|
+
</div>
|
|
19
|
+
<br>
|
|
20
|
+
<button type="submit" class="btn btn-primary p-2 m-3 submit-login">
|
|
21
|
+
Submit
|
|
22
|
+
<span class="spinner-border spinner-border-sm spinner-login" hidden></span>
|
|
23
|
+
</button>
|
|
24
|
+
<span class="alert alert-danger" id="login-error" hidden>Wrong credentials</span>
|
|
25
|
+
</form>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% if nextcloud %}
|
|
2
|
+
<div class="h2">{{user}}'s Folders</div>
|
|
3
|
+
{% for item in nextcloud.nxc_list_files_and_folders() %}
|
|
4
|
+
{% include 'nxc_file_tree.html' %}
|
|
5
|
+
{% endfor %}
|
|
6
|
+
<button type="submit" class="btn btn-primary p-2 m-3 submit-selection">
|
|
7
|
+
Submit
|
|
8
|
+
<span class="spinner-border spinner-border-sm spinner-submit" hidden></span>
|
|
9
|
+
</button>
|
|
10
|
+
<button type="button" class="btn btn-secondary p-2 m-3" id="nextcloud_logout" onclick="handleLogout()">
|
|
11
|
+
Logout
|
|
12
|
+
</button>
|
|
13
|
+
{% else %}
|
|
14
|
+
{% include 'nxc_login.html' %}
|
|
15
|
+
{% endif %}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
{% extends 'layout.html' %}
|
|
3
|
+
{% block content %}
|
|
4
|
+
<section class="">
|
|
5
|
+
<div class="container bg" id="navbar">
|
|
6
|
+
{% include 'project_navbar.html' %}
|
|
7
|
+
</div>
|
|
8
|
+
<div class="container tab-area mt-4 p-4 rounded-3">
|
|
9
|
+
<div class="tab-content">
|
|
10
|
+
<div class="tab-pane" id="tab-edit-project" role="tabpanel" aria-labelledby="tab-edit-project-tab"></div>
|
|
11
|
+
<div class="tab-pane" id="tab-edit-other-files" role="tabpanel" aria-labelledby="tab-edit-other-files-tab">
|
|
12
|
+
</div>
|
|
13
|
+
<div class="tab-pane" id="tab-import-data" role="tabpanel" aria-labelledby="tab-import-data-tab">
|
|
14
|
+
</div>
|
|
15
|
+
<div class="tab-pane" id="tab-select-directories" role="tabpanel" aria-labelledby="tab-set-collections-tab">
|
|
16
|
+
</div>
|
|
17
|
+
<div class="tab-pane" id="tab-set-collections" role="tabpanel" aria-labelledby="tab-set-collections-tab">
|
|
18
|
+
</div>
|
|
19
|
+
<div class="tab-pane" id="tab-prepare-metadata" role="tabpanel" aria-labelledby="tab-prepare-metadata-tab">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="tab-pane" id="tab-check-metadata" role="tabpanel" aria-labelledby="tab-check-metadata-tab">
|
|
22
|
+
</div>
|
|
23
|
+
<div class="tab-pane" id="tab-prepare-upload" role="tabpanel" aria-labelledby="tab-prepare-upload-tab">
|
|
24
|
+
</div>
|
|
25
|
+
<div class="tab-pane" id="tab-check-results" role="tabpanel" aria-labelledby="tab-check-results-tab">
|
|
26
|
+
</div>
|
|
27
|
+
<div class="tab-pane" id="tab-publication" role="tabpanel" aria-labelledby="tab-publication-tab"></div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<!-- <a href="#" class="m-4 text-muted helper position-fixed bottom-0 end-0 mx-5"
|
|
31
|
+
data-bs-toggle="Contact ... for help" title="Need help?">
|
|
32
|
+
<i class="bi bi-question-circle fs-1"></i>
|
|
33
|
+
</a> -->
|
|
34
|
+
</div>
|
|
35
|
+
</section>
|
|
36
|
+
{% endblock %}
|