diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml new file mode 100644 index 0000000..fc42fbb --- /dev/null +++ b/.github/workflows/pypi.yml @@ -0,0 +1,105 @@ +name: upload-pypi + +on: + release: + types: [published] + +permissions: + contents: write + id-token: write + + +jobs: + release-build: + runs-on: ubuntu-latest + + steps: + - name: Set version from release tag + run: echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Build release distributions + run: | + # NOTE: put your own distribution build steps here. + python -m pip install build + python -m build + + - name: Upload distributions + uses: actions/upload-artifact@v4 + with: + name: release-dists + path: dist/ + + pypi-publish: + runs-on: ubuntu-latest + needs: + - release-build + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + + # Dedicated environments with protections for publishing are strongly recommended. + # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules + environment: + name: pypi + # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status: + #url: https://pypi.org/p/${GITHUB_REPOSITORY#*/} + # + # ALTERNATIVE: if your GitHub Release name is the PyPI project version string + # ALTERNATIVE: exactly, uncomment the following line instead: + url: https://pypi.org/project/${GITHUB_REPOSITORY#*/}/${{ github.event.release.name }} + + steps: + - name: Retrieve release distributions + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/ + sign-package: + runs-on: ubuntu-latest + needs: + - release-build + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + - name: Sign the dists with Sigstore + uses: sigstore/gh-action-sigstore-python@v3.0.0 + with: + inputs: >- + ./dist/*.tar.gz + ./dist/*.whl + publish-to-testpypi: + name: Publish Python 🐍 distribution 📦 to TestPyPI + needs: + - release-build + runs-on: ubuntu-latest + + environment: + name: testpypi + url: https://test.pypi.org/p/${GITHUB_REPOSITORY#*/} + + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + - name: Publish distribution 📦 to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8dc22e8..1c73052 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: '3.7' + python-version: '3.11' - name: Install requirements run: pip install flake8 pycodestyle - name: Check syntax @@ -18,16 +18,25 @@ jobs: needs: lint strategy: matrix: - ckan-version: ["2.10", 2.9] + include: + - ckan-version: "2.11" + ckan-image: "ckan/ckan-dev:2.11-py3.10" + solr-image: "2.11-solr9-spatial" + harvester-version: 'master' + - ckan-version: "2.10" + ckan-image: "ckan/ckan-dev:2.10-py3.10" + solr-image: "2.10-solr9-spatial" + harvester-version: 'master' fail-fast: false - name: CKAN ${{ matrix.ckan-version }} + name: CKAN ${{ matrix.ckan-version }}, Solr ${{ matrix.solr-image }} runs-on: ubuntu-latest container: - image: ckan/ckan-dev:${{ matrix.ckan-version }} + image: ${{ matrix.ckan-image }} + options: --user root services: solr: - image: ckan/ckan-solr:${{ matrix.ckan-version }} + image: ckan/ckan-solr:${{ matrix.solr-image }} postgres: image: ckan/ckan-postgres-dev:${{ matrix.ckan-version }} env: @@ -36,14 +45,14 @@ jobs: POSTGRES_DB: postgres options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 redis: - image: redis:3 + image: redis:7 env: CKAN_SQLALCHEMY_URL: postgresql://ckan_default:pass@postgres/ckan_test CKAN_DATASTORE_WRITE_URL: postgresql://datastore_write:pass@postgres/datastore_test CKAN_DATASTORE_READ_URL: postgresql://datastore_read:pass@postgres/datastore_test CKAN_SOLR_URL: http://solr:8983/solr/ckan CKAN_REDIS_URL: redis://redis:6379/1 - + steps: - uses: actions/checkout@v3 - name: Install requirements @@ -63,4 +72,4 @@ jobs: - name: Upload coverage report to codecov uses: codecov/codecov-action@v1 with: - file: ./coverage.xml \ No newline at end of file + file: ./coverage.xml--cov=ckanext.matolabtheme diff --git a/MANIFEST.in b/MANIFEST.in index e7d0ad1..3579131 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,3 +3,4 @@ include LICENSE include requirements.txt recursive-include ckanext/matolabtheme *.html *.json *.js *.less *.css *.mo *.yml recursive-include ckanext/matolabtheme/migration *.ini *.py *.mako +recursive-include ckanext/matolabtheme/public/static *.svg *.png diff --git a/README.md b/README.md index 66445da..3cfbe56 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,17 @@ [![Tests](https://github.com/Mat-O-Lab/ckanext-matolabtheme/actions/workflows/test.yml/badge.svg)](https://github.com/Mat-O-Lab/ckanext-matolabtheme/actions/workflows/test.yml) # ckanext-matolabtheme -**TODO:** Put a description of your extension here: What does it do? What features does it have? Consider including some screenshots or embedding a video! - +CKAN theme of the Mat-O-Lab Project, changes landing Page and add alternative Data Privacy Act in English and German. ## Requirements -**TODO:** For example, you might want to mention here which versions of CKAN this -extension works with. - -If your extension works across different versions you can add the following table: - Compatibility with core CKAN versions: | CKAN version | Compatible? | | --------------- | ------------- | -| 2.6 and earlier | not tested | -| 2.7 | not tested | -| 2.8 | not tested | -| 2.9 | not tested | +| 2.9 and earlier | not tested | +| 2.10 | yes | +| 2.11 | yes | Suggested values: @@ -30,106 +23,64 @@ Suggested values: ## Installation -**TODO:** Add any additional install steps to the list below. - For example installing any non-Python dependencies or adding any required - config settings. - -To install ckanext-matolabtheme: +To install the extension: 1. Activate your CKAN virtual environment, for example: - - . /usr/lib/ckan/default/bin/activate - -2. Clone the source and install it on the virtualenv - - git clone https://github.com/Mat-O-Lab/ckanext-matolabtheme.git - cd ckanext-matolabtheme - pip install -e . - pip install -r requirements.txt - +```bash +. /usr/lib/ckan/default/bin/activate +``` +2. Use pip to install package +```bash +pip install ckanext-matolabtheme +``` 3. Add `matolabtheme` to the `ckan.plugins` setting in your CKAN - config file (by default the config file is located at - `/etc/ckan/default/ckan.ini`). - -4. Restart CKAN. For example if you've deployed CKAN with Apache on Ubuntu: - - sudo service apache2 reload +   config file (by default the config file is located at +   `/etc/ckan/default/ckan.ini`). +4. Restart CKAN. For example, if you've deployed CKAN with Apache on Ubuntu: +```bash +sudo service apache2 reload +``` ## Config settings ```bash -CKANINI__CKANEXT__MATOLABTHEME__CONTACT_URL = -CKANINI__CKANEXT__MATOLABTHEME__LEGAL_PERSON_MD = -CKANINI__CKANEXT__MATOLABTHEME__DSVGO_CONTACT_MD = +CKANINI__CKANEXT__MATOLABTHEME__CONTACT_URL= +CKANINI__CKANEXT__MATOLABTHEME__LEGAL_PERSON_MD= +CKANINI__CKANEXT__MATOLABTHEME__LEGAL_NOTICE_URL= +CKANINI__CKANEXT__MATOLABTHEME__DSVGO_CONTACT_MD= +CKANINI__CKANEXT__MATOLABTHEME__CONTACT_DP_COMMISSIONER_EMAIL_MD="[datenprotection_commissioner@example.de](mailto:datenschutzbeauftragte@example.de?subject=dataprotection ${CKAN_HOST})" CKANINI__CKAN__FAVICON=/img/favicon.png ``` or ckan.ini parameters. ```bash ckan.matolabtheme.contact_url = ckan.matolabtheme.legal_person_md = +ckan.matolabtheme.legal_notice_url = ckan.matolabtheme.dsvgo_contact_md = +ckan.matolabtheme.dsvgo_contact_md = "[datenprotection_commissioner@example.de](mailto:datenschutzbeauftragte@example.de?subject=dataprotection]" ckan.favicon = /img/favicon.png ``` If no contact_url is given, it will relate to the about page! -**TODO:** Document any optional config settings here. For example: - - # The minimum number of hours to wait before re-checking a resource - # (optional, default: 24). - ckanext.matolabtheme.some_setting = some_default_value - - ## Developer installation -To install ckanext-matolabtheme for development, activate your CKAN virtualenv and +To install ckanext-csvtocsvw for development, activate your CKAN virtualenv and do: - - git clone https://github.com/Mat-O-Lab/ckanext-matolabtheme.git - cd ckanext-matolabtheme - python setup.py develop - pip install -r dev-requirements.txt - +```bash +git clone https://github.com/Mat-O-Lab/ckanext-matolabtheme.git +cd ckanext-matolabtheme +python setup.py develop +pip install -r dev-requirements.txt +``` ## Tests To run the tests, do: - - pytest --ckan-ini=test.ini - - -## Releasing a new version of ckanext-matolabtheme - -If ckanext-matolabtheme should be available on PyPI you can follow these steps to publish a new version: - -1. Update the version number in the `setup.py` file. See [PEP 440](http://legacy.python.org/dev/peps/pep-0440/#public-version-identifiers) for how to choose version numbers. - -2. Make sure you have the latest version of necessary packages: - - pip install --upgrade setuptools wheel twine - -3. Create a source and binary distributions of the new version: - - python setup.py sdist bdist_wheel && twine check dist/* - - Fix any errors you get. - -4. Upload the source distribution to PyPI: - - twine upload dist/* - -5. Commit any outstanding changes: - - git commit -a - git push - -6. Tag the new release of the project on GitHub with the version number from - the `setup.py` file. For example if the version number in `setup.py` is - 0.0.1 then do: - - git tag 0.0.1 - git push --tags +```bash +pytest --ckan-ini=test.ini +``` ## License diff --git a/ckanext/matolabtheme/action.py b/ckanext/matolabtheme/action.py new file mode 100644 index 0000000..7a39592 --- /dev/null +++ b/ckanext/matolabtheme/action.py @@ -0,0 +1,74 @@ +import ckan.plugins.toolkit as toolkit + +if toolkit.check_ckan_version("2.10"): + from ckan.types import Context +else: + + class Context(dict): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + +from typing import Any +from sqlalchemy import Table, select, func, and_, false +import ckan.model as model + + +def table(name: str): + return Table(name, model.meta.metadata, autoload_with=model.meta.engine) + + +# Function to serialize SQLAlchemy result +def serialize_row(row): + return {column: getattr(row, column) for column in row._mapping} + + +@toolkit.side_effect_free +def theme_stats(context: Context, data_dict: dict[str, Any]) -> dict[str, Any]: + package = table("package") + resource = table("resource") + session = model.Session + s = ( + select( + package.c["owner_org"], + func.count(package.c["id"]).label("count"), + ) + .group_by(package.c["owner_org"]) + .where( + and_( + package.c["owner_org"].isnot(None), + package.c["private"] == false(), + package.c["state"] == "active", + ) + ) + .order_by(func.count(package.c["id"]).desc()) + # .limit(limit) + ) + conn: Any = model.Session.connection() + # cursor = conn.execute(q) + + org_rows = conn.execute(s).fetchall() + s = select( + func.count(resource.c["id"]), + ).where( + and_( + resource.c["state"] != "deleted", + ) + ) + res_rows = conn.execute(s).fetchall() + orgs = [serialize_row(row) for row in org_rows] + org_count = len(orgs) + pkg_sum = sum([org.get("count", 0) for org in orgs]) + res = res_rows[0]["count_1"] if len(res_rows) > 0 else None + # res_count = len(model.Package().resources) + return { + "orgs": orgs, + "pkg_count": pkg_sum, + "res_count": res, + "org_count": org_count, + } + + +def get_actions(): + actions = {"matolabtheme_stats": theme_stats} + return actions diff --git a/ckanext/matolabtheme/assets/dark.css b/ckanext/matolabtheme/assets/dark.css new file mode 100644 index 0000000..3db35f2 --- /dev/null +++ b/ckanext/matolabtheme/assets/dark.css @@ -0,0 +1,76 @@ +/*! + * Dark Mode Overrides for Bootstrap-Dark + * Include this file after light.css to enable dark mode. + */ + +/* Dark Mode Variable Overrides */ +@media (prefers-color-scheme: dark) { + :root { + --bs-white: #fafafa; + --bs-black: #111; + --bs-gray: #7e7e7e; + --bs-primary: #375a7f; + --bs-secondary: #4e6c7e; + --bs-light: #2a333c; + --bs-primary-rgb: 55, 90, 127; + --bs-secondary-rgb: 78, 108, 126; + --bs-light-rgb: 42, 51, 60; + --bs-body-bg-rgb: 34, 34, 34; + --bs-body-color: #a6bbc8; + --bs-body-bg: #222; + --bs-table-bg: var(--bs-body-bg); + } + + /* Dark Mode Utility Classes */ + .d-dark-inline { display: inline !important; } + .d-dark-inline-block { display: inline-block !important; } + .d-dark-block { display: block !important; } + .d-dark-grid { display: grid !important; } + .d-dark-table { display: table !important; } + .d-dark-table-row { display: table-row !important; } + .d-dark-table-cell { display: table-cell !important; } + .d-dark-flex { display: flex !important; } + .d-dark-inline-flex { display: inline-flex !important; } + .d-dark-none { display: none !important; } + + /* Additional Dark-Specific Overrides */ + .tag { + color: var(--bs-body-color); + } + .btn { + color: var(--bs-body-color); + } + .counter-link:hover { + color: var(--bs-body-color); + text-decoration: none; + } + .text-light { + color: var(--bs-body-color) !important; + } + .site-footer .attribution .row .col, + .site-footer a, + .site-footer .text-end, + .site-footer .attribution p, + .site-footer label { color: var(--bs-body-color) !important; } + + + .checkbox input[type=checkbox], .form-check-input { + background-color: var(--bs-body-bg); + } + .accordion-item { + background-color: var(--bs-body-bg); + } + .accordion-button, .accordion-button:not(.collapsed){ + background-color: var(--bs-body-color); + } + .navbar-nav li a { + color: var(--bs-body-color); + } + .nav-tabs .nav-link.active, + .nav-tabs .nav-item.show .nav-link { + color: var(--bs-body-color); + } + +} + /* End of dark.css */ + \ No newline at end of file diff --git a/ckanext/matolabtheme/assets/index.js b/ckanext/matolabtheme/assets/index.js new file mode 100644 index 0000000..c61261e --- /dev/null +++ b/ckanext/matolabtheme/assets/index.js @@ -0,0 +1,65 @@ +'use strict'; + +ckan.module('matolabtheme-module', function ($) { + return { + initialize: function () { + console.log('matolabtheme-module initialized!'); + console.log('Element:', this.el); + + const updateCounter = (counter, targetValue) => { + counter.innerText = '0'; // Start the counter from 0 + counter.setAttribute('data-target', targetValue); // Update data-target attribute + + const duration = +counter.getAttribute('data-duration') * 1000; + const increment = targetValue / (duration / 10); + let count = 0; + + const animate = () => { + count += increment; + + if (count >= targetValue) { + counter.innerText = targetValue; // Final value + } else { + counter.innerText = Math.ceil(count); // Animated value + requestAnimationFrame(animate); + } + }; + + requestAnimationFrame(animate); + }; + + const fetchAndAnimateCounter = async () => { + const apiUrl = this.el.get(0).getAttribute('data-api-url'); + if (!apiUrl) { + console.error('No API URL specified for counter:', this.el); + return; + } + + try { + const response = await $.getJSON(apiUrl); + let datasetCount = 0; + let totalResources = 0; + let orgCount = 0; + + if (response && response.success && response.result) { + const result = response.result; + // Count datasets, resources, and organizations + datasetCount = result.pkg_count || 0; // `pkg_count` for datasets + totalResources = result.res_count || 0; // `res_count` for resources + orgCount = result.org_count || 0; // `org_count` for organizations + } else { + console.error('Invalid API response structure:', response); + } + + updateCounter(document.getElementById('dataset_counter'), datasetCount); + updateCounter(document.getElementById('resource_counter'), totalResources); + updateCounter(document.getElementById('orgs_counter'), orgCount); + } catch (error) { + console.error(`API request to ${apiUrl} failed:`, error); + } + }; + + fetchAndAnimateCounter(); + }, + }; +}); diff --git a/ckanext/matolabtheme/assets/script.js b/ckanext/matolabtheme/assets/script.js index b343078..0de2488 100644 --- a/ckanext/matolabtheme/assets/script.js +++ b/ckanext/matolabtheme/assets/script.js @@ -1,35 +1,27 @@ -ckan.module("matolabtheme-module", function ($, _) { - "use strict"; - return { - options: { - debug: false, - }, - initialize: function () { - console.log("Initialized Counter Animation for element: ", this.el); - const counters = this.el.get(0).querySelectorAll('.theme-counter') - // this.el.querySelectorAll(".theme-counter"); - counters.forEach((counter) => { - console.log("counter element: ", counter); - counter.innerText = "0"; - const updateCounter = () => { - const target = +counter.getAttribute("data-target"); - const duration = +counter.getAttribute("data-duration") * 1000; - const count = +counter.innerText; - const increment = (target - count) / duration * 10; - const currentTime = Date.now(); - const endTime = currentTime + duration; - const animate = () => { - const remaining = Math.max((endTime - Date.now()) / duration, 0); - const currentCount = Math.round(target - (target - count) * remaining); - counter.innerText = currentCount; - if (remaining > 0) { - requestAnimationFrame(animate); - } - }; - requestAnimationFrame(animate); - }; - updateCounter(); - }); - }, - }; +$(document).ready(function () { + let hoveredForm = null; + + // Track which form the mouse is currently over + $(document).on('mouseenter', 'form', function () { + hoveredForm = $(this); + }); + + $(document).on('mouseleave', 'form', function () { + hoveredForm = null; + }); + + // Listen for Shift + Enter keypress + $(document).on('keydown', function (event) { + if (event.shiftKey && event.key === 'Enter') { + event.preventDefault(); // Prevent default behavior + + // Find the submit button in the hovered form (or the focused form) + const form = hoveredForm || $(event.target).closest('form'); + const button = form.find('.form-actions button[type="submit"]').last(); + + if (button.length) { + button.click(); // Trigger the button's click event + } + } + }); }); diff --git a/ckanext/matolabtheme/assets/style.css b/ckanext/matolabtheme/assets/style.css index ce7746b..3841d76 100644 --- a/ckanext/matolabtheme/assets/style.css +++ b/ckanext/matolabtheme/assets/style.css @@ -1,34 +1,30 @@ @charset "UTF-8"; - /*! * Bootstrap v5.1.3 (https://getbootstrap.com/) - * Copyright 2011-2022The Bootstrap Authors - * Copyright 2011-2022 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * * Bootstrap-Dark v1.1.3 (https://vinorodrigues.github.io/bootstrap-dark-5/) - * Copyright 2020-2022 Vino Rodrigues - * This version is a dual color theme, with the default light mode and the dark - * elements optioned in by a `prefers-color-scheme: dark` media query + * + * This file contains the default (light mode) styles. */ + +/* Base Variables and Settings for Light Mode */ :root { color-scheme: light dark; } :root { - --bs-primary: #27529c; - --bs-secondary: #869ab8; - --bs-success: #80a733; - --bs-info: #bdd34e; - --bs-warning: #f58220; + --bs-primary: #005b7f; + --bs-secondary: #a6bbc8; + --bs-success: #179C7d; + --bs-info: #f58220; + --bs-warning: #b2d235; --bs-danger: #dc3545; --bs-light: #f8f9fa; --bs-dark: #212529; - --bs-primary-rgb: 39, 82, 156; - --bs-secondary-rgb: 134, 154, 184; - --bs-success-rgb: 128, 167, 51; - --bs-info-rgb: 189, 211, 78; - --bs-warning-rgb: 245, 130, 32; + --bs-primary-rgb: 0, 91, 127; + --bs-secondary-rgb: 166, 187, 200; + --bs-success-rgb: 23, 156, 125; + --bs-info-rgb: 245, 130, 32; + --bs-warning-rgb: 178, 210, 53; --bs-danger-rgb: 220, 53, 69; --bs-light-rgb: 248, 249, 250; --bs-dark-rgb: 33, 37, 41; @@ -47,29 +43,28 @@ --bs-body-bg: #fff; --bs-lightgray: #cccccc; --bs-table-bg: var(--bs-body-bg); - } -@media (prefers-color-scheme: dark) { - :root { - --bs-white: #fafafa; - --bs-black: #111; - --bs-gray: #7e7e7e; - --bs-primary: #193666; - --bs-secondary: #2f3c50; - --bs-light: #151a1e; - --bs-primary-rgb: 25, 54, 102; - --bs-secondary-rgb: 47, 60, 80; - --bs-light-rgb: 21, 26, 30; - --bs-body-bg-rgb: 34, 34, 34; - --bs-body-color: #a6bbc8; - --bs-body-bg: #222; - --bs-table-bg: var(--bs-body-bg); - } -} - - - +/* Light Mode Utility Classes (wrapped in a media query for clarity) */ +@media (prefers-color-scheme: light) { + .d-light-inline { display: inline !important; } + .d-light-inline-block { display: inline-block !important; } + .d-light-block { display: block !important; } + .d-light-grid { display: grid !important; } + .d-light-table { display: table !important; } + .d-light-table-row { display: table-row !important; } + .d-light-table-cell { display: table-cell !important; } + .d-light-flex { display: flex !important; } + .d-light-inline-flex { display: inline-flex !important; } + .d-light-none { display: none !important; } +} +.site-footer .attribution .row .col, + .site-footer a, + .site-footer .text-end, + .site-footer .attribution p, + .site-footer label { color: var(--bs-light) !important; } + +/* Common Styles */ *, *::before, *::after { @@ -77,9 +72,7 @@ } @media (prefers-reduced-motion: no-preference) { - :root { - scroll-behavior: smooth; - } + :root { scroll-behavior: smooth; } } body { @@ -92,9 +85,11 @@ body { text-align: var(--bs-body-text-align); background-color: rgba(var(--bs-body-bg-rgb), 1.0); -webkit-text-size-adjust: 100%; + flex-direction: column !important; + min-height: 100vh !important; + display: flex !important; } - .main { background: none; } @@ -105,10 +100,9 @@ body { left: 0; width: 100%; height: 100%; - background-color: rgba(var(--bs-body-bg-rgb) 0.5); + background-color: rgba(var(--bs-body-bg-rgb), 0.5); /* change the alpha value as needed */ z-index: -1; - /* background-size:100% 100%; */ mix-blend-mode: multiply; opacity: 0.05; } @@ -119,11 +113,20 @@ a { } a:hover { - color: var(--bs-primary) !important; + color: var(--bs-primary); text-decoration: underline; } -.module-narrow .nav-item>a, +.nav-link:hover { + color: var(--bs-light) !important; +} + +.counter-link:hover { + color: var(--bs-dark); + text-decoration: none; +} + +.module-narrow .nav-item > a, .module-narrow .nav-aside li a { color: var(--bs-body-color); } @@ -132,10 +135,6 @@ a:hover { color: inherit; } -.navbar-dark .navbar-brand { - -webkit-filter: brightness(0) invert(1); -} - .homepage .module-promotion { background: var(--bs-light); } @@ -144,17 +143,20 @@ a:hover { background-size: 100% 100%; } +.index-logo { + max-height: 150px; +} + .navbar-nav li a { display: block; width: 100%; - padding: 0.25rem 1rem; + padding: 0.5rem; clear: both; font-weight: 400; text-align: inherit; white-space: nowrap; background-color: transparent; border: 0; - padding: 0.5rem 0.5rem; color: var(--bs-light); } @@ -162,14 +164,10 @@ a:hover { background-color: var(--bs-body-bg) !important; } - - .dropdown-menu li a { color: var(--bs-body-color); } - - aside { background: var(--bs-light); } @@ -178,6 +176,11 @@ aside { background-color: rgba(var(--bs-light-rgb), 1.0); } +.wrapper { + position: relative; + min-height: 300px; + background-color: var(--bs-body-bg); +} .theme-counter { display: inline; @@ -188,13 +191,8 @@ aside { } @keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } + from { opacity: 0; } + to { opacity: 1; } } .popup { @@ -203,13 +201,11 @@ aside { animation-name: fadeIn; } - .editor .editor-info-block { background-color: var(--bs-secondary); color: var(--bs-light); } - .form-switch .form-check-input, .form-switch .form-check-input:checked { background-color: rgba(var(--bs-primary-rgb), 0.7); @@ -221,13 +217,13 @@ aside { background-color: var(--bs-body-bg); } -table.dataTable thead tr>.dtfc-fixed-left, -table.dataTable thead tr>.dtfc-fixed-right { +table.dataTable thead tr > .dtfc-fixed-left, +table.dataTable thead tr > .dtfc-fixed-right { background-color: inherit !important; } -table.dataTable tbody tr>.dtfc-fixed-left, -table.dataTable tbody tr>.dtfc-fixed-right { +table.dataTable tbody tr > .dtfc-fixed-left, +table.dataTable tbody tr > .dtfc-fixed-right { background-color: inherit !important; } @@ -251,14 +247,12 @@ table.dataTable tbody tr>.dtfc-fixed-right { border-color: #dee2e6 #dee2e6 #fff; } - .counter-row { background-color: rgba(var(--bs-light-rgb), 0.1) !important; } - .counter-link, -.counter-link>a:hover { +.counter-link > a:hover { display: block; padding: 0.5rem 1rem; color: var(--bs-primary); @@ -284,22 +278,11 @@ table.dataTable tbody tr>.dtfc-fixed-right { color: var(--bs-info); } - .site-footer { background-size: 100% 100%; - /* mix-blend-mode: multiply; */ padding: 20px 0; - background-size: cover; - background-position: bottom; -} - -.site-footer a, -.site-footer .attribution p, -.site-footer label { - color: var(--bs-light) !important; } - .page-header .nav-tabs li.active a, .page-header .nav-tabs a:hover { background-color: var(--bs-light); @@ -307,7 +290,7 @@ table.dataTable tbody tr>.dtfc-fixed-right { .nav-link, .page-header .nav-tabs li a { - color: var(--bs-primary); + color: var(--bs-body-color); } .media-grid, @@ -323,31 +306,31 @@ table.dataTable tbody tr>.dtfc-fixed-right { background-color: var(--bs-light); } -.badge[data-format=csv], -.badge[data-format*=csv] { +.badge[data-format="csv"], +.badge[data-format*="csv"] { background-color: var(--bs-info); } -.badge[data-format=json], -.badge[data-format*=json] { +.badge[data-format="json"], +.badge[data-format*="json"] { background-color: var(--bs-warning); } -.badge[data-format=pdf], -.badge[data-format*=pdf] { +.badge[data-format="pdf"], +.badge[data-format*="pdf"] { background-color: var(--bs-danger); } -.badge[data-format=rdf], -.badge[data-format*=rdf], -.badge[data-format*=nquad], -.badge[data-format*=ntriples], -.badge[data-format*=turtle] { +.badge[data-format="rdf"], +.badge[data-format*="rdf"], +.badge[data-format*="nquad"], +.badge[data-format*="ntriples"], +.badge[data-format*="turtle"] { background-color: var(--bs-primary); } -.badge[data-format=zip], -.badge[data-format*=zip] { +.badge[data-format="zip"], +.badge[data-format*="zip"] { background-color: var(--bs-secondary); } @@ -355,28 +338,23 @@ table.dataTable tbody tr>.dtfc-fixed-right { border: 1px solid var(--bs-body-color); color: var(--bs-body-color); background-color: var(--bs-body-bg) !important; - } -.controls>.form-control, -.input-group>.form-control, -.input-group>.form-select { +.controls > .form-control, +.input-group > .form-control, +.input-group > .form-select { color: var(--bs-body-color); background-color: var(--bs-body-bg); } .search-form .control-order-by .form-control { - /* color: var(--bs-light); */ background-color: var(--bs-body-bg); - } .select2-container .select2-choice { color: inherit !important; border-radius: 4px; background-color: var(--bs-body-bg); - /* background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%); */ - /* background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%); */ background-image: linear-gradient(to top, var(--bs-light) 0%, var(--bs-body-bg) 50%) !important; } @@ -425,157 +403,61 @@ table.dataTable tbody tr>.dtfc-fixed-right { pointer-events: none; background-color: var(--bs-body-bg); border-color: var(--bs-body-color); +} - /* .btn { +.btn-outline-light { + color: var(--bs-light) !important; + border-color: var(--bs-light); +} + +.btn-outline-light:hover { + color: var(--bs-light); + border-color: var(--bs-dark); + background-color: var(--bs-dark); +} + +.btn-light, +.btn-default { color: var(--bs-body-color); -} */ - - .btn-outline-light { - color: var(--bs-light); - border-color: var(--bs-light); - } - - - .btn-light, - .btn-default { - color: var(--bs-body-color); - background-color: var(--bs-light); - border-color: var(--bs-secondary); - } - - .badge { - color: var(--bs-body-color); - } - - .tag-list { - background-color: rgba(var(--bs-body-bg)); - } - - .tag { - color: var(--bs-light); - background-color: var(--bs-primary); - border: var(--bs-primary); - box-shadow: inset 0 1px 0 rgba(var(--bs-body-color-rgb), 0.15), 0 1px 1px rgba(var(--bs-body-bg-rgb), 0.075); - } - - .table { - --bs-table-bg: transparent; - --bs-table-accent-bg: transparent; - --bs-table-striped-color: var(--bs-body-color); - --bs-table-striped-bg: rgba(var(--bs-primary-rgb), 0.2); - /* --bs-table-active-color: #212529; */ - /* --bs-table-active-bg: rgba(0, 0, 0, 0.1); */ - /* --bs-table-hover-color: #212529; */ - /* --bs-table-hover-bg: rgba(0, 0, 0, 0.075); */ - /* width: 100%; */ - /* margin-bottom: 1rem; */ - color: var(--bs-body-color); - /* vertical-align: top; */ - /* border-color: #dee2e6; */ - } - - .tab-content>.tab-pane { - display: none; - } - - .tab-content>.active { - display: block; - } - - - /* - * ---------- Dark Mode ------------------------------------------------------ - */ - @media (prefers-color-scheme: light) { - .d-light-inline { - display: inline !important; - } - - .d-light-inline-block { - display: inline-block !important; - } - - .d-light-block { - display: block !important; - } - - .d-light-grid { - display: grid !important; - } - - .d-light-table { - display: table !important; - } - - .d-light-table-row { - display: table-row !important; - } - - .d-light-table-cell { - display: table-cell !important; - } - - .d-light-flex { - display: flex !important; - } - - .d-light-inline-flex { - display: inline-flex !important; - } - - .d-light-none { - display: none !important; - } - } - - @media (prefers-color-scheme: dark) { - .d-dark-inline { - display: inline !important; - } - - .d-dark-inline-block { - display: inline-block !important; - } - - .d-dark-block { - display: block !important; - } - - .d-dark-grid { - display: grid !important; - } - - .d-dark-table { - display: table !important; - } - - .d-dark-table-row { - display: table-row !important; - } - - .d-dark-table-cell { - display: table-cell !important; - } - - .d-dark-flex { - display: flex !important; - } - - .d-dark-inline-flex { - display: inline-flex !important; - } - - .d-dark-none { - display: none !important; - } - - .tag { - color: var(--bs-body-color); - } - - .btn { - color: var(--bs-body-color); - } - } - - /*# sourceMappingURL=bootstrap-dark.css.map */ \ No newline at end of file + background-color: var(--bs-light); + border-color: var(--bs-light); +} + +.btn-primary { + background-color: var(--bs-primary); + border-color: var(--bs-primary); +} + +.badge { + color: var(--bs-light); +} + +.tag-list { + background-color: rgba(var(--bs-body-bg)); +} + +.tag { + color: var(--bs-light); + background-color: var(--bs-primary); + border: var(--bs-primary); + box-shadow: inset 0 1px 0 rgba(var(--bs-body-color-rgb), 0.15), + 0 1px 1px rgba(var(--bs-body-bg-rgb), 0.075); +} + +.table { + --bs-table-bg: transparent; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: var(--bs-body-color); + --bs-table-striped-bg: rgba(var(--bs-primary-rgb), 0.2); + color: var(--bs-body-color); +} + +.tab-content > .tab-pane { + display: none; +} + +.tab-content > .active { + display: block; +} + +/* End of light.css */ diff --git a/ckanext/matolabtheme/assets/webassets.yml b/ckanext/matolabtheme/assets/webassets.yml index 56c90d6..b18cf35 100644 --- a/ckanext/matolabtheme/assets/webassets.yml +++ b/ckanext/matolabtheme/assets/webassets.yml @@ -6,8 +6,20 @@ js: extra: preload: - base/main - +index-js: + filters: rjsmin + output: matolabtheme/matolabtheme_index.js + contents: + - index.js + extra: + preload: + - base/main style: contents: - style.css output: matolabtheme/matolabtheme.css + +dark: + contents: + - dark.css + output: matolabtheme/matolabtheme_dark.css diff --git a/ckanext/matolabtheme/auth.py b/ckanext/matolabtheme/auth.py new file mode 100644 index 0000000..6fcf77b --- /dev/null +++ b/ckanext/matolabtheme/auth.py @@ -0,0 +1,23 @@ +# import ckanext.datastore.logic.auth as auth +from typing import Any + +import ckan.plugins.toolkit as toolkit + +if toolkit.check_ckan_version("2.10"): + from ckan.types import Context +else: + + class Context(dict): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + +def theme_stats(context: Context, data_dict: dict[str, Any]): + # List of all active packages are visible by default + return {"success": True} + + +def get_auth_functions(): + return { + "theme_stats": theme_stats, + } diff --git a/ckanext/matolabtheme/helpers.py b/ckanext/matolabtheme/helpers.py index 045a590..beea45d 100644 --- a/ckanext/matolabtheme/helpers.py +++ b/ckanext/matolabtheme/helpers.py @@ -22,18 +22,6 @@ def contact_url(): return CONTACT_URL -def all_datasets_count(): - return toolkit.get_action("package_search")({}, {})["count"] - - -def all_resource_count(): - return toolkit.get_action("resource_search")({}, {"query": "name:"})["count"] - - -def all_organizations_count(): - return len(toolkit.get_action("organization_list")({}, {})) - - def custom_build_nav_main( *args: Union[ tuple[str, str], @@ -108,8 +96,5 @@ def get_helpers(): return { "parent_site_url": parent_site_url, "custom_build_nav_main": custom_build_nav_main, - "all_datasets_count": all_datasets_count, - "all_resource_count": all_resource_count, - "all_organizations_count": all_organizations_count, "contact_url": contact_url, } diff --git a/ckanext/matolabtheme/i18n/ckanext-matolabtheme.pot b/ckanext/matolabtheme/i18n/ckanext-matolabtheme.pot new file mode 100644 index 0000000..e097760 --- /dev/null +++ b/ckanext/matolabtheme/i18n/ckanext-matolabtheme.pot @@ -0,0 +1,586 @@ +# Translations template for ckanext-matolabtheme. +# Copyright (C) 2025 ORGANIZATION +# This file is distributed under the same license as the ckanext-matolabtheme +# project. +# FIRST AUTHOR , 2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: ckanext-matolabtheme 0.0.1\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2025-05-19 09:58+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.15.0\n" + +#: ckanext/matolabtheme/views.py:40 ckanext/matolabtheme/views.py:127 +msgid "Need to be system administrator to administer" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:9 +msgid "About {0}" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:15 +msgid "Data Privacy" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:16 +msgid "CKAN API" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:17 +msgid "CKAN Association" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:28 +msgid "Powered by" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:33 +msgid "Provided by" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:41 +msgid "Contact Us" +msgstr "" + +#: ckanext/matolabtheme/templates/footer.html:42 +msgid "Legal Notice" +msgstr "" + +#: ckanext/matolabtheme/templates/header.html:41 +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:36 +msgid "Search" +msgstr "" + +#: ckanext/matolabtheme/templates/header.html:42 +msgid "Search datasets..." +msgstr "" + +#: ckanext/matolabtheme/templates/header.html:43 +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:37 +msgid "Submit" +msgstr "" + +#: ckanext/matolabtheme/templates/header.html:54 +#: ckanext/matolabtheme/templates/header.html:62 +#: ckanext/matolabtheme/templates/header.html:64 +msgid "View profile" +msgstr "" + +#: ckanext/matolabtheme/templates/admin/config.html:5 +msgid "Theme Config" +msgstr "" + +#: ckanext/matolabtheme/templates/home/index.html:3 +msgid "Welcome" +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:23 +msgid "Welcome to CKAN" +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:25 +msgid "" +"This is a nice introductory paragraph about CKAN or the site in general. We " +"don't have any copy to go here yet but soon we will" +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:36 +msgid "Search our database..." +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:58 +msgid "Log in" +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:71 +msgid "Datasets" +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:80 +msgid "Resources" +msgstr "" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:89 +msgid "Organizations" +msgstr "" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:15 +msgid "http://example.com/my-image.jpg" +msgstr "" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:16 +msgid "Image URL" +msgstr "" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:17 +msgid "Image" +msgstr "" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:45 +msgid "Clear Upload" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:3 +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:10 +msgid "Data Protection" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:16 +msgid "" +"Information on data protection in accordance with Art. 13 of the General Data" +" Protection Regulation (GDPR) on" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:18 +msgid "" +"The following information provides you with an overview of the processing of " +"your personal data on " +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:18 +msgid "" +"and your rights under data protection law. According to Art. 4 No. 1 of the " +"EU General Data Protection Regulation (GDPR), personal data is any " +"information relating to an identified or identifiable natural person." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:20 +msgid "Table of Contents" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:23 +msgid "Controller and Data Protection Commissioner " +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:25 +msgid "" +"According to the GDPR (Art. 4, No. 7) and other data protection regulations, " +"the controller is:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:29 +msgid "The controller is a public corporation represented by its President." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:31 +msgid "The Data Protection Commissioner can be contacted by email at:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:33 +msgid "" +"or by ordinary mail with Data Protection Commissioner being indicated on the " +"envelope." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:35 +msgid "Accessing the website and server log files (visiting the portal)" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:37 +msgid "The anonymized IP address" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:38 +msgid "The date and time of access" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:39 +msgid "The URL of the retrieved file" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:40 +msgid "The amount of data transferred" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:41 +msgid "The message indicating whether the retrieval was successful" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:42 +msgid "The information about the browser and operating system used" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:43 +msgid "The URL of the website from which the access occurred" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:44 +msgid "The name of the internet service provider" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:46 +msgid "" +"Scope and Purpose: When using the website for information purposes only, i.e." +" when you do not register or transmit other information, we will only collect" +" the personal data that are transmitted by your browser to our server " +"according to the settings made by you. The data serves the technical " +"optimization of the website and to ensure the security of our information " +"technology systems. The IP address is necessary for the operation or delivery" +" of the website, is shortened in the log files, and is no longer available as" +" a whole after the request. A direct conclusion about individual persons is " +"not possible based on this data. A matching with other data records does not " +"take place. We reserve the right to review this data retrospectively if we " +"become aware of specific indications of illegal use." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:47 +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:63 +msgid "Recipient: There is no transfer of data to third parties." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:48 +msgid "" +"Legal basis: The legal basis for processing is Art. 6 par. 1 (b), par. 3 (b) " +"GDPR in conjunction with Art. 4 State Data Protection Act " +"\"Landesdatenschutzgesetz\" (LSDG) respectively Art. 20 par. 1 KITG in " +"conjunction with Art. 12 par. 1 Higher Education Acts " +"\"Landeshochschulgesetz\" (LHG)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:49 +msgid "" +"Storage duration: The personal data will be stored as long as it is necessary" +" to achieve the purpose for which it was collected. The data will be deleted " +"after a maximum of seven days." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:51 +msgid "Example of processing:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:53 +msgid "" +"The collection and processing of this data is carried out for the purpose of " +"providing the platform (establishing a connection), permanently ensuring " +"system security and stability, technical administration of the network " +"infrastructure, optimizing the internet offering, and general statistical " +"evaluation. A personal reference is not possible due to the anonymization of " +"the IP address." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:54 +msgid "" +"The operator collects and stores this data to ensure the management of users " +"and the processing of processes associated with their roles." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:55 +msgid "" +"If a user contacts the operator using the contact details provided in the " +"imprint, personal data will be processed." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:58 +msgid "Cookies" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:59 +msgid "" +"Scope and Purpose: In addition to the above data, cookies will be stored on " +"your computer when using our website. Cookies are small text files stored by " +"the browser you use. From these cookies, we (the server of our website) " +"obtain certain information. We use so-called session cookies (transient " +"cookies) that are technically required to make the website work. The " +"following data is stored and transmitted in the cookies we use:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:61 +msgid "Anonymous user ID as UUID" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:64 +msgid "" +"Legal basis: The legal basis for the processing of personal data using " +"technically necessary cookies in accordance with § 25 (2) Telecommunications " +"Digital Services Data Protection Act \"Telekommunikation-Digitale-Dienste-" +"Datenschutz-Gesetz\" (TDDDG) is Art. 6(1)(f) of the GDPR. The legitimate " +"interest of the operator in data processing according to Art. 6(1)(f) of the " +"GDPR is also present in the aforementioned purposes." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:65 +msgid "" +"Storage duration: The session cookies will be deleted at the latest when you " +"close the browser." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:67 +msgid "Contact (Email, Phone, Forms)" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:68 +msgid "" +"Scope and purpose: If you contact us by e-mail, telephone or via a form, the " +"contact details you provide, such as your e-mail address, telephone number " +"and, if applicable, your name, will be stored for the purpose of processing " +"and responding to your request.\n" +" We would like to point out that data transmission (e.g. when " +"communicating by e-mail) may be subject to security vulnerabilities. Complete" +" protection of data against access by third parties is not possible." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:70 +msgid "" +"Recipient: If necessary for the response to your contact, personal data may " +"be forwarded to responsible parties within the operator. The respective " +"responsible employees of the operator use your personal data solely for " +"processing your inquiry. There is no transfer of data to third parties." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:71 +msgid "" +"Legal basis: The legal basis for the processing of this data is Art. 6 para. " +"1 lit. e GDPR in conjunction with Art. 4 LDSG respectively Art. 20 para. 1 " +"KITG in conjunction with § 12 para. 1 LHG or other relevant legal provisions." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:72 +msgid "" +"Storage duration: The personal data will be stored as long as it is necessary" +" to fulfill the aforementioned purpose, meaning the data will be deleted when" +" it can be assumed that further communication is no longer desired." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:74 +msgid "Registration process as a user" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:75 +msgid "" +"Scope and purpose: The operator collects and stores this data to ensure the " +"management of users and the processing of processes associated with their " +"roles. A matching with other data records does not take place. We reserve the" +" right to review this data retrospectively if we become aware of specific " +"indications of illegal use. As part of a registration process as a user, the " +"operator stores the following data provided by the user:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:77 +msgid "Name (last name, first name)" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:78 +msgid "Email address" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:79 +msgid "Login name (user ID)" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:80 +msgid "Password" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:81 +msgid "Affiliation (research institutions or project consortia)" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:84 +msgid "" +"Recipient: Name and login name are visible to members of the same " +"organization assigned to them based on their affiliation. There is no " +"transfer of data to third parties." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:85 +msgid "" +"Legal basis: The legal basis for processing of this data is Art. 6 par. 1 (b)" +" GDPR." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:86 +msgid "" +"Storage duration: The personal data will be stored as long as it is necessary" +" to achieve the purpose of its collection. They will be permanently removed " +"upon deletion of the user account." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:88 +msgid "Links to other websites" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:89 +msgid "If we link to websites outside of" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:89 +msgid ", the data protection notices and statements there apply." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:91 +msgid "Encrypted transmission (TLS encryption)" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:92 +msgid "" +"This site uses TLS encryption to protect the transmission of all content, " +"including the requests you send to us as the site operator. With TLS " +"encryption, the data you transmit to us cannot generally be read by third " +"parties. Please note, however, that when data is transmitted over the " +"Internet, it is never possible to guarantee complete protection against " +"access by third parties." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:94 +msgid "How do we process this data?" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:95 +msgid "" +"Your personal data is stored with us. Any use of personal data occurs only " +"for the purposes mentioned above and only to the extent necessary to achieve " +"these purposes. We employ technical and organizational security measures to " +"protect your personal data against accidental or unlawful destruction, loss, " +"or alteration, as well as against unauthorized disclosure or access. Our " +"security standards are always in line with the latest technological " +"developments." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:97 +msgid "Under what conditions can we pass your data on to third parties?" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:99 +msgid "" +"Without the user's explicit consent, the operator will not pass on personal " +"data to third parties." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:100 +msgid "" +"The exception applies insofar as the transmission to state authorities or " +"agencies is required by a mandatory national legal provision or if the " +"transfer is necessary in the event of attacks on the operator's network " +"infrastructure for legal or criminal prosecution." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:102 +msgid "Your rights" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:103 +msgid "As far as your personal data are concerned, you have the following rights:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:105 +msgid "" +"Right to revoke your consent with effect for the future, provided that " +"processing is based on a consent according to Art. 6, par. 1, sub-par. 1, a " +"GDPR (Art. 7, par. 3 GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:106 +msgid "" +"Right to confirmation whether data about you are processed and right to " +"information about the data processed and about data processing as well as " +"right to obtain copies of the data (Art. 15 GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:107 +msgid "" +"Right to rectification or completion of incorrect or incomplete data (Art. 16" +" GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:108 +msgid "Right to immediate erasure of your personal data (Art. 17 GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:109 +msgid "Right to restriction of processing (Art. 18 GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:110 +msgid "" +"Right to data portability in a structured, standard, and machine-readable " +"format, if processing is based on a consent according to Art. 6, par. 1, sub-" +"par. 1, a or Art. 9, par. 2, a or on an agreement according to Art. 6, par. " +"1, sub-par. 1, b (Art. 20 GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:111 +msgid "" +"Right to object to the future processing of your personal data, if the data " +"are processed accord-ing to Art. 6, par. 1, e or f GDPR (Art. 21 GDPR)." +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:114 +msgid "" +"In addition, you have the right to complain about the processing of your " +"personal data by the controller of this website with its super-visory " +"authority (Art. 77 GDPR). According to Art. 25, par. 1, LDSG, the su-" +"pervisory authority of the controller of this website according to Art. 51, " +"par. 1 GDPR is:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:121 +msgid "As of:" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:16 +msgid "Enable Dark Mode" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:21 +msgid "Banner Top" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:21 +msgid "Banner top" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:26 +msgid "Banner Bottom" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:26 +msgid "Banner bottom" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:31 +msgid "Attribution Logo" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:31 +msgid "Attribution logo" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:35 +msgid "Update Config" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:44 +msgid "CKAN config options" +msgstr "" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:51 +#, python-format +msgid "" +"

