tg-prepare 1.0.0__py3-none-any.whl → 2.1.0b1__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.

Potentially problematic release.


This version of tg-prepare might be problematic. Click here for more details.

Files changed (56) hide show
  1. {tg_prepare-1.0.0.dist-info → tg_prepare-2.1.0b1.dist-info}/METADATA +3 -3
  2. tg_prepare-2.1.0b1.dist-info/RECORD +54 -0
  3. {tg_prepare-1.0.0.dist-info → tg_prepare-2.1.0b1.dist-info}/WHEEL +1 -1
  4. tg_prepare-2.1.0b1.dist-info/projects/.secret_key +1 -0
  5. tgp_backend/__init__.py +3 -4
  6. tgp_backend/config.py +31 -0
  7. tgp_backend/directories.py +6 -12
  8. tgp_backend/nextcloud.py +40 -19
  9. tgp_backend/project.py +179 -52
  10. tgp_backend/session_manager.py +47 -0
  11. tgp_backend/tgclient.py +0 -1
  12. tgp_backend/util.py +73 -25
  13. tgp_ui/app.py +43 -337
  14. tgp_ui/routes/__init__.py +0 -0
  15. tgp_ui/routes/collection.py +272 -0
  16. tgp_ui/routes/data.py +228 -0
  17. tgp_ui/routes/project.py +102 -0
  18. tgp_ui/routes/publication.py +129 -0
  19. tgp_ui/routes/tabs.py +34 -0
  20. tgp_ui/routes/views.py +62 -0
  21. tgp_ui/static/css/navbar.css +92 -0
  22. tgp_ui/static/js/collectionManager.js +60 -0
  23. tgp_ui/static/js/fileManager.js +186 -0
  24. tgp_ui/static/js/main.js +32 -450
  25. tgp_ui/static/js/modalManager.js +105 -0
  26. tgp_ui/static/js/navbarManager.js +151 -0
  27. tgp_ui/static/js/projectManager.js +60 -0
  28. tgp_ui/static/js/require.js +5 -0
  29. tgp_ui/static/js/sidebarManager.js +32 -0
  30. tgp_ui/static/js/tabManager.js +79 -0
  31. tgp_ui/templates/layout.html +39 -37
  32. tgp_ui/templates/macros.html +84 -74
  33. tgp_ui/templates/project_main.html +36 -0
  34. tgp_ui/templates/project_navbar.html +81 -0
  35. tgp_ui/templates/{projects.html → projects_main.html} +14 -29
  36. tgp_ui/templates/publication.html +156 -0
  37. tgp_ui/templates/tab_final_upload.html +29 -0
  38. tg_prepare-1.0.0.dist-info/RECORD +0 -46
  39. tgp_ui/static/js/jstree.min.js +0 -3
  40. tgp_ui/templates/collection.html +0 -194
  41. tgp_ui/templates/empty.html +0 -4
  42. tgp_ui/templates/file_upload.html +0 -24
  43. tgp_ui/templates/jsfiler.html +0 -6
  44. tgp_ui/templates/layout2.html +0 -99
  45. tgp_ui/templates/main.html +0 -5
  46. tgp_ui/templates/nxc_file_tree.html +0 -33
  47. tgp_ui/templates/project.html +0 -25
  48. tgp_ui/templates/project_nxc.html +0 -37
  49. tgp_ui/templates/publish.html +0 -120
  50. tgp_ui/templates/storage.html +0 -49
  51. tgp_ui/templates/tei_browser.html +0 -14
  52. tgp_ui/templates/tei_explorer.html +0 -48
  53. tgp_ui/templates/xpath_parser_modal_content.html +0 -37
  54. {tg_prepare-1.0.0.dist-info → tg_prepare-2.1.0b1.dist-info}/entry_points.txt +0 -0
  55. {tg_prepare-1.0.0.dist-info → tg_prepare-2.1.0b1.dist-info}/licenses/LICENSE +0 -0
  56. {tg_prepare-1.0.0.dist-info → tg_prepare-2.1.0b1.dist-info}/top_level.txt +0 -0
@@ -1,91 +1,101 @@
1
- {% macro multi_input(type, heading, elements, version=1) %}
2
- <div class="border-top mb-3 row">
3
- <label class="col-sm-12 col-form-label">
4
- <div class="d-flex justify-content-between align-items-center">
5
- <b>{{ heading }}</b>
6
- <a href="#" class="add-multi-input btn btn-md" title="Add {{ heading }}">
7
- <span class="bi bi-plus-circle"></span>
8
- </a>
9
- </div>
10
- </label>
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 %}
11
18
  </div>
12
- {% for item in elements or [None] %}
13
- <div class="multi-input" data-name="{{ type }}">
14
- {% if version == 1 %}
15
- <div class="mb-3 row">
16
- <label class="col-lg-2 col-form-label">ID
17
- <a href="#" class="badge text-dark remove-multi-field">
18
- <span class="bi bi-trash"></span>
19
- </a>
19
+ {% endif %}
20
+ {% endfor %}
21
+ {% endmacro %}
22
+
23
+ {% macro form_field_with_xpath(type, label, field_key, elem, delete_button=False) %}
24
+ <div class="mb-2 row">
25
+ <div class="col-12 d-flex justify-content-between align-items-center">
26
+ <label class="form-label mb-0">
27
+ {{ label }}
20
28
  </label>
21
- <div class="col-lg-4">
22
- <input type="text" class="form-control" data-key="id" value="{{ item['id'] if item['id'] }}">
23
- </div>
24
- <label class="col-lg-2 col-form-label">URL</label>
25
- <div class="col-lg-4">
26
- <input type="text" class="form-control" data-key="url" value="{{ item['url'] if item['url'] }}">
27
- </div>
29
+ {% if delete_button %}
30
+ <a href="#" class="badge text-dark remove-multi-field-classification ms-3">
31
+ <span class="bi bi-trash"></span>
32
+ </a>
33
+ {% endif %}
28
34
  </div>
29
- <div class="mb-3 row">
30
- <label class="col-lg-2 col-form-label">Value</label>
31
- <div class="col-lg-10 {{'pb-2 border-bottom' if loop.nextitem }}">
32
- <input type="text" class="form-control" data-key="value" value="{{ item['value'] if item['value'] }}">
35
+ <div class="col-12">
36
+ <div class="input-group">
37
+ <input type="text" class="form-control" data-key="{{ field_key }}" data-type="value" placeholder="Value"
38
+ value="{{ elem['value'] if elem and elem.get('value') }}" name="{{ type }}-{{ field_key }}-value">
39
+ <input type="text" class="form-control" data-key="{{ field_key }}" data-type="xpath" placeholder="XPath"
40
+ value="{{ elem['xpath'] if elem and elem.get('xpath') }}" name="{{ type }}-{{ field_key }}-xpath">
33
41
  </div>
34
42
  </div>
35
- {% elif version == 2 %}
36
- <div class="mb-3 row {{'pb-2 border-bottom' if loop.nextitem }}">
37
- <label class="col-lg-2 col-form-label">
38
- Fullname
43
+ </div>
44
+ {% endmacro %}
45
+
46
+ {% macro classification_input(type, heading, elements) %}
47
+ <div class="border-bottom mb-3 row">
48
+ <div class="d-flex justify-content-between align-items-center">
49
+ <label class="form-label text-center flex-grow-1 mb-0">
50
+ <i>{{ heading }}</i>
39
51
  </label>
40
- <div class="col-lg-4">
41
- <input type="text" class="form-control" data-key="fullname"
42
- value="{{ item['fullname'] if item['fullname'] }}">
43
- </div>
44
- <label class="col-lg-1 col-form-label">URL</label>
45
- <div class="col-lg-4 ">
46
- <input type="text" class="form-control" data-key="url" value="{{ item['url'] if item['url'] }}">
47
- </div>
48
- <div class="col-lg-1 mt-lg-0 mt-2">
49
- <a href="#" class="btn btn-md remove-multi-field">
50
- <span class="bi bi-trash"></span>
51
- </a>
52
- </div>
52
+ <a href="#" class="add-multi-input-classifications btn btn-md ms-3" title="Add {{ heading }}">
53
+ <span class="bi bi-plus-circle"></span>
54
+ </a>
53
55
  </div>
54
- {% endif %}
56
+ </div>
57
+ {% for item in elements or [None] %}
58
+ <div class="multi-input {{'mb-3 pb-3 border-bottom' if loop.nextitem }}" data-name="{{ type }}">
59
+ {{ form_field_with_xpath(type, 'ID', 'id', item.get('id') if item, delete_button=True) }}
60
+ {{ form_field_with_xpath(type, 'URL', 'url', item.get('url') if item) }}
61
+ {{ form_field_with_xpath(type, 'Value', 'value', item.get('value') if item) }}
55
62
  </div>
56
63
  {% endfor %}
57
64
  {% endmacro %}
58
65
 