Site Title: This is the title of this CKAN instance It " +"appears in various places throughout CKAN.

Custom " +"Stylesheet: Define an alternative main CSS file.

Site" +" Tag Logo: This is the logo that appears in the header of all the " +"CKAN instance templates.

About: This text will appear" +" on this CKAN instances about page.

" +"

Intro Text: This text will appear on this CKAN instances " +"home page as a welcome to visitors.

" +"

Custom CSS: This is a block of CSS that appears in " +"<head> tag of every page. If you wish to customize the " +"templates more fully we recommend reading the documentation.

" +msgstr "" + +#: ckanext/matolabtheme/templates/user/login.html:6 +msgid "" +"Sign in with\n" +" SSO" +msgstr "" + diff --git a/ckanext/matolabtheme/i18n/de/LC_MESSAGES/ckanext-matolabtheme.mo b/ckanext/matolabtheme/i18n/de/LC_MESSAGES/ckanext-matolabtheme.mo new file mode 100644 index 0000000..44bae76 Binary files /dev/null and b/ckanext/matolabtheme/i18n/de/LC_MESSAGES/ckanext-matolabtheme.mo differ diff --git a/ckanext/matolabtheme/i18n/de/LC_MESSAGES/ckanext-matolabtheme.po b/ckanext/matolabtheme/i18n/de/LC_MESSAGES/ckanext-matolabtheme.po new file mode 100644 index 0000000..6c40332 --- /dev/null +++ b/ckanext/matolabtheme/i18n/de/LC_MESSAGES/ckanext-matolabtheme.po @@ -0,0 +1,760 @@ +# German translations for ckanext-matolabtheme. +# Copyright (C) 2025 ORGANIZATION +# This file is distributed under the same license as the +# ckanext-matolabtheme +# project. +# FIRST AUTHOR , 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: ckanext-matolabtheme 0.0.1\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2025-05-19 09:58+0000\n" +"PO-Revision-Date: 2025-02-10 09:30+0000\n" +"Last-Translator: FULL NAME \n" +"Language: de\n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.15.0\n" + +#: ckanext/matolabtheme/views.py:40 ckanext/matolabtheme/views.py:127 +msgid "Need to be system administrator to administer" +msgstr "Für die Verwaltung muss man Systemadministrator sein" + +#: ckanext/matolabtheme/templates/footer.html:9 +msgid "About {0}" +msgstr "Über {0}" + +#: ckanext/matolabtheme/templates/footer.html:15 +msgid "Data Privacy" +msgstr "Datenschutz" + +#: ckanext/matolabtheme/templates/footer.html:16 +msgid "CKAN API" +msgstr "CKAN API" + +#: ckanext/matolabtheme/templates/footer.html:17 +msgid "CKAN Association" +msgstr "CKAN-Vereinigung" + +#: ckanext/matolabtheme/templates/footer.html:28 +msgid "Powered by" +msgstr "Eingesetzte Software ist" + +#: ckanext/matolabtheme/templates/footer.html:33 +msgid "Provided by" +msgstr "Bereitgestellt von" + +#: ckanext/matolabtheme/templates/footer.html:41 +msgid "Contact Us" +msgstr "Kontakt" + +#: ckanext/matolabtheme/templates/footer.html:42 +msgid "Legal Notice" +msgstr "Impressum" + +#: ckanext/matolabtheme/templates/header.html:41 +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:36 +msgid "Search" +msgstr "Suche" + +#: ckanext/matolabtheme/templates/header.html:42 +msgid "Search datasets..." +msgstr "Datensätze suchen..." + +#: ckanext/matolabtheme/templates/header.html:43 +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:37 +msgid "Submit" +msgstr "Einreichen" + +#: ckanext/matolabtheme/templates/header.html:54 +#: ckanext/matolabtheme/templates/header.html:62 +#: ckanext/matolabtheme/templates/header.html:64 +msgid "View profile" +msgstr "Profil anzeigen" + +# | msgid "Update Config" +#: ckanext/matolabtheme/templates/admin/config.html:5 +msgid "Theme Config" +msgstr "Theme konfigurieren" + +#: ckanext/matolabtheme/templates/home/index.html:3 +msgid "Welcome" +msgstr "Willkommen" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:23 +msgid "Welcome to CKAN" +msgstr "Willkommen bei CKAN" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:25 +msgid "" +"This is a nice introductory paragraph about CKAN or the site in general. " +"We don't have any copy to go here yet but soon we will" +msgstr "" +"Dies ist ein schöner einführender Abs. über CKAN oder die Seite im " +"Allgemeinen. Wir haben noch keinen Text dafür, aber bald werden wir ihn " +"haben." + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:36 +msgid "Search our database..." +msgstr "Durchsuchen Sie unsere Datenbank..." + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:58 +msgid "Log in" +msgstr "Anmelden" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:71 +msgid "Datasets" +msgstr "Datensätze" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:80 +msgid "Resources" +msgstr "Ressourcen" + +#: ckanext/matolabtheme/templates/home/snippets/promoted.html:89 +msgid "Organizations" +msgstr "Organisationen" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:15 +msgid "http://example.com/my-image.jpg" +msgstr "http://beispiel.de/mein-bild.jpg" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:16 +msgid "Image URL" +msgstr "Bild-URL" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:17 +msgid "Image" +msgstr "Bild" + +#: ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html:45 +msgid "Clear Upload" +msgstr "Löschen" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:3 +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:10 +msgid "Data Protection" +msgstr "Datenschutz" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:16 +msgid "" +"Information on data protection in accordance with Art. 13 of the General " +"Data Protection Regulation (GDPR) on" +msgstr "" +"Informationen zum Datenschutz gemäß Art. 13 Datenschutz-Grundverordnung " +"(DS-GVO) auf" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:18 +msgid "" +"The following information provides you with an overview of the processing" +" of your personal data on " +msgstr "" +"Mit den nachfolgenden Informationen geben wir Ihnen einen Überblick über " +"die Verarbeitung Ihrer personenbezogenen Daten auf" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:18 +msgid "" +"and your rights under data protection law. According to Art. 4 No. 1 of " +"the EU General Data Protection Regulation (GDPR), personal data is any " +"information relating to an identified or identifiable natural person." +msgstr "" +"sowie über Ihre Rechte aus dem Datenschutzrecht. Personenbezogene Daten " +"sind nach Art. 4 Nr. 1 der EU-Datenschutz-Grundverordnung (DS-GVO) alle " +"Informationen, die sich auf eine identifizierte oder identifizierbare " +"natürliche Person beziehen." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:20 +msgid "Table of Contents" +msgstr "Inhaltsverzeichnis" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:23 +msgid "Controller and Data Protection Commissioner " +msgstr "Verantwortlicher und Datenschutzbeauftragter" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:25 +msgid "" +"According to the GDPR (Art. 4, No. 7) and other data protection " +"regulations, the controller is:" +msgstr "" +"Verantwortlicher für die Datenverarbeitung im Sinne der DS-GVO (Art. 4 " +"Nr. 7) sowie anderer datenschutzrechtlicher Bestimmungen ist:" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:29 +msgid "The controller is a public corporation represented by its President." +msgstr "" +"Der Verantwortliche ist eine Körperschaft des öffentlichen Rechts. Es " +"wird vertreten durch die/den jeweilige/n Präsident/in." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:31 +msgid "The Data Protection Commissioner can be contacted by email at:" +msgstr "Unsere Datenschutzbeauftragte erreichen Sie unter:" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:33 +msgid "" +"or by ordinary mail with Data Protection Commissioner being indicated on " +"the envelope." +msgstr "oder postalisch addessiert an \"Die Datenschutzbeauftragte.\"" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:35 +msgid "Accessing the website and server log files (visiting the portal)" +msgstr "Aufruf der Webseite und Server-Logfiles (Besuch des Portals)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:37 +msgid "The anonymized IP address" +msgstr "Die anonymisierte IP-Adresse" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:38 +msgid "The date and time of access" +msgstr "Das Datum und die Uhrzeit des Zugriffs" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:39 +msgid "The URL of the retrieved file" +msgstr "Die URL der abgerufenen Datei" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:40 +msgid "The amount of data transferred" +msgstr "Die übertragene Datenmenge" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:41 +msgid "The message indicating whether the retrieval was successful" +msgstr "Die Meldung, ob der Abruf erfolgreich war" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:42 +msgid "The information about the browser and operating system used" +msgstr "Die Informationen zum verwendeten Browser und Betriebssystem" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:43 +msgid "The URL of the website from which the access occurred" +msgstr "Die URL der Webseite, von der aus der Aufruf erfolgt ist" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:44 +msgid "The name of the internet service provider" +msgstr "Der Name des Internetzugangs-Providers" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:46 +msgid "" +"Scope and Purpose: When using the website for information purposes only, " +"i.e. when you do not register or transmit other information, we will only" +" collect the personal data that are transmitted by your browser to our " +"server according to the settings made by you. The data serves the " +"technical optimization of the website and to ensure the security of our " +"information technology systems. The IP address is necessary for the " +"operation or delivery of the website, is shortened in the log files, and " +"is no longer available as a whole after the request. A direct conclusion " +"about individual persons is not possible based on this data. A matching " +"with other data records does not take place. We reserve the right to " +"review this data retrospectively if we become aware of specific " +"indications of illegal use." +msgstr "" +"Umfang und Zweck: Bei der bloß informatorischen Nutzung der Webseite, " +"wenn Sie sich also nicht registrieren oder uns anderweitig Informationen " +"übermitteln, erheben wir nur die personenbezogenen Daten, die Ihr Browser" +" nach den von Ihnen vorgenommenen Einstellungen an unseren Server " +"übermittelt. Die Daten dienen der technischen Optimierung der Webseite " +"und zur Sicherstellung der Sicherheit unserer informationstechnischen " +"Systeme. Die IP-Adresse ist für den Betrieb bzw. der Auslieferung der " +"Webseite notwendig, wird verkürzt in die Logfiles geschrieben und ist " +"nach dem Request nicht mehr als Ganzes verfügbar. Ein direkter " +"Rückschluss auf einzelne Personen ist uns anhand dieser Daten nicht " +"möglich. Ein Abgleich mit anderen Datenbeständen findet nicht statt. Wir " +"behalten uns vor, diese Daten nachträglich zu prüfen, wenn uns konkrete " +"Anhaltspunkte für eine rechtswidrige Nutzung bekannt werden." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:47 +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:63 +msgid "Recipient: There is no transfer of data to third parties." +msgstr "Empfänger: Eine Weitergabe der Daten an Dritte findet nicht statt." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:48 +msgid "" +"Legal basis: The legal basis for processing is Art. 6 par. 1 (b), par. 3 " +"(b) GDPR in conjunction with Art. 4 State Data Protection Act " +"\"Landesdatenschutzgesetz\" (LSDG) respectively Art. 20 par. 1 KITG in " +"conjunction with Art. 12 par. 1 Higher Education Acts " +"\"Landeshochschulgesetz\" (LHG)." +msgstr "" +"Die Rechtsgrundlage für die Verarbeitung ist Art. 6 Abs. 1 lit. e, Abs. 3" +" lit. b DS-GVO in Verbindung mit Art. 4 Landesdatenschutzgesetz (LDSG) " +"bzw. Art. 20 Abs. 1 KITG i.V.m. § 12 Abs. 1 Landeshochschulgesetz (LHG)." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:49 +msgid "" +"Storage duration: The personal data will be stored as long as it is " +"necessary to achieve the purpose for which it was collected. The data " +"will be deleted after a maximum of seven days." +msgstr "" +"Speicherdauer: Die personenbezogenen Daten werden so lange gespeichert, " +"wie es für die Erreichung des Zweckes Ihrer Erhebung erforderlich ist. " +"Die Daten werden nach spätestens sieben Tagen gelöscht." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:51 +msgid "Example of processing:" +msgstr "Beispiel zur Verarbeitung:" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:53 +msgid "" +"The collection and processing of this data is carried out for the purpose" +" of providing the platform (establishing a connection), permanently " +"ensuring system security and stability, technical administration of the " +"network infrastructure, optimizing the internet offering, and general " +"statistical evaluation. A personal reference is not possible due to the " +"anonymization of the IP address." +msgstr "" +"Die Erhebung und Verarbeitung dieser Daten erfolgt zum Zweck der " +"Bereitstellung der Plattform (Verbindungsaufbau), zur dauerhaften " +"Gewährleistung der Systemsicherheit und -stabilität, zur technischen " +"Administration der Netzinfrastruktur, zur Optimierung des " +"Internetangebots sowie zur allgemeinen, statistischen Auswertung. Ein " +"Personenbezug ist auf Grund der Anonymisierung der IP-Adresse nicht " +"möglich." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:54 +msgid "" +"The operator collects and stores this data to ensure the management of " +"users and the processing of processes associated with their roles." +msgstr "" +"Der Betreiber erhebt und speichert diese Daten, um die Verwaltung der " +"Nutzer und die Abwicklung der mit ihren Rollen verbundenen Prozesse " +"sicherzustellen." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:55 +msgid "" +"If a user contacts the operator using the contact details provided in the" +" imprint, personal data will be processed." +msgstr "" +"Wendet sich ein Nutzer mittels der im Impressum angegebenen Kontaktdaten " +"an den Betreiber, erfolgt eine Verarbeitung personenbezogener Daten." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:58 +msgid "Cookies" +msgstr "Cookies" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:59 +msgid "" +"Scope and Purpose: In addition to the above data, cookies will be stored " +"on your computer when using our website. Cookies are small text files " +"stored by the browser you use. From these cookies, we (the server of our " +"website) obtain certain information. We use so-called session cookies " +"(transient cookies) that are technically required to make the website " +"work. The following data is stored and transmitted in the cookies we use:" +msgstr "" +"Umfang und Zweck: Zusätzlich zu den zuvor genannten Daten werden bei der " +"Nutzung unserer Webseite Cookies auf Ihrem Rechner gespeichert. Cookies " +"sind kleine Textdateien, die von dem von Ihnen verwendeten Browser bei " +"Ihnen gespeichert werden und durch welche uns (dem Server unserer " +"Webseite) bestimmte Informationen zufließen. Wir nutzen sogenannte " +"Session-Cookies (transiente Cookies), die technisch erforderlich sind, um" +" die Webseite funktionsfähig zu gestalten. In den von uns eingesetzten " +"Cookies werden dabei folgende Daten zu folgenden Zwecken gespeichert und " +"übermittelt:" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:61 +msgid "Anonymous user ID as UUID" +msgstr "Anonyme User-Id als UUID" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:64 +msgid "" +"Legal basis: The legal basis for the processing of personal data using " +"technically necessary cookies in accordance with § 25 (2) " +"Telecommunications Digital Services Data Protection Act " +"\"Telekommunikation-Digitale-Dienste-Datenschutz-Gesetz\" (TDDDG) is Art." +" 6(1)(f) of the GDPR. The legitimate interest of the operator in data " +"processing according to Art. 6(1)(f) of the GDPR is also present in the " +"aforementioned purposes." +msgstr "" +"Rechtsgrundlage: Die Rechtsgrundlage für die Verarbeitung " +"personenbezogener Daten unter Verwendung von technisch erforderlichen " +"Cookies i.S.d. § 25 Abs. 2 Telekommunikation-Digitale-Dienste-" +"Datenschutz-Gesetz (TDDDG) ist Art. 6 Abs. 1 lit. f DS-GVO. In o.g. " +"Zwecken liegt auch das berechtigte Interesse des Betreibers an der " +"Datenverarbeitung nach Art. 6 Abs. 1 lit. f DS-GVO." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:65 +msgid "" +"Storage duration: The session cookies will be deleted at the latest when " +"you close the browser." +msgstr "" +"Speicherdauer: Die Session-Cookies werden spätestens dann gelöscht, wenn " +"Sie den Browser schließen." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:67 +msgid "Contact (Email, Phone, Forms)" +msgstr "Kontaktaufnahme (E-Mail, Telefon, Formulare)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:68 +msgid "" +"Scope and purpose: If you contact us by e-mail, telephone or via a form, " +"the contact details you provide, such as your e-mail address, telephone " +"number and, if applicable, your name, will be stored for the purpose of " +"processing and responding to your request.\n" +" We would like to point out that data transmission (e.g. when " +"communicating by e-mail) may be subject to security vulnerabilities. " +"Complete protection of data against access by third parties is not " +"possible." +msgstr "" +"Umfang und Zweck: Bei Kontaktaufnahme per E-Mail, Telefon oder über ein " +"Formular werden die von Ihnen übermittelten Kontaktdaten wie E-Mail-" +"Adresse, Telefonnummer und ggf. Name zum Zwecke der Bearbeitung und " +"Beantwortung Ihrer Anfrage gespeichert. Wir weisen darauf hin, dass die " +"Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) " +"Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor " +"dem Zugriff durch Dritte ist nicht möglich." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:70 +msgid "" +"Recipient: If necessary for the response to your contact, personal data " +"may be forwarded to responsible parties within the operator. The " +"respective responsible employees of the operator use your personal data " +"solely for processing your inquiry. There is no transfer of data to third" +" parties." +msgstr "" +"Empfänger: Sofern es für die Beantwortung Ihrer Kontaktaufnahme " +"erforderlich ist, können personenbezogene Daten an zuständige Stellen " +"innerhalb des Betreibers weitergeleitet werden. Die jeweils zuständigen " +"Beschäftigten des Betreibers verwenden Ihre personenbezogenen Daten " +"ausschließlich zur Bearbeitung Ihrer Anfrage. Eine Weitergabe der Daten " +"an Dritte findet nicht statt." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:71 +msgid "" +"Legal basis: The legal basis for the processing of this data is Art. 6 " +"para. 1 lit. e GDPR in conjunction with Art. 4 LDSG respectively Art. 20 " +"para. 1 KITG in conjunction with § 12 para. 1 LHG or other relevant legal" +" provisions." +msgstr "" +"Rechtsgrundlage: Die Rechtsgrundlage für die Verarbeitung dieser Daten " +"ist Art. 6 Abs. 1 lit. e DS-GVO i.V.m. Art. 4 LDSG, respektive Art. 20 " +"par. 1 KITG i.V.m. § 12 Abs. 1 LHG bzw. weitere in Frage kommende " +"Rechtsvorschriften." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:72 +msgid "" +"Storage duration: The personal data will be stored as long as it is " +"necessary to fulfill the aforementioned purpose, meaning the data will be" +" deleted when it can be assumed that further communication is no longer " +"desired." +msgstr "" +"Speicherdauer: Die personenbezogenen Daten werden so lange gespeichert, " +"wie es für die Erfüllung des o.g. Zwecks erforderlich ist, d.h. die Daten" +" werden dann gelöscht, wenn davon auszugehen ist, dass ein Austausch " +"nicht mehr erwünscht ist." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:74 +msgid "Registration process as a user" +msgstr "Registrierungsvorgang als Nutzer/Nutzerin" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:75 +msgid "" +"Scope and purpose: The operator collects and stores this data to ensure " +"the management of users and the processing of processes associated with " +"their roles. A matching with other data records does not take place. We " +"reserve the right to review this data retrospectively if we become aware " +"of specific indications of illegal use. As part of a registration process" +" as a user, the operator stores the following data provided by the user:" +msgstr "" +"Umfang und Zweck: Der Betreiber erhebt und speichert diese Daten, um die " +"Verwaltung der Nutzer und die Abwicklung der mit ihren Rollen verbundenen" +" Prozesse sicherzustellen. Ein Abgleich mit anderen Datenbeständen findet" +" nicht statt. Wir behalten uns vor, diese Daten nachträglich zu prüfen, " +"wenn uns konkrete Anhaltspunkte für eine rechtswidrige Nutzung bekannt " +"werden." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:77 +msgid "Name (last name, first name)" +msgstr "Name (Nachname, Vorname)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:78 +msgid "Email address" +msgstr "E-Mail-Adresse" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:79 +msgid "Login name (user ID)" +msgstr "Login-Name (Nutzerkennung)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:80 +msgid "Password" +msgstr "Passwort" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:81 +msgid "Affiliation (research institutions or project consortia)" +msgstr "Affiliierung (Forschungsinstitutionen oder Projektkonsortien)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:84 +msgid "" +"Recipient: Name and login name are visible to members of the same " +"organization assigned to them based on their affiliation. There is no " +"transfer of data to third parties." +msgstr "" +"Empfänger: Name und Login-Name sind sichtbar für Mitglieder der gleichen " +"Organisation, die ihnen anhand ihrer Affiliierung zugewiesen werden. Eine" +" Weitergabe der Daten an Dritte findet nicht statt." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:85 +msgid "" +"Legal basis: The legal basis for processing of this data is Art. 6 par. 1" +" (b) GDPR." +msgstr "" +"Rechtsgrundlage: Die Rechtsgrundlage für die Verarbeitung dieser Daten " +"ist Art. 6 Abs. 1 lit. b DS-GVO." + + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:86 +msgid "" +"Storage duration: The personal data will be stored as long as it is " +"necessary to achieve the purpose of its collection. They will be " +"permanently removed upon deletion of the user account." +msgstr "" +"Speicherdauer: Die personenbezogenen Daten werden so lange gespeichert, " +"wie es für die Erreichung des Zweckes ihrer Erhebung erforderlich ist. " +"Sie werden bei Löschung des Benutzerkontos permanent entfernt." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:88 +msgid "Links to other websites" +msgstr "Links auf andere Webseiten" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:89 +msgid "If we link to websites outside of" +msgstr "Wenn wir auf Webseiten außerhalb von" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:89 +msgid ", the data protection notices and statements there apply." +msgstr ", gelten die dortigen Datenschutzhinweise und -erklärungen." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:91 +msgid "Encrypted transmission (TLS encryption)" +msgstr "Verschlüsselte Übertragung (TLS-Verschlüsselung)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:92 +msgid "" +"This site uses TLS encryption to protect the transmission of all content," +" including the requests you send to us as the site operator. With TLS " +"encryption, the data you transmit to us cannot generally be read by third" +" parties. Please note, however, that when data is transmitted over the " +"Internet, it is never possible to guarantee complete protection against " +"access by third parties." +msgstr "" +"Diese Seite nutzt zum Schutz der Übertragung aller Inhalte, wie auch der " +"Anfragen, die Sie an uns als Seitenbetreiber senden, eine TLS-" +"Verschlüsselung. Bei TLS-Verschlüsselung, können die Daten, die Sie an " +"uns übermitteln, in aller Regel nicht von Dritten mitgelesen werden. " +"Bitte beachten Sie aber, dass bei der Übertragung von Daten über das " +"Internet nie ein völlig lückenloser Schutz vor dem Zugriff Dritter " +"gewährleistet werden kann." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:94 +msgid "How do we process this data?" +msgstr "Wie verarbeiten wir diese Daten?" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:95 +msgid "" +"Your personal data is stored with us. Any use of personal data occurs " +"only for the purposes mentioned above and only to the extent necessary to" +" achieve these purposes. We employ technical and organizational security " +"measures to protect your personal data against accidental or unlawful " +"destruction, loss, or alteration, as well as against unauthorized " +"disclosure or access. Our security standards are always in line with the " +"latest technological developments." +msgstr "" +"Ihre personenbezogenen Daten werden bei uns gespeichert. Jegliche Nutzung" +" der personenbezogenen Daten erfolgt nur zu den vorstehend genannten " +"Zwecken und nur in dem zur Erreichung dieser Zwecke erforderlichen " +"Umfang. Wir setzen dabei technische und organisatorische " +"Sicherheitsmaßnahmen ein, um Ihre personenbezogenen Daten gegen " +"unbeabsichtigte oder unrechtmäßige Vernichtung, Verlust oder Veränderung " +"sowie gegen unbefugte Offenlegung oder unbefugten Zugang zu schützen. " +"Unsere Sicherheitsstandards entsprechen stets den aktuellsten " +"technologischen Entwicklungen." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:97 +msgid "Under what conditions can we pass your data on to third parties?" +msgstr "Unter welchen Voraussetzungen dürfen wir Ihre Daten an Dritte weitergeben?" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:99 +msgid "" +"Without the user's explicit consent, the operator will not pass on " +"personal data to third parties." +msgstr "" +"Ohne die ausdrückliche Zustimmung des Nutzers wird der Betreiber dessen " +"personenbezogene Daten nicht an Dritte weitergeben." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:100 +msgid "" +"The exception applies insofar as the transmission to state authorities or" +" agencies is required by a mandatory national legal provision or if the " +"transfer is necessary in the event of attacks on the operator's network " +"infrastructure for legal or criminal prosecution." +msgstr "" +"Etwas anderes gilt, soweit die Übermittlung an staatliche Einrichtungen " +"oder Behörden durch eine zwingende nationale Rechtsvorschrift geboten ist" +" oder wenn die Weitergabe im Fall von Angriffen auf die Netzinfrastruktur" +" des Betreibers zur Rechts- oder Strafverfolgung erforderlich ist." + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:102 +msgid "Your rights" +msgstr "Ihre Rechte" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:103 +msgid "As far as your personal data are concerned, you have the following rights:" +msgstr "" +"Hinsichtlich der Sie betreffenden personenbezogenen Daten haben Sie " +"gegenüber uns folgende Rechte:" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:105 +msgid "" +"Right to revoke your consent with effect for the future, provided that " +"processing is based on a consent according to Art. 6, par. 1, sub-par. 1," +" a GDPR (Art. 7, par. 3 GDPR)." +msgstr "" +"Recht auf Widerruf Ihrer Einwilligung mit Wirkung für die Zukunft, sofern" +" die Verarbeitung auf einer Einwilligung gemäß Art. 6 Abs. 1 UAbs. 1 lit." +" a DS-GVO beruht (Art. 7 Abs. 3 DS-GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:106 +msgid "" +"Right to confirmation whether data about you are processed and right to " +"information about the data processed and about data processing as well as" +" right to obtain copies of the data (Art. 15 GDPR)." +msgstr "" +"Recht auf Bestätigung, ob Sie betreffende Daten verarbeitet werden und " +"auf Auskunft über die verarbeiteten Daten, auf weitere Informationen über" +" die Datenverarbeitung sowie auf Kopien der Daten (Art. 15 DS-GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:107 +msgid "" +"Right to rectification or completion of incorrect or incomplete data " +"(Art. 16 GDPR)." +msgstr "" +"Recht auf Berichtigung oder Vervollständigung unrichtiger bzw. " +"unvollständiger Daten (Art. 16 DS-GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:108 +msgid "Right to immediate erasure of your personal data (Art. 17 GDPR)." +msgstr "" +"Recht auf unverzügliche Löschung der Sie betreffenden Daten (Art. 17 DS-" +"GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:109 +msgid "Right to restriction of processing (Art. 18 GDPR)." +msgstr "Recht auf Einschränkung der Verarbeitung (Art. 18 DS-GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:110 +msgid "" +"Right to data portability in a structured, standard, and machine-readable" +" format, if processing is based on a consent according to Art. 6, par. 1," +" sub-par. 1, a or Art. 9, par. 2, a or on an agreement according to Art. " +"6, par. 1, sub-par. 1, b (Art. 20 GDPR)." +msgstr "" +"Recht auf Erhalt der Daten in einem strukturierten, gängigen und " +"maschinenlesbaren Format, sofern die Verarbeitung auf einer Einwilligung " +"gemäß Art. 6 Abs. 1 UAbs. 1 lit. a oder Art. 9 Abs. 2 lit. a oder auf " +"einem Vertrag gemäß Art. 6 Abs. 1 UAbs 1 lit. b beruht (Art. 20 DS-GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:111 +msgid "" +"Right to object to the future processing of your personal data, if the " +"data are processed accord-ing to Art. 6, par. 1, e or f GDPR (Art. 21 " +"GDPR)." +msgstr "" +"Recht auf Widerspruch gegen die künftige Verarbeitung der Sie " +"betreffenden Daten, sofern die Daten nach Maßgabe von Art. 6 Abs. 1 lit. " +"e oder f DS-GVO verarbeitet werden (Art. 21 DS-GVO)" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:114 +msgid "" +"In addition, you have the right to complain about the processing of your " +"personal data by the controller of this website with its super-visory " +"authority (Art. 77 GDPR). According to Art. 25, par. 1, LDSG, the su-" +"pervisory authority of the controller of this website according to Art. " +"51, par. 1 GDPR is:" +msgstr "" +"Darüber hinaus haben Sie das Recht, sich über die Verarbeitung Ihrer " +"personenbezogenen Daten durch den für die Verarbeitung Verantwortlichen " +"dieser Website bei seiner Aufsichtsbehörde zu beschweren (Art. 77 DSGVO)." +" Gemäß Art. 25, Abs.. 1 LDSG ist die Aufsichtsbehörde des für die " +"Verarbeitung Verantwortlichen dieser Website gemäß Art. 51, Abs.. 1 GDPR " +"ist:" + +#: ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html:121 +msgid "As of:" +msgstr "Stand:" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:16 +msgid "Enable Dark Mode" +msgstr "Dark Mode einschalten" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:21 +msgid "Banner Top" +msgstr "Banner oben" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:21 +msgid "Banner top" +msgstr "Banner oben" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:26 +msgid "Banner Bottom" +msgstr "Banner unten" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:26 +msgid "Banner bottom" +msgstr "Banner unten" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:31 +msgid "Attribution Logo" +msgstr "Urheberrechtslogo" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:31 +msgid "Attribution logo" +msgstr "Urheberrechtslogo" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:35 +msgid "Update Config" +msgstr "Konfiguration aktualisieren" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:44 +msgid "CKAN config options" +msgstr "CKAN-Konfigurationsoptionen" + +#: ckanext/matolabtheme/templates/matolabtheme/theme_config.html:51 +#, python-format +msgid "" +"