59
- {% macro xpath_or_value_input(heading, input_name, item, collection_parser, is_subsection=True) %}
60
- <div class="mb-1 row gap-1 align-items-center xpath-or-value-input">
61
- <label class="col-lg-2 col-form-label">
62
- {% if is_subsection %}
63
- {{ heading }}
64
- {% else %}
65
- <b>{{ heading }}</b>
66
- {% endif %}
66
+
67
+ {% macro xpath_or_value_input(heading, input_name, item, collection_parser, required=False) %}
68
+ <div class="mb-3">
69
+ <label class="form-label">
70
+ <span>{{ heading }}</span>
71
+ {% if required %}<span class="text-danger">*</span>{% endif %}
67
72
  </label>
68
- <div class="col-lg-5">
69
- <div class="form-floating">
70
- <input type="text" class="form-control" id="valueInput_{{ input_name }}" data-name="{{ input_name }}"
71
- data-type="value" value="{{ item['value'] if item['value'] }}" placeholder="Value">
72
- <label for="valueInput_{{ input_name }}">Value</label>
73
+ <div class="row g-2">
74
+ <!-- Value Input -->
75
+ <div class="col-lg-6">
76
+ <input type="text" class="form-control" id="valueInput_{{ input_name }}" name="{{ input_name }}_value"
77
+ value="{{ item['value'] if item['value'] }}" placeholder="Value">
73
78
  </div>
74
- </div>
75
- <div class="col-lg-4 position-relative">
76
- <div class="form-floating">
77
- <input type="text" class="form-control" id="xpathInput_{{ input_name }}" data-name="{{ input_name }}"
78
- data-type="xpath" value="{{ item['xpath'] if item['xpath'] }}" placeholder="XPath">
79
- <label for="xpathInput_{{ input_name }}">XPath</label>
79
+
80
+ <!-- XPath Input -->
81
+ <div class="col-lg-6 position-relative">
82
+ <input type="text" class="form-control" id="xpathInput_{{ input_name }}" name="{{ input_name }}_xpath"
83
+ value="{{ item['xpath'] if item['xpath'] }}" placeholder="XPath">
84
+ <a href="#" class="load-modal" title="Hitrate of xpath (in %) - CLICK to see results"
85
+ data-args_xpath="{{ item['xpath'] }}"
86
+ data-url="{{ url_for('collection.modal_xpath_parser', projectname=project.name, collectionname=collectionname) }}">
87
+ <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-success"
88
+ data-bs-placement="top" title="Hitrate of XPath in percentage">
89
+ {{ collection_parser.test_xpath(item['xpath'])['count']['percentage'] if item['xpath'] else '-' }}
90
+ </span>
91
+ </a>
80
92
  </div>
81
- <a href="#" class="show-xpath-in-tei-explorer" title="Hitrate of xpath (in %) - CLICK to see results"
82
- data-url="{{ url_for('xpath_parser_modal', projectname=project.name, title=collection_title) }}"
83
- data-xpath="{{ item['xpath'] }}">
84
- <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-success"
85
- data-bs-toggle="tooltip" data-bs-placement="top" title="Hitrate of XPath in percentage">
86
- {{ collection_parser.test_xpath(item['xpath'])['count']['percentage'] if item['xpath'] else '-' }}
87
- </span>
88
- </a>
89
93
  </div>
90
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>
91
101
  {% endmacro %}
@@ -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-final-upload" role="tabpanel" aria-labelledby="tab-final-upload-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 %}
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html>
2
+ <div class="row align-items-center justify-content-between position-relative">
3
+ <!-- Line -->
4
+ <div class="line blank"></div>
5
+ <div class="line blue"></div>
6
+
7
+ <!-- Main Button 1: Manage Project -->
8
+ <div class="col-auto expanding-button text-center">
9
+ <button type="button" class="btn btn-light btn-circle btn-xl" id="tab-group-project" title="Manage Project">
10
+ <i class="bi bi-archive main-icon"></i>
11
+ <div class="row sub-buttons d-none nav">
12
+ <!-- Sub-Button: Project Settings -->
13
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary last-opened " data-bs-toggle="tab"
14
+ data-bs-target="#tab-edit-project"
15
+ data-url="{{ url_for('project.tab_edit_project', projectname=project.name) }}">
16
+ <i class="bi bi-pen fs-4"></i>
17
+ </div>
18
+ <!-- Sub-Button: Upload Data -->
19
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
20
+ data-bs-target="#tab-import-data"
21
+ data-url="{{ url_for('data.tab_import_data', projectname=project.name)}}">
22
+ <i class="bi bi-archive fs-4"></i>
23
+ </div>
24
+ </div>
25
+ </button>
26
+ </div>
27
+
28
+ <!-- Main Button 2: Manage Collections -->
29
+ <div class="col-auto text-center">
30
+ <button type="button" class="btn btn-light btn-circle btn-xl" id="tab-group-collections"
31
+ title="Manage Collections">
32
+ <i class="bi bi-pencil"></i>
33
+ <div class="row sub-buttons d-none nav">
34
+ <!-- Sub-Button: Select Data -->
35
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
36
+ data-bs-target="#tab-select-directories"
37
+ data-url="{{ url_for('collection.tab_select_directories', projectname=project.name)}}">
38
+ <i class="bi bi-list-nested fs-4"></i>
39
+ </div>
40
+ <!-- Sub-Button: Manage Metadata -->
41
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
42
+ data-bs-target="#tab-set-collections"
43
+ data-url="{{ url_for('collection.tab_manage_collections', projectname=project.name)}}">
44
+ <i class="bi bi-pen fs-4"></i>
45
+ </div>
46
+ <!-- Sub-Button: Check Settings & Metadata -->
47
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
48
+ data-bs-target="#tab-check-metadata"
49
+ data-url="{{ url_for('collection.tab_validate_metadata', projectname=project.name)}}">
50
+ <i class="bi bi-list-check fs-4"></i>
51
+ </div>
52
+ </div>
53
+ </button>
54
+ </div>
55
+ <!-- Main Button 3: Upload & Publish to TextGrid -->
56
+ <div class="col-auto text-center">
57
+ <button type="button" class="btn btn-light btn-circle btn-xl" id="tab-group-upload">
58
+ <i class="bi bi-cloud"></i>
59
+ <div class="row sub-buttons d-none nav">
60
+ <!-- Sub-Button: TG-Sesssion-ID, -Project-ID & -Upload -->
61
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
62
+ data-bs-target="#tab-prepare-upload"
63
+ data-url="{{ url_for('publication.tab_upload', projectname=project.name)}}">
64
+ <i class="bi bi-key fs-4"></i>
65
+ </div>
66
+ <!-- Sub-Button: Check TG-Project -->
67
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
68
+ data-bs-target="#tab-check-results"
69
+ data-url="{{ url_for('publication.tab_check_result', projectname=project.name) }}">
70
+ <i class="bi bi-arrow-repeat fs-4"></i>
71
+ </div>
72
+ <!-- Sub-Button: TG-Publish -->
73
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
74
+ data-bs-target="#tab-final-upload"
75
+ data-url="{{ url_for('tab_final_upload', projectname=project.name)}}">
76
+ <i class="bi bi-cloud-upload fs-4"></i>
77
+ </div>
78
+ </div>
79
+ </button>
80
+ </div>
81
+ </div>
@@ -1,15 +1,22 @@
1
- {% extends 'layout2.html' %}
1
+ <!DOCTYPE html>
2
+ {% extends 'layout.html' %}
2
3
  {% block content %}
4
+ <div class="row">
5
+ <div class="col-12">
6
+ <h1 class="text-center">Projects</h1>
7
+ <p class="text-center text-muted">Manage your projects here. You can create, edit, and delete projects.</p>
8
+ </div>
9
+ </div>
3
10
  <div class="row row-cols-xxl-6 row-cols-lg-4 row-cols-md-2">
4
- {% for project in projects%}
11
+ {% for project in get_projects() %}
5
12
  <div class="card text-center m-1">
6
13
  <div class="card-body">
7
14
  <h5 class="card-title">{{ project.name }}</h5>
8
- <a class="btn btn-secondary btn-forward" href="project/{{ project.name }}" title="Edit project">
15
+ <a class="btn btn-secondary btn-forward" href="project/{{ project.path }}" title="Edit project">
9
16
  <span class="bi bi-pencil-square"></span>
10
17
  </a>
11
- <a class="btn btn-danger btn-forward" title="Delete project" data-bs-toggle="modal"
12
- data-bs-target="#deleteProject" data-projectname="{{ project.name }}">
18
+ <a class="btn btn-danger load-modal" title="Delete project"
19
+ data-url="{{ url_for('project.modal_delete_project', projectname=project.path) }}">
13
20
  <span class="bi bi-trash"></span>
14
21
  </a>
15
22
  </div>
@@ -29,14 +36,14 @@
29
36
  <div class="modal fade" id="newProject" tabindex="-1" aria-labelledby="newProjectLabel" aria-hidden="true">
30
37
  <div class="modal-dialog">
31
38
  <div class="modal-content">
32
- <form action="{{ url_for('new_project') }}" method="POST">
39
+ <form action="{{ url_for('project.new_project') }}" method="POST">
33
40
  <div class="modal-header">