Site Title: This is the title of this CKAN instance " +"It appears in various places throughout CKAN.

Custom " +"Stylesheet: Define an alternative main CSS file.

" +"

Site Tag Logo: This is the logo that appears in the " +"header of all the CKAN instance templates.

About:" +" This text will appear on this CKAN instances about page.

Intro " +"Text: This text will appear on this CKAN instances home page as a welcome to visitors.

" +"

Custom CSS: This is a block of CSS that appears in " +"<head> tag of every page. If you wish to customize the" +" templates more fully we recommend reading the documentation.

" +msgstr "" +"

Seitenüberschrift: Dies ist der Titel dieser CKAN-" +"Instanz. Er erscheint an verschiedenen Stellen in CKAN.

" +"

Benutzerdefiniertes Stylesheet: Definieren Sie eine " +"alternative Haupt-CSS-Datei.

Seiten-Tag-Logo: " +"Dies ist das Logo, das im Kopfbereich aller CKAN-Instanzvorlagen " +"erscheint.

Über: Dieser Text wird auf der Über-Seite dieser CKAN-Instanz angezeigt.

" +"

Einführungstext: Dieser Text wird auf der Startseite dieser CKAN-Instanz als " +"Willkommensgruß für Besucher angezeigt.

" +"

Benutzerdefiniertes CSS: Dies ist ein Block von CSS, " +"der im <head>-Tag jeder Seite erscheint. Wenn Sie die " +"Vorlagen umfassender anpassen möchten, empfehlen wir, die " +"Dokumentation zu lesen.

" + +#: ckanext/matolabtheme/templates/user/login.html:6 +msgid "" +"Sign in with\n" +" SSO" +msgstr "" +"Anmelden mit\n" +" SSO" + diff --git a/ckanext/matolabtheme/plugin.py b/ckanext/matolabtheme/plugin.py index ed51af0..a98323e 100644 --- a/ckanext/matolabtheme/plugin.py +++ b/ckanext/matolabtheme/plugin.py @@ -1,13 +1,19 @@ import ckan.plugins as plugins import ckan.plugins.toolkit as toolkit +from ckan.config.declaration import Declaration, Key +from ckan.lib.plugins import DefaultTranslation -from ckanext.matolabtheme import helpers, views +from ckanext.matolabtheme import action, auth, helpers, views -class MatolabthemePlugin(plugins.SingletonPlugin): +class MatolabthemePlugin(plugins.SingletonPlugin, DefaultTranslation): plugins.implements(plugins.IConfigurer) + plugins.implements(plugins.IConfigDeclaration) plugins.implements(plugins.ITemplateHelpers) + plugins.implements(plugins.IActions) plugins.implements(plugins.IBlueprint) + plugins.implements(plugins.IAuthFunctions) + plugins.implements(plugins.ITranslation) # IConfigurer @@ -16,12 +22,106 @@ def update_config(self, config_): toolkit.add_public_directory(config_, "public") toolkit.add_resource("assets", "matolabtheme") + # IConfigDeclaration + + def declare_config_options(self, declaration: Declaration, key: Key): + + declaration.annotate("matolabtheme") + group = key.ckanext.matolabtheme + declaration.declare(group.contact_url, "https://github.com/Mat-O-Lab") + declaration.declare( + group.legal_notice_url, "/legal_notice.html" + ) + declaration.declare( + group.contact_dp_commissioner_email_md, + "[datenprotection_commissioner@example.de](mailto:datenschutzbeauftragte@example.de?subject=dataprotection CKAN)", + ) + declaration.declare( + group.dsvgo_contact_md, + "legal person name, street number, Zip city, country", + ) + option = declaration.declare_bool(group.dark_mode, False) + option.set_validators("not_missing boolean_validator") + declaration.declare(group.banner_top, "/static/banner_top.png") + declaration.declare(group.banner_top_upload, "") + declaration.declare(group.clear_banner_top_upload, "") + declaration.declare(group.banner_bottom, "/static/banner_bottom.png") + declaration.declare(group.banner_bottom_upload, "") + declaration.declare(group.clear_banner_bottom_upload, "") + declaration.declare(group.attribution_logo, "/static/favicon.png") + declaration.declare(group.attribution_logo_upload, "") + declaration.declare(group.clear_attribution_logo_upload, "") + + def update_config_schema(self, schema): + + ignore_missing = toolkit.get_validator("ignore_missing") + # bool_val = toolkit.get_validator("boolean_validator") + unicode_safe = toolkit.get_validator("unicode_safe") + # dark_mode = toolkit.config.get("ckanext.matolabtheme.dark_mode") + schema.update( + { + # This is an existing CKAN core configuration option, we are just + # making it available to be editable at runtime + # "ckanext.matolabtheme.dark_mode": [ + # ignore_missing, bool_val + # ], + "ckanext.matolabtheme.banner_top": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.banner_bottom": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.banner_top_upload": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.banner_bottom_upload": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.clear_banner_top_upload": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.clear_banner_bottom_upload": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.attribution_logo": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.attribution_logo_upload": [ + ignore_missing, + unicode_safe, + ], + "ckanext.matolabtheme.clear_attribution_logo_upload": [ + ignore_missing, + unicode_safe, + ], + } + ) + return schema + # ITemplateHelpers def get_helpers(self): return helpers.get_helpers() + # IActions + + def get_actions(self): + actions = action.get_actions() + return actions + # IBlueprint def get_blueprint(self): return views.get_blueprint() + + # IAuthFunctions + + def get_auth_functions(self): + return auth.get_auth_functions() diff --git a/ckanext/matolabtheme/public/static/Logo.svg b/ckanext/matolabtheme/public/static/Logo.svg index 89a3a9e..784f243 100644 --- a/ckanext/matolabtheme/public/static/Logo.svg +++ b/ckanext/matolabtheme/public/static/Logo.svg @@ -1,122 +1,21 @@ - - - - -Zeichenfläche 1 Kopie 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ckanext/matolabtheme/public/static/banner.png b/ckanext/matolabtheme/public/static/banner.png deleted file mode 100644 index 01f72a4..0000000 Binary files a/ckanext/matolabtheme/public/static/banner.png and /dev/null differ diff --git a/ckanext/matolabtheme/public/static/banner_bottom.png b/ckanext/matolabtheme/public/static/banner_bottom.png new file mode 100644 index 0000000..23b0bb2 Binary files /dev/null and b/ckanext/matolabtheme/public/static/banner_bottom.png differ diff --git a/ckanext/matolabtheme/public/static/banner_top.png b/ckanext/matolabtheme/public/static/banner_top.png new file mode 100644 index 0000000..23b0bb2 Binary files /dev/null and b/ckanext/matolabtheme/public/static/banner_top.png differ diff --git a/ckanext/matolabtheme/public/static/favicon.png b/ckanext/matolabtheme/public/static/favicon.png index d0d2611..848f43e 100644 Binary files a/ckanext/matolabtheme/public/static/favicon.png and b/ckanext/matolabtheme/public/static/favicon.png differ diff --git a/ckanext/matolabtheme/templates/admin/config.html b/ckanext/matolabtheme/templates/admin/config.html new file mode 100644 index 0000000..6cb758f --- /dev/null +++ b/ckanext/matolabtheme/templates/admin/config.html @@ -0,0 +1,6 @@ +{% ckan_extends %} +{% block admin_form_help %} +{{super()}} +