34
41
  <h5 class="modal-title" id="newProjectLabel">Create new Project</h5>
35
42
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
36
43
  </div>
37
44
  <div class="modal-body">
38
45
  <div class="mb-3">
39
- <input type="text" class="form-control" id="project" name="projectname"
46
+ <input type="text" id="projectNameInput" class="form-control" name="projectname"
40
47
  placeholder="Projectname" value="{{ projectname }}">
41
48
  </div>
42
49
  </div>
@@ -48,26 +55,4 @@
48
55
  </div>
49
56
  </div>
50
57
  </div>
51
-
52
- <div class="modal fade" id="deleteProject" tabindex="-1" aria-labelledby="deleteProjectLabel" aria-hidden="true">
53
- <div class="modal-dialog">
54
- <div class="modal-content">
55
- <form action="{{ url_for('projects') }}" method="POST">
56
- <div class="modal-header">
57
- <h5 class="modal-title" id="deleteProjectLabel">
58
- <span>Delete Project:</span>
59
- <i class="projectname"></i>
60
- </h5>
61
- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
62
- </div>
63
- <div class="modal-footer">
64
- <input type="hidden" name="delete" value="true">
65
- <input type="hidden" name="projectname">
66
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
67
- <button type="submit" class="btn btn-danger">Delete</button>
68
- </div>
69
- </form>
70
- </div>
71
- </div>
72
- </div>
73
58
  {% endblock %}
@@ -0,0 +1,156 @@
1
+ <div class="container-fluid p-4">
2
+ <div class="card shadow-sm border-0">
3
+ <div class="card-header bg-secondary bg-gradient text-white py-2">
4
+ <h5 class="mb-0">
5
+ <i class="bi bi-cloud-upload me-2"></i>
6
+ Publish project to TextGrid-Testinstance
7
+ </h5>
8
+ </div>
9
+
10
+ <div class="card-body p-3">
11
+ {% set tg_session_id = project.main_config.get_tg_session_id('test')%}
12
+
13
+ <!-- 1. Session ID Section -->
14
+ <div class="card bg-light border-0 shadow-sm mb-4">
15
+ <div class="card-body p-3">
16
+ <h5 class="card-title mb-3">Session ID</h5>
17
+ <form class="tab-submit" method="POST" data-projectname="{{ project.name }}"
18
+ action="{{ url_for('save_session_id', projectname=project.name, instance='test') }}">
19
+ <div class="row g-2 align-items-center">
20
+ <div class="col-md-8">
21
+ <div class="input-group shadow-sm">
22
+ <span class="input-group-text bg-light"><i class="bi bi-key"></i></span>
23
+ <input type="text" class="form-control" name="tg_auth_session_id"
24
+ placeholder="TgAuth Session ID" value="{{tg_session_id if tg_session_id}}">
25
+ </div>
26
+ </div>
27
+ <div class="col-md-4">
28
+ <button type="submit" class="btn btn-success w-100 shadow-sm">
29
+ <span class="bi bi-floppy2-fill me-2"></span>
30
+ <span class="spinner-border spinner-border-sm" style="display: none;"
31
+ role="status"></span>
32
+ Save Session ID
33
+ </button>
34
+ </div>
35
+ </div>
36
+ </form>
37
+ </div>
38
+ </div>
39
+
40
+ {% if tg_session_id %}
41
+ <!-- 2. Select Project Section -->
42
+ <div class="card bg-light border-0 shadow-sm mb-4">
43
+ <div class="card-body p-3">
44
+ <h5 class="card-title mb-3">Select from existing projects</h5>
45
+ <div class="list-group">
46
+ {% for tg_project in project.get_tgp('test').get_tg_projects() %}
47
+ <div
48
+ class="list-group-item list-group-item-action d-flex justify-content-between align-items-center py-2">
49
+ <div class="d-flex align-items-center">
50
+ <a href="#" class="text-success select-tg-project me-3"
51
+ data-url="{{ url_for('save_tg_project_id', projectname=project.name, instance='test') }}"
52
+ data-tg_project_id="{{ tg_project.id }}" data-projectname="{{ project.name }}">
53
+ <i
54
+ class="bi bi-{% if project.main_config.get_tg_project_id('test') == tg_project.id %}circle-fill{% else %}circle{% endif %} fs-5"></i>
55
+ <span class="spinner-border spinner-border-sm ms-2" style="display: none;"
56
+ role="status"></span>
57
+ </a>
58
+ <div>
59
+ <strong>{{ tg_project.name }}</strong>
60
+ <small class="text-muted d-block">
61
+ <span class="tgProjectHits badge bg-secondary me-2">{{ tg_project.contents
62
+ }}</span>
63
+ Elements | ID: {{ tg_project.id }}
64
+ </small>
65
+ </div>
66
+ </div>
67
+ <a href="#" class="btn btn-outline-danger btn-sm delete-tg-project"
68
+ data-projectname="{{ project.name }}"
69
+ data-url="{{ url_for('delete_tg_project_id', projectname=project.name, instance='test', tg_project_id= tg_project.id ) }}"
70
+ data-hits_url="{{ url_for('get_tg_project_hits', projectname=project.name, instance='test', tg_project_id= tg_project.id ) }}">
71
+ <span class="bi bi-trash me-1"></span>
72
+ <span class="spinner-border spinner-border-sm ms-2" style="display: none;"
73
+ role="status"></span>
74
+ <b>Delete</b>
75
+ </a>
76
+ </div>
77
+ {% endfor %}
78
+ </div>
79
+ </div>
80
+ </div>
81
+
82
+ <!-- 3. Create New Project Section -->
83
+ <div class="card bg-light border-0 shadow-sm mb-4">
84
+ <div class="card-body p-3">
85
+ <h5 class="card-title mb-3">Create new project</h5>
86
+ <form class="row g-2 tab-submit" method="POST" data-projectname="{{ project.name }}"
87
+ action="{{ url_for('create_tg_project', projectname=project.name, instance='test') }}">
88
+ <div class="col-md-8">
89
+ <input type="text" class="form-control" name="tg_projectname"
90
+ placeholder="Enter project name" required>
91
+ </div>
92
+ <div class="col-md-4">
93
+ <button type="submit" class="btn btn-secondary w-100">
94
+ <span class="bi bi-plus-circle me-2"></span>
95
+ <span class="spinner-border spinner-border-sm" style="display: none;"
96
+ role="status"></span>
97
+ <b>Create Project</b>
98
+ </button>
99
+ </div>
100
+ </form>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- 4. Publish Project Section -->
105
+ <div class="card bg-light border-0 shadow-sm">
106
+ <div class="card-body p-3">
107
+ <h5 class="card-title mb-3">Publish project</h5>
108
+ <form class="tab-submit" method="POST" data-projectname="{{ project.name }}"
109
+ action="{{ url_for('publish_project', projectname=project.name, instance='test') }}">
110
+ <div class="d-flex justify-content-between align-items-center mb-3">
111
+ {% if project.main_config.get_tg_project_id('test') %}
112
+ <button type="submit" class="btn btn-success">
113
+ <span class="bi bi-rocket-takeoff me-2"></span>
114
+ <span class="spinner-border spinner-border-sm" style="display: none;"
115
+ role="status"></span>
116
+ Publish
117
+ </button>
118
+ {% endif %}
119
+ </div>
120
+
121
+ {% if project.main_config.get_tg_project_id('test') %}
122
+ <div class="alert alert-info mb-0">
123
+ <h6 class="alert-heading fw-bold mb-2">What's next?</h6>
124
+ <ol class="mb-0">
125
+ <li class="mb-2">Go to <a href="https://test.textgridrep.org/projects"
126
+ class="alert-link">Testinstance</a></li>
127
+ <li class="mb-2">Display 'Unpublished projects' <i>My TextGrid/Unpublished Data</i></li>
128
+ <li>Check if everything looks as favored</li>
129
+ </ol>
130
+ </div>
131
+ {% else %}
132
+ <div class="alert alert-warning mb-0">
133
+ <h6 class="alert-heading fw-bold mb-2">Attention</h6>
134
+ <p class="mb-0">You need to select a TextGrid project to publish!</p>
135
+ </div>
136
+ {% endif %}
137
+ </form>
138
+ </div>
139
+ </div>
140
+ {% else %}
141
+ <!-- No Session ID Warning -->
142
+ <div class="alert alert-warning shadow-sm">
143
+ <h5 class="alert-heading"><i class="bi bi-exclamation-triangle me-2"></i>Attention Required</h5>
144
+ <p class="mb-3">You need to provide a "TgAuth Session ID" to publish your project:</p>
145
+ <ol class="mb-0">
146
+ <li class="mb-2">Visit <a
147
+ href="https://test.textgridlab.org/1.0/Shibboleth.sso/Login?target=/1.0/secure/TextGrid-WebAuth.php?authZinstance=test.textgridlab.org"
148
+ class="alert-link" target="_blank">the authentication page</a></li>
149
+ <li class="mb-2">Click on "More Details" and copy the "TgAuth Session ID"</li>
150
+ <li>Paste the ID into the input field above and save</li>
151
+ </ol>
152
+ </div>
153
+ {% endif %}
154
+ </div>
155
+ </div>
156
+ </div>
@@ -0,0 +1,29 @@
1
+ <div class="container bg-white my-4 p-4 rounded">
2
+ <div class="row justify-content-center">
3
+ <div class="col-lg-8">
4
+ <div
5
+ class="bg-light rounded p-5 h-100 d-flex flex-column align-items-center justify-content-center shadow-sm">
6
+ <!-- TextGrid Logo -->
7
+ <img src="{{ url_for('static', filename='img/textgrid-logo.svg') }}" alt="TextGrid Logo"
8
+ style="max-width: 320px; height: auto;" class="mb-4">
9
+ <h2 class="fs-3 mb-4 text-center">
10
+ <i class="bi bi-cloud-upload text-primary me-2"></i>
11
+ Publish Project to <span class="text-primary">TextGrid Official Instance</span>
12
+ </h2>
13
+ <form method="POST"
14
+ action="{{ url_for('publication.upload_project', projectname=project.name, instance='live') }}"
15
+ class="w-100">
16
+ <button type="submit" class="btn btn-success btn-lg w-100 py-3" style="font-size:1.5rem;">
17
+ <i class="bi bi-rocket-takeoff me-2"></i>
18
+ Publish to Official Instance
19
+ </button>
20
+ </form>
21
+ <div class="alert alert-warning text-center mt-4 w-100" role="alert" style="font-size:1.1rem;">
22
+ <i class="bi bi-exclamation-triangle me-2"></i>
23
+ <b>Attention:</b> This action will publish your project to the official TextGrid instance.<br>
24
+ Please make sure you have checked your data carefully before proceeding!
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
@@ -1,46 +0,0 @@
1
- tg_prepare-1.0.0.dist-info/licenses/LICENSE,sha256=deYu6g1OGKm0VUwhM4Octoh8qlzjsiHHxoI-KkCBVBE,11351
2
- tgp_backend/__init__.py,sha256=4Q_pjhWDF2eAyPa8bvgIcBIrV0qGKa3uYgvYqTCmKWs,419
3
- tgp_backend/auth.py,sha256=hUPd0rc01BTT003xpkdmhNc6o0JztbAdimyDb0B9oTQ,2293
4
- tgp_backend/cli.py,sha256=iw_gknn-_m_UFZZUKfkV9aJixG3sVcHIONybNtOG40I,551
5
- tgp_backend/directories.py,sha256=CjrrBOL3Hov0b5SyyPRtMfmfcb3cSsLnTpBGJcI5Dto,2564
6
- tgp_backend/interfaces.py,sha256=SO7mOdhkd1f7irUBrwFhp5aKx3UKkkUzU9QBYDl0Tvc,91
7
- tgp_backend/nextcloud.py,sha256=9p-YT-oN05seWo2zwnfHSbvVa4Am7qONczfR6Fx8pqM,4424
8
- tgp_backend/project.py,sha256=yesTH2eHDJsSmBB4SLE12PAkGE4LdgatgPpAxVraWEk,8877
9
- tgp_backend/tgclient.py,sha256=DXqUQcTT6nwBPzkA3_Nl49bJtLiO-V8kGAI2f46hWiY,2980
10
- tgp_backend/util.py,sha256=PsRO7CGhHZjGubkM39KDuTwJwyfq_Gs7HM-n0DFlIZc,2210
11
- tgp_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- tgp_ui/app.py,sha256=SZp5YeTpNBLndNz4hoUCkc3voTzXNI2wsPZcIN7YLwc,12160
13
- tgp_ui/static/css/bootstrap-icons.min.css,sha256=XxUvYRPQvG4RTCkukUmXwvf1N0YF9KQ_ocuWV6O1dk8,85797
14
- tgp_ui/static/css/bootstrap.min.css,sha256=djO3wMl9GeaC_u6K-ic4Uj_LKhRUSlUFcsruzS7v5ms,155845
15
- tgp_ui/static/css/main.css,sha256=EK8euwgxX8I3qsBiDmIvj8UBIxkSKQZz1mo_OX4Q1FQ,2641
16
- tgp_ui/static/css/simpleXML.css,sha256=dfY7UZCiC79BkNOT1hM0GQ6v_yLSxhKCnmV0RZIT9S8,961
17
- tgp_ui/static/js/bootstrap.bundle.min.js,sha256=fh8VA992XMpeCZiRuU4xii75UIG6KvHrbUF8yIS_2_4,78743
18
- tgp_ui/static/js/jquery.min.js,sha256=_xUj-3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej_m4,89501
19
- tgp_ui/static/js/jstree.min.js,sha256=bLd6OqSD4Ff3ueyKs1cvu_mHhlFps_7SJ0P660kwuE4,141969
20
- tgp_ui/static/js/main.js,sha256=NB5xXJXLVLsUznce-RQjYll4pLlGI44EzzEc0gIMRzQ,15621
21
- tgp_ui/static/js/simpleXML.js,sha256=jEkZe3TuiHuEt6V7If_1EmqYIgTywssJ3OwOQzOFYNg,8065
22
- tgp_ui/templates/collection.html,sha256=WnYAH_5kJ6CzvVIqGk8XU_TZmhIrcOXggBoImyuGVZE,11416
23
- tgp_ui/templates/empty.html,sha256=__5AerKuSBFUn2yZGxEmjYzuGmmy81xYxm18ipU7dow,63
24
- tgp_ui/templates/file_tree.html,sha256=IKWp5MLUvnFF65cIUIxU4Jf5wi9Fg8koSXD96Mk328E,1640
25
- tgp_ui/templates/file_upload.html,sha256=fIelltVaTnqUqxBZoMy859IWbuwqNjrDZbVh9JlYl-g,1004
26
- tgp_ui/templates/jsfiler.html,sha256=TV27S3qWYe183zw7Bp8IGbPyyfESELpct_er_nysep0,134
27
- tgp_ui/templates/layout.html,sha256=6-rL9yIUoGei3M34ydTo4BUitR6y855chhClatG_0Bs,2766
28
- tgp_ui/templates/layout2.html,sha256=xtm3Uw-aE0iFaGsc7LvzQuPRdaQ5Lrt3tsFm6yH1_tI,4940
29
- tgp_ui/templates/macros.html,sha256=FFSPrllz12E6MJElpGFtZFbAS8PowAdY9Un9eqQX418,4047
30
- tgp_ui/templates/main.html,sha256=Aub0atvoi7f4GQWlV0P6RNHq08GHy2obyeDnrtkORo8,173
31
- tgp_ui/templates/nxc_file_tree.html,sha256=i8nLf71c9vUyAP46eC6BdJJVXgAJcJd4xcIv7vW6Y9k,1275
32
- tgp_ui/templates/nxc_login.html,sha256=tDxqHYPZqsY2ZNnkn4a5bMOYiD8ybcNRpzSq7MvMWCo,1269
33
- tgp_ui/templates/nxc_tab.html,sha256=9HWCa7UZKxL0fZasT_g6uozI64L-497Y2LppPPTHF2M,517
34
- tgp_ui/templates/project.html,sha256=11xH5_Y3w_g0hjND1XChv84F-D5wqlcOuYfTAuo37Ng,970
35
- tgp_ui/templates/project_nxc.html,sha256=Id0-9gRt4QnuavhHnSe6GXNsvCk-MAsNr3r3zkU5KD4,1468
36
- tgp_ui/templates/projects.html,sha256=X4NBmnTOCGpDEotHYjhm0g6wqJH_2DHFp9As2m1tjq4,3345
37
- tgp_ui/templates/publish.html,sha256=zEB3AdT3K8qLqDec10xzftNJpkTr_NI0aN8ZvZnS844,5612
38
- tgp_ui/templates/storage.html,sha256=ZgLIawovCTkgQy7aX3QB0cMlQj4uiby68c8aJFQ_HNw,1985
39
- tgp_ui/templates/tei_browser.html,sha256=Djq9GMIf3imMvYIWMWwNYCAL95pi3gV42VIdTJpZ_eM,372
40
- tgp_ui/templates/tei_explorer.html,sha256=YPLYZcgsqvA2AAL8NQ61Eo1ekwn3FEQf6pB58lLLL8U,2472
41
- tgp_ui/templates/xpath_parser_modal_content.html,sha256=Hm3VNtXbmEUIPFihGnE11AcSRdvMGro73IKjvDJAAqg,1573
42
- tg_prepare-1.0.0.dist-info/METADATA,sha256=6JqeJip2M-knbJylyAaYRVJoTeRVrOd5YCuVfUJk8pY,532
43
- tg_prepare-1.0.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
44
- tg_prepare-1.0.0.dist-info/entry_points.txt,sha256=mbsfiEA8_fQdrFUE_oabDi-Syw8jjli37Ms7tawDDhs,78
45
- tg_prepare-1.0.0.dist-info/top_level.txt,sha256=ueOyX_KdozreQJD_HRs6kAsvGNO4vfM9B_QqqhdyRPI,19
46
- tg_prepare-1.0.0.dist-info/RECORD,,