Banner Config: You can change the banners for top and bottom here

+{% link_for _('Theme Config'), named_route='matolabtheme.theme_config', class_='btn btn-secondary', icon='upload' %} +{% endblock %} diff --git a/ckanext/matolabtheme/templates/base.html b/ckanext/matolabtheme/templates/base.html index 4c9ab22..015ed61 100644 --- a/ckanext/matolabtheme/templates/base.html +++ b/ckanext/matolabtheme/templates/base.html @@ -2,14 +2,14 @@ {% block meta %} {{ super() }} - - - {%- endblock -%} {%- block styles %} {{ super() }} {% asset 'matolabtheme/style' %} +{% if config.get('ckanext.matolabtheme.dark_mode') %} +{% asset 'matolabtheme/dark' %} +{% endif %} {% endblock %} {% block bodytag %} diff --git a/ckanext/matolabtheme/templates/footer.html b/ckanext/matolabtheme/templates/footer.html index ad06cbf..d92e414 100644 --- a/ckanext/matolabtheme/templates/footer.html +++ b/ckanext/matolabtheme/templates/footer.html @@ -1,8 +1,8 @@ - diff --git a/ckanext/matolabtheme/templates/header.html b/ckanext/matolabtheme/templates/header.html index 2f08118..39f46a1 100644 --- a/ckanext/matolabtheme/templates/header.html +++ b/ckanext/matolabtheme/templates/header.html @@ -7,13 +7,13 @@ {% block header_logo %} {% if g.site_logo %} + {% if g.site_logo %} {{ g.site_title }} - - {% else %} - + height="30"/> + {% else %} {{ g.site_title }} + height="30"/> + {% endif %} {% endif %} {% endblock %} @@ -31,15 +31,7 @@ {% block header_site_navigation_tabs %} {% set org_type = h.default_group_type('organization') %} {% set group_type = h.default_group_type('group') %} - - {{ h.custom_build_nav_main( - (dataset_type ~ '.search', h.humanize_entity_type('package', dataset_type, 'main nav') or _('Datasets'), - ["dataset", "resource"]), - (org_type ~ '.index', - h.humanize_entity_type('organization', org_type, 'main nav') or _('Organizations'), ['organization']), - (group_type ~ '.index', - h.humanize_entity_type('group', group_type, 'main nav') or _('Groups'), ['group']), - ('home.about', _('About')) ) }} + {{super()}} {% endblock %} {% endblock %} @@ -56,48 +48,39 @@ {% endif %} {% block header_account_container_content %} + {% if c.userobj %} + {% else %} + {% endif %} + {% endblock %} diff --git a/ckanext/matolabtheme/templates/home/index.html b/ckanext/matolabtheme/templates/home/index.html index 7aadc2d..80bc683 100644 --- a/ckanext/matolabtheme/templates/home/index.html +++ b/ckanext/matolabtheme/templates/home/index.html @@ -5,6 +5,10 @@ {% block maintag %}{% endblock %} {% block toolbar %}{% endblock %} +{%- block header %} +{% endblock -%} + + {% block content %} {% block promoted %} {% snippet 'home/snippets/promoted.html' %} @@ -21,10 +25,10 @@ {% with items = h.get_facet_items_dict("tags", search_facets, 30) %} {% if items or not hide_empty %} {% for item in items %} - {{item.name}} - + {{item.count}} unread messages @@ -37,4 +41,9 @@ {% endblock %} +{% endblock %} + +{%- block scripts %} +{{ super() }} +{% asset 'matolabtheme/index-js' %} {% endblock %} \ No newline at end of file diff --git a/ckanext/matolabtheme/templates/home/snippets/promoted.html b/ckanext/matolabtheme/templates/home/snippets/promoted.html index 27d9a71..8dfd24c 100644 --- a/ckanext/matolabtheme/templates/home/snippets/promoted.html +++ b/ckanext/matolabtheme/templates/home/snippets/promoted.html @@ -1,66 +1,93 @@ {% set intro = g.site_intro_text %} {% block home_image %} - -
+ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html b/ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html new file mode 100644 index 0000000..74ba71a --- /dev/null +++ b/ckanext/matolabtheme/templates/macros/form/image_upload_prefix.html @@ -0,0 +1,52 @@ +{% from 'macros/form/input.html' import input %} +{% from 'macros/form/checkbox.html' import checkbox %} + +{# +Builds a file upload for input + +Example +{% import 'macros/form.html' as form %} +{{ form.image_upload_prefix(data, errors, is_upload_enabled=true) }} + +#} +{% macro image_upload_prefix(data, errors, prefix='', field_url='image_url', field_upload='image_upload', field_clear='clear_upload', + is_url=false, is_upload=false, is_upload_enabled=false, placeholder=false, + url_label='', upload_label='', field_name='image_url') %} +{% set placeholder = placeholder if placeholder else _('http://example.com/my-image.jpg') %} +{% set url_label = url_label or _('Image URL') %} +{% set upload_label = upload_label or _('Image') %} +{% set previous_upload = data['previous_upload'] %} + +{% if field_url == 'url' and field_upload == 'upload' %} + {# backwards compatibility for old resource forms that still call the `forms.image_upload()` macro, eg ckanext-scheming #} + {% snippet 'package/snippets/resource_upload_field.html', + data=data, + errors=errors, + is_url=is_url, + is_upload=is_upload, + is_upload_enabled=is_upload_enabled, + url_label=url_label, + upload_label=upload_label, + placeholder=placeholder %} +{% else %} +
+ + +
+ {% if is_upload_enabled %} + or upload file: +
+ +
+ {% if is_upload %} +
+ + +
+ {% endif %} + {% endif %} +{% endif %} + +{% endmacro %} \ No newline at end of file diff --git a/ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html b/ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html new file mode 100644 index 0000000..5066861 --- /dev/null +++ b/ckanext/matolabtheme/templates/matolabtheme/dataprivacy.html @@ -0,0 +1,149 @@ +{% extends "page.html" %} + +{% block subtitle %}{{ _("Data Protection") }}{% endblock %} + +{% block breadcrumb_content_selected %} class="active" +{% endblock %} + +{% block breadcrumb_content %} +
  • + {% link_for _("Data Protection"), named_route=matolabtheme ~'.dataprotection'%}
  • +{% endblock %} + +{% block primary %} +
    +
    +

    {{ _("Information on data protection in accordance with Art. 13 of the General Data Protection Regulation (GDPR) on") }} {{host}}

    + +

    {{ _("The following information provides you with an overview of the processing of your personal data on ") }} {{host}} {{ _("and your rights under data protection law. According to Art. 4 No. 1 of the EU General Data Protection Regulation (GDPR), personal data is any information relating to an identified or identifiable natural person.") }}

    + +

    {{ _("Table of Contents") }}

    +
      + +

      {{ _("Controller and Data Protection Commissioner ") }}

      +
      + {{ _("According to the GDPR (Art. 4, No. 7) and other data protection regulations, the controller is:")}} +
      + {{ h.render_markdown(legal_person_address_md,allow_html=True) }} +
      + {{_("The controller is a public corporation represented by its President.")}} +
      +

      {{ _("The Data Protection Commissioner can be contacted by email at:")}} + {{ h.render_markdown(contact_dp_commissioner_email_md,allow_html=True) }} + {{_("or by ordinary mail with Data Protection Commissioner being indicated on the envelope.")}} +

      +

      {{ _("Accessing the website and server log files (visiting the portal)") }}

      +
        +
      • {{ _("The anonymized IP address") }}
      • +
      • {{ _("The date and time of access") }}
      • +
      • {{ _("The URL of the retrieved file") }}
      • +
      • {{ _("The amount of data transferred") }}
      • +
      • {{ _("The message indicating whether the retrieval was successful") }}
      • +
      • {{ _("The information about the browser and operating system used") }}
      • +
      • {{ _("The URL of the website from which the access occurred") }}
      • +
      • {{ _("The name of the internet service provider") }}
      • +
      +

      {{ _("Scope and Purpose: When using the website for information purposes only, i.e. when you do not register or transmit other information, we will only collect the personal data that are transmitted by your browser to our server according to the settings made by you. The data serves the technical optimization of the website and to ensure the security of our information technology systems. The IP address is necessary for the operation or delivery of the website, is shortened in the log files, and is no longer available as a whole after the request. A direct conclusion about individual persons is not possible based on this data. A matching with other data records does not take place. We reserve the right to review this data retrospectively if we become aware of specific indications of illegal use.")}}

      +

      {{ _("Recipient: There is no transfer of data to third parties.")}}

      +

      {{ _("Legal basis: The legal basis for processing is Art. 6 par. 1 (b), par. 3 (b) GDPR in conjunction with Art. 4 State Data Protection Act \"Landesdatenschutzgesetz\" (LSDG) respectively Art. 20 par. 1 KITG in conjunction with Art. 12 par. 1 Higher Education Acts \"Landeshochschulgesetz\" (LHG).")}}

      +

      {{ _("Storage duration: The personal data will be stored as long as it is necessary to achieve the purpose for which it was collected. The data will be deleted after a maximum of seven days.") }}

      + +

      {{ _("Example of processing:")}}

      +
        +
      • {{ _("The collection and processing of this data is carried out for the purpose of providing the platform (establishing a connection), permanently ensuring system security and stability, technical administration of the network infrastructure, optimizing the internet offering, and general statistical evaluation. A personal reference is not possible due to the anonymization of the IP address.") }}
      • +
      • {{ _("The operator collects and stores this data to ensure the management of users and the processing of processes associated with their roles.") }}
      • +
      • {{ _("If a user contacts the operator using the contact details provided in the imprint, personal data will be processed.") }}
      • +
      + +

      {{ _("Cookies") }}

      +

      {{ _("Scope and Purpose: In addition to the above data, cookies will be stored on your computer when using our website. Cookies are small text files stored by the browser you use. From these cookies, we (the server of our website) obtain certain information. We use so-called session cookies (transient cookies) that are technically required to make the website work. The following data is stored and transmitted in the cookies we use:")}}

      +
        +
      • {{ _("Anonymous user ID as UUID") }}
      • +
      +

      {{ _("Recipient: There is no transfer of data to third parties.")}}

      +

      {{ _("Legal basis: The legal basis for the processing of personal data using technically necessary cookies in accordance with § 25 (2) Telecommunications Digital Services Data Protection Act \"Telekommunikation-Digitale-Dienste-Datenschutz-Gesetz\" (TDDDG) is Art. 6(1)(f) of the GDPR. The legitimate interest of the operator in data processing according to Art. 6(1)(f) of the GDPR is also present in the aforementioned purposes.")}}

      +

      {{ _("Storage duration: The session cookies will be deleted at the latest when you close the browser.")}}

      + +

      {{ _("Contact (Email, Phone, Forms)") }}

      +

      {{ _("Scope and purpose: If you contact us by e-mail, telephone or via a form, the contact details you provide, such as your e-mail address, telephone number and, if applicable, your name, will be stored for the purpose of processing and responding to your request. + We would like to point out that data transmission (e.g. when communicating by e-mail) may be subject to security vulnerabilities. Complete protection of data against access by third parties is not possible.")}}

      +

      {{ _("Recipient: If necessary for the response to your contact, personal data may be forwarded to responsible parties within the operator. The respective responsible employees of the operator use your personal data solely for processing your inquiry. There is no transfer of data to third parties.")}}

      +

      {{ _("Legal basis: The legal basis for the processing of this data is Art. 6 para. 1 lit. e GDPR in conjunction with Art. 4 LDSG respectively Art. 20 para. 1 KITG in conjunction with § 12 para. 1 LHG or other relevant legal provisions.")}}

      +

      {{ _("Storage duration: The personal data will be stored as long as it is necessary to fulfill the aforementioned purpose, meaning the data will be deleted when it can be assumed that further communication is no longer desired.")}}

      + +

      {{ _("Registration process as a user") }}

      +

      {{ _("Scope and purpose: The operator collects and stores this data to ensure the management of users and the processing of processes associated with their roles. A matching with other data records does not take place. We reserve the right to review this data retrospectively if we become aware of specific indications of illegal use. As part of a registration process as a user, the operator stores the following data provided by the user:")}} +

        +
      • {{ _("Name (last name, first name)") }}
      • +
      • {{ _("Email address") }}
      • +
      • {{ _("Login name (user ID)") }}
      • +
      • {{ _("Password") }}
      • +
      • {{ _("Affiliation (research institutions or project consortia)") }}
      • +
      +

      +

      {{ _("Recipient: Name and login name are visible to members of the same organization assigned to them based on their affiliation. There is no transfer of data to third parties.")}}

      +

      {{ _("Legal basis: The legal basis for processing of this data is Art. 6 par. 1 (b) GDPR.")}}

      +

      {{ _("Storage duration: The personal data will be stored as long as it is necessary to achieve the purpose of its collection. They will be permanently removed upon deletion of the user account.") }}

      + + +

      {{ _("If we link to websites outside of") }} {{host}} {{ _(", the data protection notices and statements there apply.")}}

      + +

      {{ _("Encrypted transmission (TLS encryption)") }}

      +

      {{ _("This site uses TLS encryption to protect the transmission of all content, including the requests you send to us as the site operator. With TLS encryption, the data you transmit to us cannot generally be read by third parties. Please note, however, that when data is transmitted over the Internet, it is never possible to guarantee complete protection against access by third parties.")}}

      + +

      {{ _("How do we process this data?") }}

      +

      {{_("Your personal data is stored with us. Any use of personal data occurs only for the purposes mentioned above and only to the extent necessary to achieve these purposes. We employ technical and organizational security measures to protect your personal data against accidental or unlawful destruction, loss, or alteration, as well as against unauthorized disclosure or access. Our security standards are always in line with the latest technological developments.")}}

      + +

      {{ _("Under what conditions can we pass your data on to third parties?") }}

      +
        +
      • {{ _("Without the user's explicit consent, the operator will not pass on personal data to third parties.") }}
      • +
      • {{ _("The exception applies insofar as the transmission to state authorities or agencies is required by a mandatory national legal provision or if the transfer is necessary in the event of attacks on the operator's network infrastructure for legal or criminal prosecution.") }}
      • +
      +

      {{ _("Your rights") }}

      +

      {{ _("As far as your personal data are concerned, you have the following rights:") }}

      +
        +
      • {{ _("Right to revoke your consent with effect for the future, provided that processing is based on a consent according to Art. 6, par. 1, sub-par. 1, a GDPR (Art. 7, par. 3 GDPR).") }}
      • +
      • {{ _("Right to confirmation whether data about you are processed and right to information about the data processed and about data processing as well as right to obtain copies of the data (Art. 15 GDPR).") }}
      • +
      • {{ _("Right to rectification or completion of incorrect or incomplete data (Art. 16 GDPR).") }}
      • +
      • {{ _("Right to immediate erasure of your personal data (Art. 17 GDPR).") }}
      • +
      • {{ _("Right to restriction of processing (Art. 18 GDPR).") }}
      • +
      • {{ _("Right to data portability in a structured, standard, and machine-readable format, if processing is based on a consent according to Art. 6, par. 1, sub-par. 1, a or Art. 9, par. 2, a or on an agreement according to Art. 6, par. 1, sub-par. 1, b (Art. 20 GDPR).") }}
      • +
      • {{ _("Right to object to the future processing of your personal data, if the data are processed accord-ing to Art. 6, par. 1, e or f GDPR (Art. 21 GDPR).") }}
      • +
      +

      + {{ _("In addition, you have the right to complain about the processing of your personal data by the controller of this website with its super-visory authority (Art. 77 GDPR). According to Art. 25, par. 1, LDSG, the su-pervisory authority of the controller of this website according to Art. 51, par. 1 GDPR is:") }} +

      +
      + {{ h.render_markdown(dsvgo_contact_md,allow_html=True) }} +
      +
      +

      +

      {{ _("As of:") }} 02.2025

      +
      +
      + + +{% endblock %} + +{% block secondary %}{% endblock %} \ No newline at end of file diff --git a/ckanext/matolabtheme/templates/matolabtheme/dataprotection.html b/ckanext/matolabtheme/templates/matolabtheme/dataprotection.html deleted file mode 100644 index 2948a55..0000000 --- a/ckanext/matolabtheme/templates/matolabtheme/dataprotection.html +++ /dev/null @@ -1,302 +0,0 @@ -{% extends "page.html" %} - -{% block subtitle %}{{ _("Data Protection") }}{% endblock %} - -{% block breadcrumb_content_selected %} class="active" -{% endblock %} - -{% block breadcrumb_content %} - - {% link_for _("Data Protection"), named_route=matolabtheme ~'.dataprotection'%} - - {% endblock %} - - - {% block primary %} -
      -
      -

      {{ _("Datenschutzerklärung und - allgemeine Informationen zur Umsetzung der datenschutzrechtlichen Vorgaben der Artikel 12 bis 14 der - Datenschutz-Grundverordnung auf")}} {{host}}

      -
        -
      • -

        {{ _("Einleitung")}}

        -
      • -

        {{ _("Die Nutzung von")}} {{host}} {{_("ist so ausgestaltet, dass möglichst wenig personenbezogene - Daten - erhoben - und - verarbeitet - werden. - Im Folgenden informieren wir Sie darüber, welche personenbezogenen Daten wir erheben, bei wem wir - sie - erheben - und - was wir mit diesen Daten machen. Außerdem informieren wir Sie über Ihre Rechte in Datenschutzfragen - und an - wen - Sie - sich diesbezüglich wenden können.") }} -

        -
      • -

        {{ _("Wer sind wir?")}}

        -

        Verantwortlich für die Verarbeitung Ihrer personenbezogenen Daten ist die: - {{ h.render_markdown(legal_person_address_md) }} -

        -
      • -
      • {{_("Zu welchem Zweck verarbeiten wir Ihre personenbezogenen Daten?")}} -

        {{_("Daten werden verarbeitet für die folgenden Zwecke:")}} -

          -
        1. {{_("Besuch des Portals")}}
        2. -
        3. {{_("Im Rahmen eines Registrierungsvorgangs als Nutzer")}}
        4. -
        5. {{_("Nutzung des Kontaktformulars")}}
        6. -
        -

        -

        zur Verarbeitung: -

          -
        1. {{_("Die Erhebung und Verarbeitung dieser Daten erfolgt zum Zwecke der Bereitstellung der - Plattform - (Verbindungsaufbau), zur dauerhaften Gewährleistung der Systemsicherheit und -stabilität, - zur - technischen - Administration der Netzinfrastruktur, zur Optimierung des Internetangebots sowie zur - allgemeinen, - statistischen Auswertung. Ein Personenbezug ist auf Grund der Anonymisierung der IP-Adresse - nicht - möglich.")}}
        2. -
        3. {{_("Der Betreiber erhebt und speichert diese Daten, um die Verwaltung der Nutzer und die - Abwicklung - der - mit ihren Rollen verbundenen Prozesse sicherzustellen.")}}
        4. -
        5. {{_("Wendet sich ein Nutzer mittels der im Impressum angegebenen Kontaktdaten an den - Betreiber, - erfolgt - eine Verarbeitung personenbezogener Daten.")}}
        6. -
        -

        -
      • -
      • -

        {{_("Welche personenbezogenen Daten verarbeiten wir?")}}

        -

        Wir verarbeiten insbesondere folgende personenbezogene Daten: -

          -
        1. Beim Besuch des Portals speichern die Webserver des Betreibers temporär jeden Zugriff in - einer - Protokolldatei. Hierbei können folgende Daten ohne Zutun des Nutzers erfasst und bis zur - automatisierten - Löschung vom Betreiber gespeichert werden: - - die (durch Löschung des letzten Bytes anonymisierte) IP-Adresse des anfragenden Rechners, - das Datum und die Uhrzeit des Zugriffs, - der Name und die URL der abgerufenen Datei, - die übertragene Datenmenge, - die Meldung, ob der Abruf erfolgreich war, - die Informationen zum verwendeten Browser- und Betriebssystem, - die URL der Webseite, von der aus der Aufruf erfolgt ist, - der Name des Internet-Zugangs-Providers. - - - Die Erhebung und Verarbeitung dieser Daten erfolgt zum Zwecke der Bereitstellung der - Plattform - (Verbindungsaufbau), zur dauerhaften Gewährleistung der Systemsicherheit und -stabilität, - zur - technischen - Administration der Netzinfrastruktur, zur Optimierung des Internetangebots sowie zur - allgemeinen, - statistischen - Auswertung. Ein Personenbezug ist auf Grund der Anonymisierung der IP-Adresse nicht möglich. -
        2. - -
        3. Im Rahmen eines Registrierungsvorgangs als Nutzer speichert der Betreiber folgende vom - Nutzer - angegebene - Daten: - - Name (Nachname, Vorname), bei Personengesellschaften oder juristischen Personen die des - gesetzlichen - Vertreters - und die des Ansprechpartners, - E-Mail-Adresse, - Login-Name (Nutzerkennung), - Passwort. - - - Der Betreiber erhebt und speichert diese Daten, um die Verwaltung der Nutzer und die - Abwicklung der - mit ihren - Rollen verbundenen Prozesse sicherzustellen. -
        4. -
        5. Wendet sich ein Nutzer mittels der im Impressum angegebenen Kontaktdaten an den Betreiber, - erfolgt - eine - Verarbeitung personenbezogener Daten. In diesem Fall speichert der Betreiber die vom Nutzer - zur - Kontaktaufnahme - angegebenen personenbezogenen Daten, wie beispielsweise den Namen und die E-Mail-Adresse für - die - Verwendung zur - weiteren Korrespondenz mit diesem. -
        6. -
        -

        -
      • -

        {{_("Wie verarbeiten wir diese Daten?")}}

        -

        - Ihre personenbezogenen Daten werden bei uns gespeichert. - Jegliche Nutzung der personenbezogenen Daten erfolgt nur zu den vorstehend genannten Zwecken und - nur in - dem zur - Erreichung dieser Zwecke erforderlichen Umfang. Wir setzen dabei technische und organisatorische - Sicherheitsmaßnahmen ein, um Ihre personenbezogenen Daten gegen unbeabsichtigte oder - unrechtmäßige - Vernichtung, - Verlust oder Veränderung sowie gegen unbefugte Offenlegung oder unbefugten Zugang zu schützen. - Unsere - Sicherheitsstandards entsprechen stets den aktuellsten technologischen Entwicklungen. -

        -
      • -
      • -

        {{_("Welchen Voraussetzungen dürfen wir Ihre Daten an Dritte weitergeben?")}}

        -
          -
        1. Ohne die ausdrückliche Zustimmung des Nutzers wird der Betreiber dessen personenbezogene - Daten nicht - an Dritte weitergeben.
        2. -
        3. Etwas anderes gilt, soweit die Übermittlung an staatliche Einrichtungen oder Behörden durch - eine - zwingende - nationale Rechtsvorschrift geboten ist oder wenn die Weitergabe im Fall von Angriffen auf - die - Netzinfrastruktur - des Betreibers zur Rechts- oder Strafverfolgung erforderlich ist. -
        4. -
        5. der Einbindung von Social Media Plugins werden die datenschutzrechtlichen Maßgaben durch die - Implementierung der durch den Heise-Verlag entwickelten und bereitgestellten - Shariff-Bibliothek - berücksichtigt. - Die Kommunikation mit den sozialen Netzwerken übernimmt beim Shariff ein auf dem Server des - Webseitenbetreibers - abgelegtes Skript. Der Server steht zunächst als Vermittler zwischen dem Nutzer und - Facebook, Google - oder - Twitter. Erst wenn der Nutzer einen Share- oder Like-Button betätigt, entsteht eine direkte - Verbindung. - So - können die Dienste auch keine Daten über den Nutzer erfassen, bevor er aktiv wird. -
        6. -
        -
      • - -

        {{_("Cookies")}}

        -

        - Das Portal macht Gebrauch von Cookies, um Daten lokal zwischenzuspeichern. Eine Nutzung ist jedoch - auch - ohne - Cookies möglich. Mit dem Gebrauch von Cookies werden durch das Portal erweiterte Funktionen - bereitstellt. Die - Deaktivierung von Cookies kann dazu führen, dass der Nutzer nicht alle Funktionen des Portals nutzen - kann. Durch - die Speicherung von Cookies werden keine personenbezogenen Daten an den Betreiber übermittelt. -

        - -
      • -

        {{_("Wie lange speichern wir Ihre Daten?")}}

        -

        - Wir speichern Ihre im Rahmen der Registrierung erhobenen Daten, solange Sie diese Registrierung - nutzen. - Nach - Abmeldung der Registrierung werden diese Daten gelöscht. Jeder Nutzer kann die Löschung seines - Accounts - selber - durchführen. Wenn Sie mit dem Verfahren nicht einverstanden sind, nehmen Sie bitte Kontakt mit - uns auf, - so dass - wir die Löschung ihres Accounts durchführen. -

        -
      • - -
      • -

        {{_("Welche Rechte (Auskunftsrecht, Widerspruchsrecht usw.) haben Sie?")}}

        -

        - - Sie haben nach der Datenschutz-Grundverordnung verschiedene Rechte. Einzelheiten ergeben sich - insbesondere aus - Artikel 15 bis 18 und 21 der Datenschutz-Grundverordnung. -

        -
          -
        • Recht auf Auskunft -

          - Sie können Auskunft über Ihre von uns verarbeiteten personenbezogenen Daten verlangen. - In Ihrem - Auskunftsantrag - sollten Sie Ihr Anliegen präzisieren, um uns das Zusammenstellen der erforderlichen - Daten zu - erleichtern. Daher - sollten in dem Antrag möglichst Angaben zum konkreten Verwaltungsverfahren und zum - Verfahrensabschnitt - gemacht - werden.

          -
        • -
        • Recht auf Berichtigung -

          Sollten die Sie betreffenden Angaben nicht (mehr) zutreffend sein, können Sie eine - Berichtigung - verlangen. - Sollten Ihre Daten unvollständig sein, können Sie eine Vervollständigung verlangen.

          -
        • -
        • Recht auf Löschung

          - Sie können die Löschung Ihrer personenbezogenen Daten verlangen. Ihr Anspruch auf - Löschung hängt - u. a. - davon ab, - ob die Sie betreffenden Daten von uns zur Erfüllung unserer gesetzlichen Aufgaben noch - benötigt - werden.

          -
        • -
        • Recht auf Einschränkung der Verarbeitung

          - Sie haben das Recht, eine Einschränkung der Verarbeitung der Sie betreffenden Daten zu - verlangen. Die - Einschränkung steht einer Verarbeitung nicht entgegen, soweit an der Verarbeitung ein - wichtiges - öffentliches - Interesse besteht.

          -
        • -
        • Recht auf Widerspruch

          - Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, - jederzeit der - Verarbeitung - der Sie betreffenden Daten zu widersprechen. Allerdings können wir dem nicht nachkommen, - wenn an - der - Verarbeitung ein überwiegendes öffentliches Interesse besteht oder eine Rechtsvorschrift - uns zur - Verarbeitung - verpflichtet.

          -
        • -
        • Recht auf Beschwerde -

          - Wenn Sie der Auffassung sind, dass wir Ihrem Anliegen nicht oder nicht in vollem Umfang - nachgekommen - sind, - können Sie bei der zuständigen Datenschutzaufsichtsbehörde Beschwerde einlegen: -

          -

          - {{ h.render_markdown(dsvgo_contact_md) }} -

          -
        • -
        -

        Allgemeine Hinweise zu diesen Rechten

        -

        In einigen Fällen können oder dürfen wir Ihrem Anliegen nicht entsprechen. Sofern dies gesetzlich - zulässig ist, - teilen wir Ihnen in diesem Fall immer den Grund für die Verweigerung mit. - Wir werden Ihnen aber grundsätzlich innerhalb eines Monats nach Eingang Ihres Anliegens - antworten. - Sollten wir - länger als einen Monat für eine abschließende Klärung brauchen, erhalten Sie eine - Zwischennachricht. -

        -
      • -
      -

      {{_("Stand:")}} 06.2024

      -
      -
      - {% endblock %} - - {% block secondary %}{% endblock %} \ No newline at end of file diff --git a/ckanext/matolabtheme/templates/matolabtheme/theme_config.html b/ckanext/matolabtheme/templates/matolabtheme/theme_config.html new file mode 100644 index 0000000..4e3d31f --- /dev/null +++ b/ckanext/matolabtheme/templates/matolabtheme/theme_config.html @@ -0,0 +1,69 @@ +{% import 'macros/autoform.html' as autoform %} + +{% extends "admin/base.html" %} + +{% import 'macros/form.html' as form %} +{% import 'macros/form/image_upload_prefix.html' as iu %} + +{% block primary_content_inner %} + + {{ form.errors(error_summary) }} + +
      + {% block admin_form %} + {{ h.csrf_input() }} + + + + {% set field1_url = 'ckanext.matolabtheme.banner_top' %} + {% set is_upload = data[field1_url] and not data[field1_url].startswith('http') %} + {% set is_url = data[field1_url] and data[field1_url].startswith('http') %} + {{ iu.image_upload_prefix(data, errors, prefix='banner_top', is_upload_enabled=h.uploads_enabled(), field_name='ckanext.matolabtheme.banner_top_url', is_url=is_url, is_upload=is_upload, upload_label = _('Banner Top'), url_label=_('Banner top'), field_url=field1_url, field_upload='ckanext.matolabtheme.banner_top_upload', field_clear='ckanext.matolabtheme.clear_banner_top_upload' )}} + + {% set field2_url = 'ckanext.matolabtheme.banner_bottom' %} + {% set is_upload = data[field2_url] and not data[field2_url].startswith('http') %} + {% set is_url = data[field2_url] and data[field2_url].startswith('http') %} + {{ iu.image_upload_prefix(data, errors, prefix='banner_bottom', is_upload_enabled=h.uploads_enabled(), field_name='ckanext.matolabtheme.banner_bottom_url', is_url=is_url, is_upload=is_upload, upload_label = _('Banner Bottom'), url_label=_('Banner bottom'), field_url=field2_url, field_upload='ckanext.matolabtheme.banner_bottom_upload', field_clear='ckanext.matolabtheme.clear_banner_bottom_upload' )}} + + {% set field3_url = 'ckanext.matolabtheme.attribution_logo' %} + {% set is_upload = data[field3_url] and not data[field2_url].startswith('http') %} + {% set is_url = data[field3_url] and data[field3_url].startswith('http') %} + {{ iu.image_upload_prefix(data, errors, prefix='attribution_logo', is_upload_enabled=h.uploads_enabled(), field_name='ckanext.matolabtheme.attribution_logo_url', is_url=is_url, is_upload=is_upload, upload_label = _('Attribution Logo'), url_label=_('Attribution logo'), field_url=field3_url, field_upload='ckanext.matolabtheme.attribution_logo_upload', field_clear='ckanext.matolabtheme.clear_attribution_logo_upload' )}} + + {% endblock %} +
      + +
      +
      +{% endblock %} + +{% block secondary_content %} +
      +

      + + {{ _('CKAN config options') }} +

      +
      + {% block admin_form_help %} + {% set about_url = h.url_for('home.about') %} + {% set home_url = h.url_for('home.index') %} + {% set docs_url = "http://docs.ckan.org/en/{0}/theming".format(g.ckan_doc_version) %} + {% trans %} +

      Site Title: This is the title of this CKAN instance + It appears in various places throughout CKAN.

      +

      Custom Stylesheet: Define an alternative main CSS file.

      +

      Site Tag Logo: This is the logo that appears in the + header of all the CKAN instance templates.

      +

      About: This text will appear on this CKAN instances + about page.

      +

      Intro Text: This text will appear on this CKAN instances + home page as a welcome to visitors.

      +

      Custom CSS: This is a block of CSS that appears in + <head> tag of every page. If you wish to customize + the templates more fully we recommend + reading the documentation.

      + {% endtrans %} + {% endblock %} +
      +
      +{% endblock %} \ No newline at end of file diff --git a/ckanext/matolabtheme/templates/page.html b/ckanext/matolabtheme/templates/page.html index 264edfd..74ce352 100644 --- a/ckanext/matolabtheme/templates/page.html +++ b/ckanext/matolabtheme/templates/page.html @@ -1,138 +1,7 @@ -{% extends "base.html" %} +{% ckan_extends %} -{%- block page -%} - -{% block skip %} - -{% endblock %} - -{# -Override the header on a page by page basis by extending this block. If -making sitewide header changes it is preferable to override the header.html -file. -#} -{%- block header %} -{% include "header.html" %} -{% endblock -%} - -{# The content block allows you to replace the content of the page if needed #} -{%- block content %} {% block maintag %} -
      -
      - {% endblock %} -
      - {% block main_content %} - {% block flash %} -
      - {% block flash_inner %} - {% for category, message in h.get_flashed_messages(with_categories=true) %} -
      - {{ h.literal(message) }} -
      - {% endfor %} - {% endblock %} -
      - {% endblock %} - - {% block toolbar %} - - {% endblock %} - -
      - {# - The pre_primary block can be used to add content to before the - rendering of the main content columns of the page. - #} - {% block pre_primary %} - {% endblock %} - - {% block secondary %} - - {% endblock %} - - {% block primary %} -
      - {# - The primary_content block can be used to add content to the page. - This is the main block that is likely to be used within a template. - - Example: - - {% block primary_content %} -

      My page content

      -

      Some content for the page

      - {% endblock %} - #} - {% block primary_content %} -
      - {% block page_header %} - - {% endblock %} -
      - {% if self.page_primary_action() | trim %} -
      - {% block page_primary_action %}{% endblock %} -
      - {% endif %} - {% block primary_content_inner %} - {% endblock %} -
      -
      - {% endblock %} -
      - {% endblock %} -
      - {% endblock %} -
      -
      -{% endblock -%} - -{# -Override the footer on a page by page basis by extending this block. If -making sitewide header changes it is preferable to override the footer.html-u -file. -#} -{%- block footer %} -{% include "footer.html" %} -{% endblock -%} -{%- endblock -%} +
      +
      +{% endblock %} -{%- block scripts %} -{% asset 'base/main' %} -{% asset 'base/ckan' %} -{{ super() }} -{% endblock -%} \ No newline at end of file diff --git a/ckanext/matolabtheme/views.py b/ckanext/matolabtheme/views.py index 0eb16f0..34e43eb 100644 --- a/ckanext/matolabtheme/views.py +++ b/ckanext/matolabtheme/views.py @@ -1,35 +1,163 @@ -import os +import ckan.lib.base as base +import ckan.plugins.toolkit as toolkit from flask import Blueprint from flask.views import MethodView -import ckan.lib.base as base + +from typing import Any, Union + +import ckan.lib.navl.dictization_functions as dict_fns +import ckan.lib.uploader as uploader +import ckan.logic as logic +import ckan.logic.schema +import ckan.model as model +from ckan.common import _, config, current_user, request +from ckan.lib.helpers import helper_functions as h +from ckan.views.home import CACHE_PARAMETERS +from flask.wrappers import Response log = __import__("logging").getLogger(__name__) blueprint = Blueprint("matolabtheme", __name__) -HOST = os.environ.get("CKAN_HOST", "CKAN") -LEGAL_PERSON = os.environ.get( - "CKANINI__CKANEXT__MATOLABTHEME__LEGAL_PERSON_MD", "NAME LEGAL PERSON RESPONSIBLE" -) -DSVGO_CONTACT = os.environ.get( - "CKANINI__CKANEXT__MATOLABTHEME__DSVGO_CONTACT_MD", "CONTACT FOR DSVGO CONFLICTS" -) +if toolkit.check_ckan_version(min_version="2.10"): + from ckan.types import Context +else: + + class Context(dict): + def __init__(self, **kwargs): + super().__init__(**kwargs) -class DataProtectionView(MethodView): +class ThemeConfigView(MethodView): + def post(self) -> Union[str, Response]: + try: + context: Context = { + "user": current_user.name, + "auth_user_obj": current_user, + } + logic.check_access("sysadmin", context) + except logic.NotAuthorized: + base.abort(403, _("Need to be system administrator to administer")) + try: + req = request.form.copy() + req.update(request.files.to_dict()) + data_dict = logic.clean_dict( + dict_fns.unflatten( + logic.tuplize_dict( + logic.parse_params(req, ignore_keys=CACHE_PARAMETERS) + ) + ) + ) + # dark_mode=toolkit.config.get("ckanext.matolabtheme.dark_mode") + # Set dark_mode based on whether the checkbox was checked + data_dict["ckanext.matolabtheme.dark_mode"] = ( + "ckanext.matolabtheme.dark_mode" in req + ) + del data_dict["save"] + # data = logic.get_action("config_option_update")( + # {"user": current_user.name}, data_dict + # ) + # Handle banner uploads AFTER calling CKAN’s function + upload = uploader.get_uploader("admin") + for key in list(data_dict.keys()): + if key == "ckanext.matolabtheme.banner_top": + upload.update_data_dict( + data_dict, + "ckanext.matolabtheme.banner_top", + "ckanext.matolabtheme.banner_top_upload", + "ckanext.matolabtheme.clear_banner_top_upload", + ) + upload.upload(uploader.get_max_image_size()) + value = data_dict[key] + if upload.filepath: + static_url = upload.filepath.split("storage", 1)[-1] + value = h.url_for_static(static_url) + # Update CKAN's `config` object + model.set_system_info(key, value) + config[key] = value + elif key == "ckanext.matolabtheme.banner_bottom": + upload.update_data_dict( + data_dict, + "ckanext.matolabtheme.banner_bottom", + "ckanext.matolabtheme.banner_bottom_upload", + "ckanext.matolabtheme.clear_banner_bottom_upload", + ) + upload.upload(uploader.get_max_image_size()) + value = data_dict[key] + if upload.filepath: + static_url = upload.filepath.split("storage", 1)[-1] + value = h.url_for_static(static_url) + model.set_system_info(key, value) + config[key] = value + elif key == "ckanext.matolabtheme.attribution_logo": + upload.update_data_dict( + data_dict, + "ckanext.matolabtheme.attribution_logo", + "ckanext.matolabtheme.attribution_logo_upload", + "ckanext.matolabtheme.clear_attribution_logo_upload", + ) + upload.upload(uploader.get_max_image_size()) + value = data_dict[key] + if upload.filepath: + static_url = upload.filepath.split("storage", 1)[-1] + value = h.url_for_static(static_url) + model.set_system_info(key, value) + config[key] = value + elif key == "ckanext.matolabtheme.dark_mode": + value = data_dict[key] + model.set_system_info(key, value) + config[key] = value + + except logic.ValidationError as e: + data = request.form + errors = e.error_dict + error_summary = e.error_summary + vars = dict(data=data, errors=errors, error_summary=error_summary) + return base.render("matolabtheme/theme_config.html", extra_vars=vars) + return h.redirect_to("matolabtheme.theme_config") + + def get(self) -> str: + try: + context: Context = { + "user": current_user.name, + "auth_user_obj": current_user, + } + logic.check_access("sysadmin", context) + except logic.NotAuthorized: + base.abort(403, _("Need to be system administrator to administer")) + # dark_mode = toolkit.config.get("ckanext.matolabtheme.dark_mode") + schema = ckan.logic.schema.update_configuration_schema() + data = {} + for key in schema: + data[key] = config.get(key) + vars: dict[str, Any] = dict(data=data, errors={}) + return base.render("matolabtheme/theme_config.html", extra_vars=vars) + + +class DataPrivacyView(MethodView): def get(self): return base.render( - "matolabtheme/dataprotection.html", + "matolabtheme/dataprivacy.html", extra_vars={ - "host": HOST, - "legal_person_address_md": LEGAL_PERSON, - "dsvgo_contact_md": DSVGO_CONTACT, + "host": h.get_site_protocol_and_host()[-1], + "legal_person_address_md": toolkit.config.get( + "ckanext.matolabtheme.legal_person_md" + ), + "dsvgo_contact_md": toolkit.config.get( + "ckanext.matolabtheme.dsvgo_contact_md" + ), + "contact_dp_commissioner_email_md": toolkit.config.get( + "ckanext.matolabtheme.contact_dp_commissioner_email_md" + ), }, ) blueprint.add_url_rule( - "/dataprotection", view_func=DataProtectionView.as_view(str("dataprotection")) + "/dataprotection", view_func=DataPrivacyView.as_view(str("dataprotection")) +) +blueprint.add_url_rule( + "/admin/theme_config", view_func=ThemeConfigView.as_view(str("theme_config")) ) diff --git a/setup.py b/setup.py index 4d26df7..a878282 100644 --- a/setup.py +++ b/setup.py @@ -1,16 +1,49 @@ # -*- coding: utf-8 -*- -from setuptools import setup +from codecs import open # To use a consistent encoding +from os import path, environ + +from setuptools import find_packages, setup # Always prefer setuptools over distutils + +here = path.abspath(path.dirname(__file__)) + + +# Get the long description from the relevant file +with open(path.join(here, "README.md"), encoding="utf-8") as f: + long_description = f.read() + +with open(path.join(here,"requirements.txt")) as f: + requirements = f.read().splitlines() setup( + name="""ckanext-matolabtheme""", # If you are changing from the default layout of your extension, you may # have to change the message extractors, you can read more about babel # message extraction at # http://babel.pocoo.org/docs/messages/#extraction-method-mapping-and-configuration + version=environ.get('VERSION', '0.0.0'), + description="""CKAN theme of the Mat-O-Lab Project, changes landing Page and add alternative Data Privacy Act in English and German.""", + long_description=long_description, + long_description_content_type="text/markdown", + install_requires=requirements, + # The project's main homepage. + url="https://github.com/Mat-O-Lab/ckanext-matolabtheme", + # Author details + author="""Thomas Hanke""", + author_email="""thomas.hanke@iwm.fraunhofer.de""", + # Choose your license + license="AGPL", + packages=find_packages(), + include_package_data=True, message_extractors={ 'ckanext': [ ('**.py', 'python', None), ('**.js', 'javascript', None), ('**/templates/**.html', 'ckan', None), ], - } + }, + entry_points=""" + [ckan.plugins] + matolabtheme=ckanext.matolabtheme.plugin:MatolabthemePlugin + """, + )