From 20d5d358676496a9f48a33dbc0d1b6fcbb107ee5 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:18 +0000 Subject: [PATCH 01/18] ci: update workflow files standardise format, change name of tests file --- .github/workflows/bump.yml | 8 ++++---- .github/workflows/pypi-publish.yml | 7 ++++--- .github/workflows/sync.yml | 6 +++--- .github/workflows/{main.yml => tests.yml} | 8 ++++---- 4 files changed, 15 insertions(+), 14 deletions(-) rename .github/workflows/{main.yml => tests.yml} (77%) diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml index 8b17261..1bb1860 100644 --- a/.github/workflows/bump.yml +++ b/.github/workflows/bump.yml @@ -7,12 +7,12 @@ on: jobs: bump-version: - if: "!startsWith(github.event.head_commit.message, 'bump:')" + name: Bump version and create changelog runs-on: ubuntu-latest - name: "Bump version and create changelog" + if: "!startsWith(github.event.head_commit.message, 'bump:')" steps: - - name: Check out - uses: actions/checkout@v3 + - name: Checkout source code + uses: actions/checkout@v4 with: token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} fetch-depth: 0 diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 6866a49..6df8f70 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -10,15 +10,16 @@ permissions: jobs: deploy: + name: Deploy package to PyPI runs-on: ubuntu-latest steps: - - name: Check out - uses: actions/checkout@v3 + - name: Checkout source code + uses: actions/checkout@v4 with: token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@5 with: python-version: '3.x' - name: Install dependencies diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index bc66f38..4fec115 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -7,11 +7,11 @@ on: jobs: sync-branches: + name: Sync dev and patch branches to latest commit runs-on: ubuntu-latest - name: "Sync dev and patch branches to latest commit" steps: - - name: Check out - uses: actions/checkout@v3 + - name: Checkout source code + uses: actions/checkout@v4 with: token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} fetch-depth: 0 diff --git a/.github/workflows/main.yml b/.github/workflows/tests.yml similarity index 77% rename from .github/workflows/main.yml rename to .github/workflows/tests.yml index 38530ec..faa59fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/tests.yml @@ -3,18 +3,18 @@ name: Tests on: push: workflow_dispatch: + pull_request: + types: [opened, edited, reopened, synchronize] jobs: test: + name: Run tests runs-on: ubuntu-latest - steps: - name: Checkout source code - uses: actions/checkout@v3 - + uses: actions/checkout@v4 - name: Build images run: docker compose build - - name: Run tests env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} From ecab19e84d006a0806022104660e7f6bd452ec4f Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:18 +0000 Subject: [PATCH 02/18] ci: add pull request validation workflow new workflow to check commit format and code style against pre-commit config --- .github/workflows/pull-requests.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/pull-requests.yml diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml new file mode 100644 index 0000000..b9aa2bd --- /dev/null +++ b/.github/workflows/pull-requests.yml @@ -0,0 +1,27 @@ +name: Validate pull requests + +on: + pull_request: + types: [opened, edited, reopened, synchronize] + +jobs: + validate-commits: + name: Validate commit messages + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + - name: Check commit message format + uses: webiny/action-conventional-commits@v1.3.0 + with: + allowed-commit-types: 'feat,fix,refactor,perf,docs,style,test,build,ci,chore,new,patch,revert,ui' + pre-commit: + name: Run pre-commit checks + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 From c7287eadbb8cf14053026cdc56cb9cc7e2c59a8e Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:18 +0000 Subject: [PATCH 03/18] ci: update tool config update pre-commit repo versions and switch black to ruff --- .pre-commit-config.yaml | 19 +++++++++---------- pyproject.toml | 7 +++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2d3b017..728e347 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ exclude: /(vendor|dist)/ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v5.0.0 hooks: - id: check-merge-conflict - id: detect-private-key @@ -11,23 +11,22 @@ repos: exclude: ^tests/helpers/ - id: trailing-whitespace - repo: https://github.com/commitizen-tools/commitizen - rev: v2.37.0 + rev: v3.30.0 hooks: - id: commitizen additional_dependencies: ["cz-nhm"] - - repo: https://github.com/psf/black - rev: 22.10.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.1 hooks: - - id: black + - id: ruff + args: [ '--fix', '--select', 'I', '--select', 'F401' ] + - id: ruff-format - repo: https://github.com/PyCQA/docformatter - rev: v1.5.0 + rev: eb1df34 hooks: - id: docformatter - # these can't be pulled directly from the config atm, not sure why - args: ["-i", "--wrap-summaries=88", "--wrap-descriptions=88", - "--pre-summary-newline", "--make-summary-multi-line"] - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + rev: v4.0.0-alpha.8 hooks: - id: prettier types_or: [ javascript, vue, less, sass, scss, css ] diff --git a/pyproject.toml b/pyproject.toml index ec14643..91e6ec0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ dependencies = [ "unidecode", "nameparser", "prompt_toolkit", - "ckantools>=0.3.0" + "ckantools>=0.4.0" ] [project.optional-dependencies] @@ -73,9 +73,8 @@ version_files = [ "CITATION.cff:^version" ] -[tool.black] -line-length = 88 -skip_string_normalization = true +[tool.ruff.format] +quote-style = "single" [tool.pylint] max-line-length = 88 From 7720691c36bd52077aa6ba81d72b7f3175a08645 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 04/18] chore: update tool details in contributing guide --- CONTRIBUTING.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3372db8..e619a40 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ This extension and [several others](https://github.com/search?q=topic:ckan+org:N The current core team consists of: - Josh ([@jrdh](https://github.com/jrdh)) - Technical Lead -- Ginger ([@alycejenni](https://github.com/alycejenni)) - Software Engineer +- Ginger ([@alycejenni](https://github.com/alycejenni)) - Senior Software Engineer ## Questions @@ -81,7 +81,10 @@ The process is generally as follows: 3. Make your changes, and commit often; each commit should only contain one change. See below for specifics on how to word your commits. 4. Push your changes back to your fork. 5. [Open a pull request](https://docs.github.com/en/get-started/quickstart/contributing-to-projects#making-a-pull-request) in this repository, with the base branch set to **dev** and the compare branch set to your new branch. Provide a summary of your changes in the description. -6. If the automatic tests fail (these may take a while), please go back to your code and try to make them pass. You may have to update the tests themselves. You don't have to close the pull request while you're doing this; it'll update as you add further commits. +6. There are several automated checks that will run when you open the pull request. Try to make all of them pass. If you do not at least _attempt_ to make them pass, we will not merge your pull request. + 1. Tests. Update them so that they pass, if necessary. New tests are always welcome in any pull request, but if you have added a new feature that has decreased the coverage, new tests are required. + 2. Commit format validation. If you have not followed the conventional commits format for one or more of your commits, this will fail. + 3. Code format validation. If you have not formatted your code correctly (using Ruff, docformatter, and/or Prettier), this will fail. 7. Wait for feedback from one of the core maintainers. If it's been a week or so and we haven't responded, we may not have seen it. You can find other places to contact us in [SUPPORT.md](./.github/SUPPORT.md). ### Commits @@ -142,9 +145,9 @@ cz c ##### pre-commit -pre-commit is a tool that runs a variety of checks and modifications before a commit is made. You can check the [.pre-commit-config.yaml](./.pre-commit-config.yaml) file to see eaxtly what it's currently configured to do for this repository, but of particular note: +pre-commit is a tool that runs a variety of checks and modifications before a commit is made. You can check the [.pre-commit-config.yaml](./.pre-commit-config.yaml) file to see exactly what it's currently configured to do for this repository, but of particular note: -- reformats Python code with [Black](https://github.com/psf/black) +- reformats Python code with [Ruff](https://docs.astral.sh/ruff) - reformats JavaScript and stylesheets with [Prettier](https://prettier.io) - reformats docstrings with [docformatter](https://github.com/PyCQA/docformatter) - checks your commit message is correcly formatted @@ -161,15 +164,15 @@ pre-commit run Don't forget to stage any modifications that it makes! Once it runs without failing, then you can make your commit. -Something to remember is that empty docstrings will cause conflicts between Black and docformatter and the checks will fail repeatedly - so don't leave your docstrings empty! +Something to remember is that empty docstrings will cause conflicts between Ruff and docformatter and the checks will fail repeatedly - so don't leave your docstrings empty! ### Code changes and style guide -We generally use external style guides and tools to help us maintain standardised code. Black and Prettier will be run with pre-commit. +We generally use external style guides and tools to help us maintain standardised code. Ruff and Prettier will be run with pre-commit. #### Python -We follow the [Black style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html), with the notable exception that we use single quotes. +We use [Ruff](https://docs.astral.sh/ruff) to format our code, using defaults for everything except quote style (we use single quotes). We also _mostly_ use [CKAN's style](http://docs.ckan.org/en/latest/contributing/python.html), with the following exceptions: - prefer `f''` strings over `.format()` @@ -178,7 +181,7 @@ We also _mostly_ use [CKAN's style](http://docs.ckan.org/en/latest/contributing/ #### JavaScript and stylesheets (CSS, LESS, etc) -We use [Prettier](https://prettier.io) to format these files. +We use [Prettier](https://prettier.io) to format these files. As with Ruff, we use defaults for everything except quote style (we use single quotes). #### Accessibility From 37240f063c97149d11a620c0623aca4554f86425 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 05/18] chore: add pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..59ee47b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,4 @@ +- [ ] I have read the [section on commits and pull requests](https://github.com/NaturalHistoryMuseum/ckanext-attribution/blob/main/CONTRIBUTING.md#commits-and-pull-requests) in `CONTRIBUTING.md` + + +Describe your changes, tagging relevant issues where possible. From 18bfb3c1642ac574c0a054dbaaa58848b04e923f Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 06/18] build: remove version from docker compose file version specifier is deprecated --- docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 91ac279..89b6e2e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3" - services: ckan: build: From 9b6134d005f02c654aa3bbeea1b3c479e52443a7 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 07/18] ci: remove python version specifier should be unnecessary to specify python 3 now --- .github/workflows/pypi-publish.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 6df8f70..d3ac620 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -20,8 +20,6 @@ jobs: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@5 - with: - python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip From 1374436ef9b3090413280014512ba5e7481fdb8c Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 08/18] build: pin package versions and make cli dependencies optional not pinning sqlalchemy and requests because they're used elsewhere and pinning will probably cause some kind of horrible conflict; everything else has just been pinned to major versions, except spacy which needs to be <3.8 for python 3.8 compatibility (so is just pinned to the latest possible minor version) --- pyproject.toml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 91e6ec0..80aa2d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,15 +19,11 @@ classifiers = [ "Programming Language :: Python :: 3.8" ] dependencies = [ - "orcid", + "orcid~=1.0", "sqlalchemy", "requests", "fuzzywuzzy[speedup]", - "spacy[transformers]", - "unidecode", - "nameparser", - "prompt_toolkit", - "ckantools>=0.4.0" + "ckantools>=0.4.1" ] [project.optional-dependencies] @@ -37,6 +33,12 @@ test = [ "pytest-cov>=2.7.1", "coveralls" ] +cli = [ + "spacy[transformers]~=3.7.0", + "unidecode~=1.0", + "nameparser~=1.0", + "prompt_toolkit~=3.0" +] [project.urls] repository = "https://github.com/NaturalHistoryMuseum/ckanext-attribution" From 0bd13730b2863d5c38b826a08e46f9b2f9037892 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 09/18] fix: make additional cli packages optional --- .../commands/migration/api_search.py | 19 ++++++++++++++---- .../commands/migration/combiner.py | 20 ++++++++++++------- .../attribution/commands/migration/common.py | 14 ++++++++++++- .../attribution/commands/migration/parser.py | 18 ++++++++++++----- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/ckanext/attribution/commands/migration/api_search.py b/ckanext/attribution/commands/migration/api_search.py index 199a42a..c3db5c3 100644 --- a/ckanext/attribution/commands/migration/api_search.py +++ b/ckanext/attribution/commands/migration/api_search.py @@ -5,12 +5,19 @@ # Created by the Natural History Museum in London, UK import click + from ckanext.attribution.lib.orcid_api import OrcidApi from ckanext.attribution.lib.ror_api import RorApi -from prompt_toolkit import prompt -from nameparser import HumanName -from .common import multi_choice +try: + from nameparser import HumanName + from prompt_toolkit import prompt + + cli_installed = True +except ImportError: + cli_installed = False + +from .common import check_installed, multi_choice class APISearch(object): @@ -45,6 +52,8 @@ def _search_api(self, contrib, lookup, api_name, result_format): :param result_format: display format of each result, e.g. "{name} ({location})" :return: None if not found, dict for matching result if found/selected """ + check_installed(cli_installed) + aff = '; '.join(contrib.get('affiliations', [])) api = self.api[api_name] display_name = lookup.pop('display_name') @@ -53,7 +62,7 @@ def _search_api(self, contrib, lookup, api_name, result_format): f'Do any of these {api_name} results match "{display_name}" ({aff})?' ) click.echo(f'\nSearching {api_name} for "{display_name}"...') - results = api.search(**lookup).get(u'records', []) + results = api.search(**lookup).get('records', []) if len(results) > 0: i = multi_choice( question, @@ -94,6 +103,8 @@ def _search_api(self, contrib, lookup, api_name, result_format): return update_dict def _manual_edit(self, contrib, api_name): + check_installed(cli_installed) + if click.confirm('Enter ID manually?'): api = self.api[api_name] _id = click.prompt(f'{api_name} ID', show_default=False).strip() diff --git a/ckanext/attribution/commands/migration/combiner.py b/ckanext/attribution/commands/migration/combiner.py index 6917153..25c3f32 100644 --- a/ckanext/attribution/commands/migration/combiner.py +++ b/ckanext/attribution/commands/migration/combiner.py @@ -8,13 +8,16 @@ import re import click -from ckanext.attribution.lib.orcid_api import OrcidApi -from ckanext.attribution.lib.ror_api import RorApi from fuzzywuzzy import process -from prompt_toolkit import prompt -from unidecode import unidecode -from .common import multi_choice +try: + from unidecode import unidecode + + cli_installed = True +except ImportError: + cli_installed = False + +from .common import check_installed, multi_choice class Combiner(object): @@ -30,7 +33,8 @@ def separate(self, group): """ Ensure that the automated grouping is correct. - :param group: a list of ParsedSegment instances that are probably the same contributor + :param group: a list of ParsedSegment instances that are probably the same + contributor :return: a list of lists of ParsedSegments """ all_names = sorted( @@ -92,8 +96,10 @@ def combine_person_names(self, names): """ Uses a list of HumanNames to determine the longest possible name for a person. - :return: a dict of family_name, given_names (includes middle names), and key (i.e. a sort/display name) + :return: a dict of family_name, given_names (includes middle names), and key + (i.e. a sort/display name) """ + check_installed(cli_installed) def _filter_diacritics(name_list): filtered = [n for n in name_list if unidecode(n) != n] diff --git a/ckanext/attribution/commands/migration/common.py b/ckanext/attribution/commands/migration/common.py index 9c42e22..3b05ce3 100644 --- a/ckanext/attribution/commands/migration/common.py +++ b/ckanext/attribution/commands/migration/common.py @@ -25,7 +25,7 @@ def multi_choice(question, options, default=0): click.echo('') return answer - 1 except: - click.echo('That wasn\'t an option.', err=True) + click.echo("That wasn't an option.", err=True) return multi_choice(question, options, default) @@ -40,3 +40,15 @@ def multi_choice(question, options, default=0): initialism=re.compile(r'^[A-Z.]+$'), abbr=re.compile(r'([A-Z]|(?<=[^A-Za-z])[a-z])'), ) + + +def check_installed(is_cli_installed): + """ + Returns an error message if additional CLI packages are not installed. + + :param is_cli_installed: True if additional packages are installed + """ + if not is_cli_installed: + raise click.Exception( + 'Install additional requirements with: pip install ckanext-attribution[cli]' + ) diff --git a/ckanext/attribution/commands/migration/parser.py b/ckanext/attribution/commands/migration/parser.py index 0bf8756..c7f1b1f 100644 --- a/ckanext/attribution/commands/migration/parser.py +++ b/ckanext/attribution/commands/migration/parser.py @@ -9,11 +9,17 @@ from textwrap import shorten import click -import spacy -from nameparser import HumanName -from prompt_toolkit import prompt -from .common import rgx, multi_choice +try: + import spacy + from nameparser import HumanName + from prompt_toolkit import prompt + + cli_installed = True +except ImportError: + cli_installed = False + +from .common import check_installed, multi_choice, rgx @dataclass @@ -30,6 +36,8 @@ class Parser(object): """ def __init__(self): + check_installed(cli_installed) + self.contributors = {'person': {}, 'org': {}, 'other': {}} self.affiliations = {} spacy_model = 'en_core_web_trf' @@ -111,7 +119,7 @@ def validate(self, txt): return [] pc_proper_nouns = pos.get('PROPN', 0) / len(tokens) if pc_proper_nouns < 0.5: - click.echo('\nThis text doesn\'t look right:') + click.echo("\nThis text doesn't look right:") click.echo(txt) return not click.confirm('Skip it?') return True From b95642809f8c98e7fefcfd3c34fbc1bb6492b437 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:19 +0000 Subject: [PATCH 10/18] docs: add notes about optional CLI packages --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 90dacda..d7ff7b9 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ Path variables used below: ```shell pip install ckanext-attribution +# to use the CLI as well: +pip install ckanext-attribution[cli] ``` ## Installing from source @@ -112,6 +114,8 @@ pip install ckanext-attribution 3. Install via pip: ```shell pip install $INSTALL_FOLDER/src/ckanext-attribution + # to use the cli as well: + pip install $INSTALL_FOLDER/src/ckanext-attribution[cli] ``` ### Installing in editable mode @@ -352,6 +356,8 @@ toolkit.get_action('agent_external_read')({}, data_dict) ## Commands +**NB**: you will have to install the optional `[cli]` packages to use several of these commands. + ### `initdb` ```shell ckan -c $CONFIG_FILE attribution initdb From 3a9d381a0d1e2ccf81e070d6635cdc8e2a5f2e6f Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:20 +0000 Subject: [PATCH 11/18] ci: only apply auto-fixes in pre-commit F401 returns linting errors as well as auto-fixes, so this disables the errors and just applies the fixes --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 728e347..cd0f8b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: rev: v0.7.1 hooks: - id: ruff - args: [ '--fix', '--select', 'I', '--select', 'F401' ] + args: [ '--fix', '--select', 'I', '--select', 'F401', '--fix-only' ] - id: ruff-format - repo: https://github.com/PyCQA/docformatter rev: eb1df34 From 1dd01ddd1b1c1e9d8b376f5d3fb6eff7f89f6f8e Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:03:20 +0000 Subject: [PATCH 12/18] style: automatic reformat auto reformat with ruff/docformatter/prettier after config changes --- ckanext/attribution/commands/cli.py | 13 +-- .../commands/migration/__init__.py | 6 +- ckanext/attribution/lib/helpers.py | 10 +- ckanext/attribution/lib/orcid_api.py | 30 +----- ckanext/attribution/lib/ror_api.py | 15 +-- ckanext/attribution/logic/actions/create.py | 9 +- ckanext/attribution/logic/actions/delete.py | 3 +- ckanext/attribution/logic/actions/extra.py | 10 +- ckanext/attribution/logic/actions/helpers.py | 6 +- .../attribution/logic/actions/meta/help.py | 96 +++++++++---------- .../attribution/logic/actions/meta/schema.py | 3 +- ckanext/attribution/logic/actions/show.py | 10 +- ckanext/attribution/logic/actions/update.py | 11 ++- ckanext/attribution/logic/auth/delete.py | 3 +- ckanext/attribution/logic/auth/show.py | 1 - ckanext/attribution/logic/auth/update.py | 3 +- .../attribution/model/agent_affiliation.py | 6 +- .../model/agent_contribution_activity.py | 6 +- .../model/contribution_activity.py | 5 +- ckanext/attribution/model/crud/__init__.py | 2 +- ckanext/attribution/model/crud/_base.py | 22 +---- ckanext/attribution/model/crud/agent.py | 22 +++-- .../model/crud/agent_affiliation.py | 7 +- .../model/crud/agent_contribution_activity.py | 4 - .../model/crud/contribution_activity.py | 4 - ckanext/attribution/model/crud/package.py | 7 +- .../crud/package_contribution_activity.py | 8 +- .../model/package_contribution_activity.py | 6 +- ckanext/attribution/model/relationships.py | 3 +- ckanext/attribution/plugin.py | 13 +-- ckanext/attribution/routes/user.py | 1 + .../src/components/fields/Autocomplete.vue | 8 +- .../src/components/fields/ValidatedField.vue | 8 +- docs/_scripts/gen_api_pages.py | 1 - tests/test_helpers.py | 3 +- 35 files changed, 144 insertions(+), 221 deletions(-) diff --git a/ckanext/attribution/commands/cli.py b/ckanext/attribution/commands/cli.py index b3cb231..d8b286c 100644 --- a/ckanext/attribution/commands/cli.py +++ b/ckanext/attribution/commands/cli.py @@ -8,6 +8,9 @@ from ckan.model import Session from ckan.model.package_extra import PackageExtra from ckan.plugins import toolkit +from fuzzywuzzy import fuzz, process +from sqlalchemy import and_, or_ + from ckanext.attribution.commands import migration from ckanext.attribution.logic.actions.helpers import get_author_string from ckanext.attribution.model import ( @@ -19,14 +22,12 @@ relationships, ) from ckanext.attribution.model.crud import ( - AgentQuery, - PackageQuery, - PackageContributionActivityQuery, AgentAffiliationQuery, AgentContributionActivityQuery, + AgentQuery, + PackageContributionActivityQuery, + PackageQuery, ) -from fuzzywuzzy import process, fuzz -from sqlalchemy import and_, or_ def get_commands(): @@ -235,7 +236,7 @@ def merge_agents(q, match_threshold): @click.option( '--limit', help='Process n packages at a time (best for testing/debugging).' ) -@click.option('--dry-run', help='Don\'t save anything to the database.', is_flag=True) +@click.option('--dry-run', help="Don't save anything to the database.", is_flag=True) @click.option( '--search-api/--no-search-api', help='Search external APIs (e.g. ORCID) for details.', diff --git a/ckanext/attribution/commands/migration/__init__.py b/ckanext/attribution/commands/migration/__init__.py index 2d5b1db..19dfe6e 100644 --- a/ckanext/attribution/commands/migration/__init__.py +++ b/ckanext/attribution/commands/migration/__init__.py @@ -1,4 +1,4 @@ -from .parser import Parser -from .common import multi_choice, rgx -from .combiner import Combiner from .api_search import APISearch +from .combiner import Combiner +from .common import multi_choice, rgx +from .parser import Parser diff --git a/ckanext/attribution/lib/helpers.py b/ckanext/attribution/lib/helpers.py index 1d3cd20..93eba95 100644 --- a/ckanext/attribution/lib/helpers.py +++ b/ckanext/attribution/lib/helpers.py @@ -7,8 +7,9 @@ import itertools import re -from ckan.plugins import toolkit, plugin_loaded -from ckanext.attribution.model.crud import PackageQuery, AgentQuery +from ckan.plugins import plugin_loaded, toolkit + +from ckanext.attribution.model.crud import AgentQuery, PackageQuery def can_edit(): @@ -29,12 +30,13 @@ def split_caps(string_input): def get_contributions(pkg_id): - ''' + """ Template access for the :func:`~ckanext.attribution.model.crud.PackageQuery.get_contributions` query method. + :param pkg_id: :return: - ''' + """ return PackageQuery.get_contributions(pkg_id) diff --git a/ckanext/attribution/lib/orcid_api.py b/ckanext/attribution/lib/orcid_api.py index 8728cbe..7ba76c9 100644 --- a/ckanext/attribution/lib/orcid_api.py +++ b/ckanext/attribution/lib/orcid_api.py @@ -11,10 +11,6 @@ class OrcidApi(object): - """ - - """ - def __init__(self): self.key = toolkit.config.get('ckanext.attribution.orcid_key') self.secret = toolkit.config.get('ckanext.attribution.orcid_secret') @@ -22,18 +18,12 @@ def __init__(self): @cached_property def conn(self): - """ - - """ if self.key is None or self.secret is None: raise Exception(toolkit._('ORCID API credentials not supplied.')) return orcid.PublicAPI(self.key, self.secret, sandbox=self._debug) @cached_property def read_token(self): - """ - - """ if self.key is None or self.secret is None: raise Exception(toolkit._('ORCID API credentials not supplied.')) url = ( @@ -57,12 +47,6 @@ def read_token(self): return None def search(self, orcid_q=None, q=None, family_name=None, given_names=None): - ''' - - :param orcid_q: (Default value = None) - :param q: (Default value = None) - - ''' query = [] if orcid_q is not None and orcid_q != '': query.append('orcid:' + orcid_q) @@ -77,7 +61,7 @@ def search(self, orcid_q=None, q=None, family_name=None, given_names=None): records = [] loaded_ids = [] for r in search_response.get('result', []): - _id = r.get(u'orcid-identifier', {}).get(u'path', None) + _id = r.get('orcid-identifier', {}).get('path', None) if _id is not None and _id not in loaded_ids: try: orcid_record = self.as_agent_record(self.read(_id)) @@ -90,22 +74,10 @@ def search(self, orcid_q=None, q=None, family_name=None, given_names=None): return result def read(self, orcid_id): - ''' - - - :param orcid_id: - - ''' record = self.conn.read_record_public(orcid_id, 'record', self.read_token) return record def as_agent_record(self, orcid_record): - ''' - - - :param orcid_record: - - ''' names = orcid_record.get('person', {}).get('name', {}) return { 'family_name': names.get('family-name', {}).get('value', ''), diff --git a/ckanext/attribution/lib/ror_api.py b/ckanext/attribution/lib/ror_api.py index c3db6db..37375a7 100644 --- a/ckanext/attribution/lib/ror_api.py +++ b/ckanext/attribution/lib/ror_api.py @@ -4,20 +4,15 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK -import requests import json +import requests + class RorApi(object): url = 'https://api.ror.org' def read(self, ror_id): - ''' - - - :param ror_id: - - ''' response = requests.get('{0}/organizations/{1}'.format(self.url, ror_id)) if not response.ok: return None @@ -48,12 +43,6 @@ def search(self, q): } def as_agent_record(self, ror_record): - ''' - - - :param ror_record: - - ''' if ror_record is None: return {} address = ror_record.get('addresses') diff --git a/ckanext/attribution/logic/actions/create.py b/ckanext/attribution/logic/actions/create.py index 514a7d4..728d58f 100644 --- a/ckanext/attribution/logic/actions/create.py +++ b/ckanext/attribution/logic/actions/create.py @@ -5,19 +5,20 @@ # Created by the Natural History Museum in London, UK from ckan.plugins import toolkit +from ckantools.decorators import action, basic_action + from ckanext.attribution.logic.actions.helpers import ( - parse_contributors, get_author_string, + parse_contributors, ) +from ckanext.attribution.logic.actions.meta import help, schema from ckanext.attribution.model.crud import ( + AgentAffiliationQuery, AgentContributionActivityQuery, AgentQuery, ContributionActivityQuery, PackageContributionActivityQuery, - AgentAffiliationQuery, ) -from ckantools.decorators import action, basic_action -from ckanext.attribution.logic.actions.meta import help, schema @action(schema.agent_affiliation_create, help.agent_affiliation_create) diff --git a/ckanext/attribution/logic/actions/delete.py b/ckanext/attribution/logic/actions/delete.py index 6f7e058..1ac6c1a 100644 --- a/ckanext/attribution/logic/actions/delete.py +++ b/ckanext/attribution/logic/actions/delete.py @@ -4,6 +4,8 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK +from ckantools.decorators import action + from ckanext.attribution.logic.actions.meta import help, schema from ckanext.attribution.model.crud import ( AgentAffiliationQuery, @@ -12,7 +14,6 @@ ContributionActivityQuery, PackageContributionActivityQuery, ) -from ckantools.decorators import action @action(schema.agent_affiliation_delete, help.agent_affiliation_delete) diff --git a/ckanext/attribution/logic/actions/extra.py b/ckanext/attribution/logic/actions/extra.py index b179854..83cecd3 100644 --- a/ckanext/attribution/logic/actions/extra.py +++ b/ckanext/attribution/logic/actions/extra.py @@ -3,14 +3,16 @@ # # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK + import re from ckan.plugins import toolkit +from ckantools.decorators import action + from ckanext.attribution.lib.orcid_api import OrcidApi from ckanext.attribution.lib.ror_api import RorApi +from ckanext.attribution.logic.actions.meta import help, schema from ckanext.attribution.model.crud import AgentQuery -from ckantools.decorators import action -from ckanext.attribution.logic.actions.meta import schema, help @action( @@ -109,7 +111,7 @@ def agent_external_search(q, sources): orcid_remaining = 0 orcidapi = OrcidApi() orcid_search = orcidapi.search(q=q) - n = orcid_search.get(u'total', 0) + n = orcid_search.get('total', 0) orcid_records = orcid_search.get('records') orcid_records = [ r @@ -125,7 +127,7 @@ def agent_external_search(q, sources): ror_remaining = 0 rorapi = RorApi() ror_search = rorapi.search(q=q) - n = ror_search.get(u'total', 0) + n = ror_search.get('total', 0) ror_records = ror_search.get('records') ror_records = [ r diff --git a/ckanext/attribution/logic/actions/helpers.py b/ckanext/attribution/logic/actions/helpers.py index c8c1039..c72a93f 100644 --- a/ckanext/attribution/logic/actions/helpers.py +++ b/ckanext/attribution/logic/actions/helpers.py @@ -2,13 +2,13 @@ import json from ckan.plugins import toolkit + from ckanext.attribution.model.crud import ( - AgentQuery, + AgentAffiliationQuery, AgentContributionActivityQuery, + AgentQuery, ContributionActivityQuery, - AgentAffiliationQuery, PackageQuery, - PackageContributionActivityQuery, ) diff --git a/ckanext/attribution/logic/actions/meta/help.py b/ckanext/attribution/logic/actions/meta/help.py index 881685e..4cd01b5 100644 --- a/ckanext/attribution/logic/actions/meta/help.py +++ b/ckanext/attribution/logic/actions/meta/help.py @@ -6,7 +6,7 @@ # CREATE =========================================================================================== -agent_affiliation_create = ''' +agent_affiliation_create = """ Create an :class:`~ckanext.attribution.model.agent_affiliation.AgentAffiliation` link record between two :class:`~ckanext.attribution.model.agent.Agent` records, e.g. to show institutional affiliation for an author. @@ -25,9 +25,9 @@ :type end_date: datetime.date, optional :returns: New agent affiliation record. :rtype: dict -''' +""" -agent_create = ''' +agent_create = """ Action for creating an :class:`~ckanext.attribution.model.agent.Agent` record. Different fields are required by different agent types. @@ -47,9 +47,9 @@ :type name: str, optional :returns: New agent record. :rtype: dict -''' +""" -contribution_activity_create = ''' +contribution_activity_create = """ Creates a :class:`~ckanext.attribution.model.contribution_activity.ContributionActivity` record, linked to a package and an agent via package_contribution_activity and agent_contribution_activity records (respectively). These link records are also created as part of this action, as the activity @@ -69,29 +69,29 @@ :type time: datetime.datetime, optional :returns: New contribution activity record. :rtype: dict -''' +""" # DELETE =========================================================================================== -agent_affiliation_delete = ''' +agent_affiliation_delete = """ Delete an :class:`~ckanext.attribution.model.agent_affiliation.AgentAffiliation` record by ID. :param id: ID of the affiliation record :type id: str :returns: The affiliation record. :rtype: dict -''' +""" -agent_delete = ''' +agent_delete = """ Delete an :class:`~ckanext.attribution.model.agent.Agent` record by ID. :param id: ID of the agent record :type id: str :returns: The agent record. :rtype: dict -''' +""" -agent_contribution_activity_delete = ''' +agent_contribution_activity_delete = """ Delete an :class:`~ckanext.attribution.model.agent_contribution_activity.AgentContributionActivity` record by ID. @@ -99,9 +99,9 @@ :type id: str :returns: The agent contribution activity record. :rtype: dict -''' +""" -contribution_activity_delete = ''' +contribution_activity_delete = """ Delete a :class:`~ckanext.attribution.model.contribution_activity.ContributionActivity` record by ID. @@ -109,9 +109,9 @@ :type id: str :returns: The contribution activity record. :rtype: dict -''' +""" -package_contribution_activity_delete = ''' +package_contribution_activity_delete = """ Delete a :class:`~ckanext.attribution.model.package_contribution_activity.PackageContributionActivity` record by ID. @@ -120,11 +120,11 @@ :type id: str :returns: The package contribution activity record. :rtype: dict -''' +""" # EXTRA ============================================================================================ -attribution_controlled_lists = ''' +attribution_controlled_lists = """ Return one or more lists or dicts of defined values, e.g. agent types or contribution activity types. Details dicts can include various pieces of arbitrary information (e.g. names, translations, or icon definitions for templates) as long as the initial structure is retained. @@ -133,9 +133,9 @@ :type lists: list, optional :return: dict of all requested lists (or all lists if unspecified) :rtype: dict -''' +""" -agent_external_search = ''' +agent_external_search = """ Search external sources for agent data. Ignores records that already exist in the database. :param q: searches all fields (names, ids, etc) @@ -144,9 +144,9 @@ :type sources: list, optional :returns: A list of potential matches. :rtype: list -''' +""" -agent_external_read = ''' +agent_external_read = """ Read data from an external source like ORCID or ROR. :param agent_id: ID of the record to read @@ -160,9 +160,9 @@ :type diff: bool, optional :returns: The details pulled from the external source, formatted as a record dict :rtype: dict -''' +""" -validate_external_id = ''' +validate_external_id = """ Validate/format an external ID. :param external_id: ID from external service @@ -170,29 +170,29 @@ :param external_id_scheme: external scheme, e.g. orcid :type external_id_scheme: str :return: -''' +""" # SHOW ============================================================================================= -agent_affiliation_show = ''' +agent_affiliation_show = """ Retrieve an :class:`~ckanext.attribution.model.agent_affiliation.AgentAffiliation` record by ID. :param id: ID of the affiliation record :type id: str :returns: The affiliation record. :rtype: dict -''' +""" -agent_show = ''' +agent_show = """ Retrieve an :class:`~ckanext.attribution.model.agent.Agent` record by ID. :param id: ID of the agent record :type id: str :returns: The agent record. :rtype: dict -''' +""" -agent_list = ''' +agent_list = """ Search for :class:`~ckanext.attribution.model.agent.Agent` records. :param q: name or external id (ORCID/ROR ID) of the agent record @@ -201,9 +201,9 @@ :type mode: str, optional :returns: A list of potential matches. :rtype: list -''' +""" -agent_contribution_activity_show = ''' +agent_contribution_activity_show = """ Retrieve an :class:`~ckanext.attribution.model.agent_contribution_activity.AgentContributionActivity` record by ID. @@ -212,9 +212,9 @@ :type id: str :returns: The agent contribution activity record. :rtype: dict -''' +""" -contribution_activity_show = ''' +contribution_activity_show = """ Retrieve a :class:`~ckanext.attribution.model.contribution_activity.ContributionActivity` record by ID. @@ -222,9 +222,9 @@ :type id: str :returns: The contribution activity record. :rtype: dict -''' +""" -package_contribution_activity_show = ''' +package_contribution_activity_show = """ Retrieve a :class:`~ckanext.attribution.model.package_contribution_activity.PackageContributionActivity` record by ID. @@ -233,9 +233,9 @@ :type id: str :returns: The package contribution activity record. :rtype: dict -''' +""" -package_contributions_show = ''' +package_contributions_show = """ Show associated agents and their contributions for a given package. Agents are returned in citation then agent id order. @@ -247,10 +247,10 @@ :type offset: int :returns: The package contribution activity record. :rtype: dict -''' +""" -agent_affiliations = ''' +agent_affiliations = """ Show affiliated agents, either all or for a given package. Including a package ID will still return 'global' affiliations, e.g. those with no specific package associated. @@ -260,11 +260,11 @@ :type package_id: str, optional :returns: The package contribution activity record. :rtype: dict -''' +""" # UPDATE =========================================================================================== -agent_affiliation_update = ''' +agent_affiliation_update = """ Update an :class:`~ckanext.attribution.model.agent_affiliation.AgentAffiliation` link record. :param id: ID of the record to update @@ -285,9 +285,9 @@ :param data_dict: :returns: The updated agent affiliation record. :rtype: dict -''' +""" -agent_update = ''' +agent_update = """ Action for updating an :class:`~ckanext.attribution.model.agent.Agent` record. Different fields are required by different agent types. @@ -311,9 +311,9 @@ :param data_dict: :returns: The updated agent record. :rtype: dict -''' +""" -agent_external_update = ''' +agent_external_update = """ Action for updating an :class:`~ckanext.attribution.model.agent.Agent` record by pulling information from an external source like ORCID or ROR. @@ -321,9 +321,9 @@ :type id: str :returns: The updated agent record. :rtype: dict -''' +""" -contribution_activity_update = ''' +contribution_activity_update = """ Updates a :class:`~ckanext.attribution.model.contribution_activity.ContributionActivity` record, linked to a package and an agent via package_contribution_activity and agent_contribution_activity records (respectively). These link records are also updated as part of this action, as the activity @@ -343,4 +343,4 @@ :param data_dict: :returns: New contribution activity record. :rtype: dict -''' +""" diff --git a/ckanext/attribution/logic/actions/meta/schema.py b/ckanext/attribution/logic/actions/meta/schema.py index bd1058e..9f9022b 100644 --- a/ckanext/attribution/logic/actions/meta/schema.py +++ b/ckanext/attribution/logic/actions/meta/schema.py @@ -4,9 +4,8 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK -from ckantools.validators import list_of_strings - from ckan.plugins import toolkit +from ckantools.validators import list_of_strings # grab all the validator functions upfront ignore_missing = toolkit.get_validator('ignore_missing') diff --git a/ckanext/attribution/logic/actions/show.py b/ckanext/attribution/logic/actions/show.py index 96b397d..a575b97 100644 --- a/ckanext/attribution/logic/actions/show.py +++ b/ckanext/attribution/logic/actions/show.py @@ -6,6 +6,11 @@ import itertools +from ckan.plugins import toolkit +from ckantools.decorators import action +from fuzzywuzzy import fuzz +from sqlalchemy import or_ + from ckanext.attribution.logic.actions.meta import help, schema from ckanext.attribution.model.crud import ( AgentAffiliationQuery, @@ -15,11 +20,6 @@ PackageContributionActivityQuery, PackageQuery, ) -from ckantools.decorators import action -from fuzzywuzzy import fuzz -from sqlalchemy import or_ - -from ckan.plugins import toolkit @action(schema.agent_affiliation_show, help.agent_affiliation_show, get=True) diff --git a/ckanext/attribution/logic/actions/update.py b/ckanext/attribution/logic/actions/update.py index 2cb5a56..4691af1 100644 --- a/ckanext/attribution/logic/actions/update.py +++ b/ckanext/attribution/logic/actions/update.py @@ -5,18 +5,19 @@ # Created by the Natural History Museum in London, UK from ckan.plugins import toolkit +from ckantools.decorators import action, basic_action + from ckanext.attribution.logic.actions.helpers import ( - parse_contributors, get_author_string, + parse_contributors, ) +from ckanext.attribution.logic.actions.meta import help, schema from ckanext.attribution.model.crud import ( - AgentQuery, - ContributionActivityQuery, AgentAffiliationQuery, AgentContributionActivityQuery, + AgentQuery, + ContributionActivityQuery, ) -from ckantools.decorators import action, basic_action -from ckanext.attribution.logic.actions.meta import help, schema @action(schema.agent_affiliation_update, help.agent_affiliation_update) diff --git a/ckanext/attribution/logic/auth/delete.py b/ckanext/attribution/logic/auth/delete.py index 7b067f0..78f6adb 100644 --- a/ckanext/attribution/logic/auth/delete.py +++ b/ckanext/attribution/logic/auth/delete.py @@ -4,11 +4,10 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK +from ckan.authz import is_sysadmin from ckantools.decorators import auth from ckantools.vars import auth_valid -from ckan.authz import is_sysadmin - @auth() def agent_affiliation_delete(context, data_dict): diff --git a/ckanext/attribution/logic/auth/show.py b/ckanext/attribution/logic/auth/show.py index 0564e2d..604327b 100644 --- a/ckanext/attribution/logic/auth/show.py +++ b/ckanext/attribution/logic/auth/show.py @@ -6,7 +6,6 @@ from ckantools.decorators import auth from ckantools.vars import auth_valid -from ckan.plugins import toolkit @auth(anon=True) diff --git a/ckanext/attribution/logic/auth/update.py b/ckanext/attribution/logic/auth/update.py index d50c3f1..c4e1960 100644 --- a/ckanext/attribution/logic/auth/update.py +++ b/ckanext/attribution/logic/auth/update.py @@ -4,11 +4,10 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK +from ckan.authz import is_sysadmin from ckantools.decorators import auth from ckantools.vars import auth_valid -from ckan.authz import is_sysadmin - @auth() def agent_affiliation_update(context, data_dict): diff --git a/ckanext/attribution/model/agent_affiliation.py b/ckanext/attribution/model/agent_affiliation.py index a0f1a29..10c9e15 100644 --- a/ckanext/attribution/model/agent_affiliation.py +++ b/ckanext/attribution/model/agent_affiliation.py @@ -6,9 +6,10 @@ from ckan.model import DomainObject, meta from ckan.model.types import make_uuid -from ckanext.attribution.model.agent import agent_table from sqlalchemy import Column, Date, ForeignKey, Table, UnicodeText +from ckanext.attribution.model.agent import agent_table + agent_affiliation_table = Table( 'agent_affiliation', meta.metadata, @@ -54,8 +55,5 @@ def other_agent(self, agent_id): def check_for_table(): - """ - - """ if agent_table.exists(): agent_affiliation_table.create(checkfirst=True) diff --git a/ckanext/attribution/model/agent_contribution_activity.py b/ckanext/attribution/model/agent_contribution_activity.py index 5979c16..fa656b9 100644 --- a/ckanext/attribution/model/agent_contribution_activity.py +++ b/ckanext/attribution/model/agent_contribution_activity.py @@ -6,9 +6,10 @@ from ckan.model import DomainObject, meta from ckan.model.types import make_uuid +from sqlalchemy import Column, ForeignKey, Table, UnicodeText + from ckanext.attribution.model.agent import agent_table from ckanext.attribution.model.contribution_activity import contribution_activity_table -from sqlalchemy import Column, ForeignKey, Table, UnicodeText agent_contribution_activity_table = Table( 'agent_contribution_activity', @@ -39,8 +40,5 @@ class AgentContributionActivity(DomainObject): def check_for_table(): - """ - - """ if agent_table.exists() and contribution_activity_table.exists(): agent_contribution_activity_table.create(checkfirst=True) diff --git a/ckanext/attribution/model/contribution_activity.py b/ckanext/attribution/model/contribution_activity.py index 322c0c4..4805103 100644 --- a/ckanext/attribution/model/contribution_activity.py +++ b/ckanext/attribution/model/contribution_activity.py @@ -6,7 +6,7 @@ from ckan.model import DomainObject, meta from ckan.model.types import make_uuid -from sqlalchemy import Column, DateTime, Table, UnicodeText, Integer +from sqlalchemy import Column, DateTime, Integer, Table, UnicodeText # this table stores contribution activities contribution_activity_table = Table( @@ -30,7 +30,4 @@ class ContributionActivity(DomainObject): def check_for_table(): - """ - - """ contribution_activity_table.create(checkfirst=True) diff --git a/ckanext/attribution/model/crud/__init__.py b/ckanext/attribution/model/crud/__init__.py index d9287bc..2ad522f 100644 --- a/ckanext/attribution/model/crud/__init__.py +++ b/ckanext/attribution/model/crud/__init__.py @@ -2,5 +2,5 @@ from .agent_affiliation import AgentAffiliationQuery from .agent_contribution_activity import AgentContributionActivityQuery from .contribution_activity import ContributionActivityQuery -from .package_contribution_activity import PackageContributionActivityQuery from .package import PackageQuery +from .package_contribution_activity import PackageContributionActivityQuery diff --git a/ckanext/attribution/model/crud/_base.py b/ckanext/attribution/model/crud/_base.py index 158c3d6..36478f3 100644 --- a/ckanext/attribution/model/crud/_base.py +++ b/ckanext/attribution/model/crud/_base.py @@ -5,9 +5,10 @@ # Created by the Natural History Museum in London, UK from abc import ABCMeta + from ckan.model import DomainObject, Session -from sqlalchemy import Table from ckan.plugins import toolkit +from sqlalchemy import Table class BaseQuery(object): @@ -26,12 +27,6 @@ class BaseQuery(object): @classmethod def _columns(cls, **kwargs): - ''' - - - :param kwargs: - - ''' return {c.name: kwargs.get(c.name) for c in cls.t.c if c.name in kwargs} @classmethod @@ -119,13 +114,6 @@ def all(cls): @classmethod def update(cls, item_id, **kwargs): - ''' - - - :param item_id: - :param kwargs: - - ''' try: del kwargs['id'] except KeyError: @@ -139,12 +127,6 @@ def update(cls, item_id, **kwargs): @classmethod def delete(cls, item_id): - ''' - - - :param item_id: - - ''' to_delete = Session.query(cls.m).get(item_id) if to_delete is not None: Session.delete(to_delete) diff --git a/ckanext/attribution/model/crud/agent.py b/ckanext/attribution/model/crud/agent.py index 26d57c8..dcf8b5d 100644 --- a/ckanext/attribution/model/crud/agent.py +++ b/ckanext/attribution/model/crud/agent.py @@ -6,10 +6,11 @@ from ckan.model import Session from ckan.plugins import toolkit +from requests import HTTPError + from ckanext.attribution.lib.orcid_api import OrcidApi from ckanext.attribution.lib.ror_api import RorApi from ckanext.attribution.model.agent import Agent, agent_table -from requests import HTTPError from ._base import BaseQuery @@ -18,23 +19,23 @@ class AgentQuery(BaseQuery): """ CRUD methods for :class:`~ckanext.attribution.model.agent.Agent`. - Fields - ====== + Fields ====== :param agent_type: broad type of agent; usually 'person' or 'org' :type agent_type: str :param external_id: the agent's ID from an external service like ORCID or ROR :type external_id: str, optional - :param external_id_scheme: the name of the scheme for the external ID, e.g. 'orcid' or 'ror' + :param external_id_scheme: the name of the scheme for the external ID, e.g. 'orcid' + or 'ror' :type external_id_scheme: str, optional :param family_name: family name of an person [person only, required] :type family_name: str, optional :param given_names: given name(s) or initials of an person [person only, required] :type given_names: str, optional - :param given_names_first: whether given names should be displayed before the family name - (default True) [person only, optional] + :param given_names_first: whether given names should be displayed before the family + name (default True) [person only, optional] :type given_names_first: bool, optional - :param user_id: the ID for a registered user of this CKAN instance associated with this agent - [person only, optional] + :param user_id: the ID for a registered user of this CKAN instance associated with + this agent [person only, optional] :type user_id: str, optional :param name: name of an organisation [org only, required] :type name: str, optional @@ -124,8 +125,9 @@ def _read_from_orcid_api(cls, record, api=None): :param record: the existing record :type record: Agent - :param api: an API instance already in use (useful if performing this action over many - agent records, to avoid instantiating many API connections) (Default value = None) + :param api: an API instance already in use (useful if performing this action + over many agent records, to avoid instantiating many API connections) + (Default value = None) :type api: OrcidApi :returns: the updated agent record :rtype: Agent diff --git a/ckanext/attribution/model/crud/agent_affiliation.py b/ckanext/attribution/model/crud/agent_affiliation.py index 11270f1..36104d8 100644 --- a/ckanext/attribution/model/crud/agent_affiliation.py +++ b/ckanext/attribution/model/crud/agent_affiliation.py @@ -4,20 +4,17 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK +from sqlalchemy import and_, or_ + from ckanext.attribution.model.agent_affiliation import ( AgentAffiliation, agent_affiliation_table, ) from ._base import BaseQuery -from sqlalchemy import or_, and_ class AgentAffiliationQuery(BaseQuery): - """ - - """ - # model and table (subclasses should override) m = AgentAffiliation t = agent_affiliation_table diff --git a/ckanext/attribution/model/crud/agent_contribution_activity.py b/ckanext/attribution/model/crud/agent_contribution_activity.py index 5818308..d54d7f5 100644 --- a/ckanext/attribution/model/crud/agent_contribution_activity.py +++ b/ckanext/attribution/model/crud/agent_contribution_activity.py @@ -13,10 +13,6 @@ class AgentContributionActivityQuery(BaseQuery): - """ - - """ - # model and table (subclasses should override) m = AgentContributionActivity t = agent_contribution_activity_table diff --git a/ckanext/attribution/model/crud/contribution_activity.py b/ckanext/attribution/model/crud/contribution_activity.py index 925843f..8ea7729 100644 --- a/ckanext/attribution/model/crud/contribution_activity.py +++ b/ckanext/attribution/model/crud/contribution_activity.py @@ -13,10 +13,6 @@ class ContributionActivityQuery(BaseQuery): - """ - - """ - # model and table (subclasses should override) m = ContributionActivity t = contribution_activity_table diff --git a/ckanext/attribution/model/crud/package.py b/ckanext/attribution/model/crud/package.py index 64e0844..51f0508 100644 --- a/ckanext/attribution/model/crud/package.py +++ b/ckanext/attribution/model/crud/package.py @@ -4,9 +4,8 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK -import itertools -from ckan.model import Package, package_table, Session +from ckan.model import Package, Session, package_table from ckan.plugins import toolkit from ._base import BaseQuery @@ -14,10 +13,6 @@ class PackageQuery(BaseQuery): - """ - - """ - m = Package t = package_table diff --git a/ckanext/attribution/model/crud/package_contribution_activity.py b/ckanext/attribution/model/crud/package_contribution_activity.py index e7e7471..dbbc07a 100644 --- a/ckanext/attribution/model/crud/package_contribution_activity.py +++ b/ckanext/attribution/model/crud/package_contribution_activity.py @@ -4,19 +4,17 @@ # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK +from ckan.model import Session + from ckanext.attribution.model.package_contribution_activity import ( PackageContributionActivity, package_contribution_activity_table, ) -from ckan.model import Session + from ._base import BaseQuery class PackageContributionActivityQuery(BaseQuery): - """ - - """ - # model and table (subclasses should override) m = PackageContributionActivity t = package_contribution_activity_table diff --git a/ckanext/attribution/model/package_contribution_activity.py b/ckanext/attribution/model/package_contribution_activity.py index 96820f7..a86e82f 100644 --- a/ckanext/attribution/model/package_contribution_activity.py +++ b/ckanext/attribution/model/package_contribution_activity.py @@ -6,9 +6,10 @@ from ckan.model import DomainObject, meta, package_table from ckan.model.types import make_uuid -from ckanext.attribution.model.contribution_activity import contribution_activity_table from sqlalchemy import Column, ForeignKey, Table, UnicodeText +from ckanext.attribution.model.contribution_activity import contribution_activity_table + package_contribution_activity_table = Table( 'package_contribution_activity', meta.metadata, @@ -38,8 +39,5 @@ class PackageContributionActivity(DomainObject): def check_for_table(): - """ - - """ if package_table.exists() and contribution_activity_table.exists(): package_contribution_activity_table.create(checkfirst=True) diff --git a/ckanext/attribution/model/relationships.py b/ckanext/attribution/model/relationships.py index 9697051..38e49b7 100644 --- a/ckanext/attribution/model/relationships.py +++ b/ckanext/attribution/model/relationships.py @@ -3,7 +3,6 @@ # # This file is part of ckanext-attribution # Created by the Natural History Museum in London, UK - """ These relationships are defined separately to the object/table declarations to allow them to reference each other without circular imports. @@ -11,7 +10,7 @@ from ckan.model import Package, User, meta from sqlalchemy import or_ -from sqlalchemy.orm import backref, relationship, attributes +from sqlalchemy.orm import attributes, backref, relationship from .agent import Agent, agent_table from .agent_affiliation import AgentAffiliation, agent_affiliation_table diff --git a/ckanext/attribution/plugin.py b/ckanext/attribution/plugin.py index db83fe3..08eb630 100644 --- a/ckanext/attribution/plugin.py +++ b/ckanext/attribution/plugin.py @@ -5,6 +5,10 @@ # Created by the Natural History Museum in London, UK from ckan.plugins import SingletonPlugin, implements, interfaces, toolkit +from ckantools.loaders import create_actions, create_auth + +from ckanext.attribution import routes +from ckanext.attribution.commands import cli from ckanext.attribution.lib import helpers from ckanext.attribution.model import ( agent, @@ -14,9 +18,6 @@ package_contribution_activity, relationships, ) -from ckanext.attribution.commands import cli -from ckanext.attribution import routes -from ckantools.loaders import create_actions, create_auth try: from ckanext.doi.interfaces import IDoi @@ -47,17 +48,17 @@ class AttributionPlugin(SingletonPlugin): def get_actions(self): from ckanext.attribution.logic.actions import ( create, - show, - update, delete, extra, + show, + update, ) return create_actions(create, show, update, delete, extra) # IAuthFunctions def get_auth_functions(self): - from ckanext.attribution.logic.auth import create, show, update, delete, extra + from ckanext.attribution.logic.auth import create, delete, extra, show, update return create_auth(create, show, update, delete, extra) diff --git a/ckanext/attribution/routes/user.py b/ckanext/attribution/routes/user.py index 9870d81..38841d2 100644 --- a/ckanext/attribution/routes/user.py +++ b/ckanext/attribution/routes/user.py @@ -6,6 +6,7 @@ from ckan.plugins import toolkit from flask import Blueprint + from ckanext.attribution.lib.helpers import user_contributions blueprint = Blueprint(name='attribution_user', import_name=__name__) diff --git a/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/Autocomplete.vue b/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/Autocomplete.vue index d4d5822..e44ddbd 100644 --- a/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/Autocomplete.vue +++ b/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/Autocomplete.vue @@ -116,10 +116,10 @@ export default { return this.failed ? 'fa-times' : this.loading - ? 'fa-spinner fa-spin' - : this.typing - ? 'fa-xs fa-ellipsis-h' - : 'fa-check'; + ? 'fa-spinner fa-spin' + : this.typing + ? 'fa-xs fa-ellipsis-h' + : 'fa-check'; }, }, methods: { diff --git a/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/ValidatedField.vue b/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/ValidatedField.vue index e229161..12e4732 100644 --- a/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/ValidatedField.vue +++ b/ckanext/attribution/theme/assets/scripts/apps/package-edit/src/components/fields/ValidatedField.vue @@ -48,10 +48,10 @@ export default { return this.failed ? 'fa-times' : this.loading - ? 'fa-spinner fa-spin' - : this.typing - ? 'fa-xs fa-ellipsis-h' - : 'fa-check'; + ? 'fa-spinner fa-spin' + : this.typing + ? 'fa-xs fa-ellipsis-h' + : 'fa-check'; }, }, methods: { diff --git a/docs/_scripts/gen_api_pages.py b/docs/_scripts/gen_api_pages.py index 8efa6b3..a09f789 100644 --- a/docs/_scripts/gen_api_pages.py +++ b/docs/_scripts/gen_api_pages.py @@ -1,6 +1,5 @@ # !/usr/bin/env python # encoding: utf-8 - """ Generate the code reference pages and navigation. diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 352ba36..874b4df 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -1,6 +1,7 @@ import pytest -from ckan.tests import factories from ckan.common import g +from ckan.tests import factories + from ckanext.attribution.lib import helpers From 531b36891801a14308f2dbba15a00c204047652d Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 13:09:40 +0000 Subject: [PATCH 13/18] ci: add docformatter args back apparently they don't get pulled from pyproject.toml when using the github action --- .pre-commit-config.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd0f8b7..82faf5b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,6 +25,9 @@ repos: rev: eb1df34 hooks: - id: docformatter + # these don't get pulled from the config in github actions + args: [ "-i", "--wrap-summaries=88", "--wrap-descriptions=88", + "--pre-summary-newline", "--make-summary-multi-line" ] - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0-alpha.8 hooks: From e6534365fb272f93b2152b2db624144cf700aa5c Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 14:34:40 +0000 Subject: [PATCH 14/18] ci: pull docformatter args from pyproject --- .pre-commit-config.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 82faf5b..4717609 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,9 +25,7 @@ repos: rev: eb1df34 hooks: - id: docformatter - # these don't get pulled from the config in github actions - args: [ "-i", "--wrap-summaries=88", "--wrap-descriptions=88", - "--pre-summary-newline", "--make-summary-multi-line" ] + args: [ '-i', '--config', './pyproject.toml' ] - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0-alpha.8 hooks: From 42aa975af4f2e68a2165904494431ba415119ac6 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 14:43:13 +0000 Subject: [PATCH 15/18] ci: add tomli as docformatter dep as recommended by docformatter issue 172 --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4717609..11cbb60 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,6 +26,7 @@ repos: hooks: - id: docformatter args: [ '-i', '--config', './pyproject.toml' ] + additional_dependencies: ['tomli'] - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0-alpha.8 hooks: From 9584421c22dcb0c533ecb427b01b0a4188141566 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Wed, 30 Oct 2024 14:50:13 +0000 Subject: [PATCH 16/18] chore: standardise quotes in pre-commit config --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 11cbb60..04e9d79 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,14 +7,14 @@ repos: - id: detect-private-key - id: end-of-file-fixer - id: name-tests-test - args: ["--pytest-test-first"] + args: ['--pytest-test-first'] exclude: ^tests/helpers/ - id: trailing-whitespace - repo: https://github.com/commitizen-tools/commitizen rev: v3.30.0 hooks: - id: commitizen - additional_dependencies: ["cz-nhm"] + additional_dependencies: ['cz-nhm'] - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.7.1 hooks: From 7c80e932f372036a126b2f225e47774e6bf97ca8 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Thu, 31 Oct 2024 09:53:48 +0000 Subject: [PATCH 17/18] docs: return -> returns --- ckanext/attribution/commands/migration/api_search.py | 2 +- ckanext/attribution/commands/migration/combiner.py | 6 +++--- ckanext/attribution/commands/migration/common.py | 2 +- ckanext/attribution/commands/migration/parser.py | 8 ++++---- ckanext/attribution/lib/helpers.py | 4 ++-- ckanext/attribution/logic/actions/meta/help.py | 4 ++-- ckanext/attribution/model/agent.py | 2 +- ckanext/attribution/model/crud/_base.py | 2 +- ckanext/attribution/routes/user.py | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ckanext/attribution/commands/migration/api_search.py b/ckanext/attribution/commands/migration/api_search.py index c3db5c3..47f1fef 100644 --- a/ckanext/attribution/commands/migration/api_search.py +++ b/ckanext/attribution/commands/migration/api_search.py @@ -50,7 +50,7 @@ def _search_api(self, contrib, lookup, api_name, result_format): :param lookup: dict of query params (plus display_name) to send to api.search :param api_name: name of the API (see self.api) :param result_format: display format of each result, e.g. "{name} ({location})" - :return: None if not found, dict for matching result if found/selected + :returns: None if not found, dict for matching result if found/selected """ check_installed(cli_installed) diff --git a/ckanext/attribution/commands/migration/combiner.py b/ckanext/attribution/commands/migration/combiner.py index 25c3f32..848cc3d 100644 --- a/ckanext/attribution/commands/migration/combiner.py +++ b/ckanext/attribution/commands/migration/combiner.py @@ -35,7 +35,7 @@ def separate(self, group): :param group: a list of ParsedSegment instances that are probably the same contributor - :return: a list of lists of ParsedSegments + :returns: a list of lists of ParsedSegments """ all_names = sorted( list(set([str(x.name) for x in group])), key=lambda x: -len(x) @@ -96,7 +96,7 @@ def combine_person_names(self, names): """ Uses a list of HumanNames to determine the longest possible name for a person. - :return: a dict of family_name, given_names (includes middle names), and key + :returns: a dict of family_name, given_names (includes middle names), and key (i.e. a sort/display name) """ check_installed(cli_installed) @@ -168,7 +168,7 @@ def run(self): Run the combiner over the whole parser list, including separating groups, combining names, searching APIs, and updating the affiliations dict. - :return: a list of contributors + :returns: a list of contributors """ combined = [] diff --git a/ckanext/attribution/commands/migration/common.py b/ckanext/attribution/commands/migration/common.py index 3b05ce3..5abc4bd 100644 --- a/ckanext/attribution/commands/migration/common.py +++ b/ckanext/attribution/commands/migration/common.py @@ -14,7 +14,7 @@ def multi_choice(question, options, default=0): """ Provide the user with a list of options. - :return: index of the chosen option + :returns: index of the chosen option """ click.echo(question) for i, o in enumerate(options): diff --git a/ckanext/attribution/commands/migration/parser.py b/ckanext/attribution/commands/migration/parser.py index c7f1b1f..5a78d6b 100644 --- a/ckanext/attribution/commands/migration/parser.py +++ b/ckanext/attribution/commands/migration/parser.py @@ -54,7 +54,7 @@ def run(self, txt, pkg_id, contrib_type): :param txt: the chunk of text to process :param pkg_id: associated package :param contrib_type: author, contributor, or affiliation - :return: list of ParsedSegment instances extracted from the text + :returns: list of ParsedSegment instances extracted from the text """ if not self.validate(txt): return @@ -107,7 +107,7 @@ def validate(self, txt): """ Check the text can/should actually be parsed. - :return: True/False + :returns: True/False """ if txt is None: return False @@ -130,7 +130,7 @@ def split(self, txt): contributors. :param txt: - :return: + :returns: """ lines = [ln.strip() for ln in txt.split('\n')] segments = [ @@ -224,7 +224,7 @@ def extract_affiliations(self, txt): """ Uses regexes to find probable affiliations in parentheses. - :return: contributor name, list of affiliations + :returns: contributor name, list of affiliations """ has_affiliation = rgx.has_affiliation.match(txt) no_affiliation = rgx.no_affiliation.match(txt) diff --git a/ckanext/attribution/lib/helpers.py b/ckanext/attribution/lib/helpers.py index 93eba95..3afce8f 100644 --- a/ckanext/attribution/lib/helpers.py +++ b/ckanext/attribution/lib/helpers.py @@ -16,7 +16,7 @@ def can_edit(): """ Check editing permissions for updating agent directly. - :return: + :returns: """ try: permitted = toolkit.check_access('agent_update', {}, {}) @@ -35,7 +35,7 @@ def get_contributions(pkg_id): :func:`~ckanext.attribution.model.crud.PackageQuery.get_contributions` query method. :param pkg_id: - :return: + :returns: """ return PackageQuery.get_contributions(pkg_id) diff --git a/ckanext/attribution/logic/actions/meta/help.py b/ckanext/attribution/logic/actions/meta/help.py index 4cd01b5..d0a865a 100644 --- a/ckanext/attribution/logic/actions/meta/help.py +++ b/ckanext/attribution/logic/actions/meta/help.py @@ -131,7 +131,7 @@ :param lists: names of the lists to be returned :type lists: list, optional -:return: dict of all requested lists (or all lists if unspecified) +:returns: dict of all requested lists (or all lists if unspecified) :rtype: dict """ @@ -169,7 +169,7 @@ :type external_id: str :param external_id_scheme: external scheme, e.g. orcid :type external_id_scheme: str -:return: +:returns: """ # SHOW ============================================================================================= diff --git a/ckanext/attribution/model/agent.py b/ckanext/attribution/model/agent.py index 621d54d..646f939 100644 --- a/ckanext/attribution/model/agent.py +++ b/ckanext/attribution/model/agent.py @@ -57,7 +57,7 @@ def standardised_name(self): """ Family name first for persons. - :return: + :returns: """ if self.agent_type == 'person': return ', '.join([self.family_name, self.given_names]) diff --git a/ckanext/attribution/model/crud/_base.py b/ckanext/attribution/model/crud/_base.py index 36478f3..f1db0c9 100644 --- a/ckanext/attribution/model/crud/_base.py +++ b/ckanext/attribution/model/crud/_base.py @@ -92,7 +92,7 @@ def exists(cls, item_id): Check if a record with the given ID exists. :param item_id: the ID of the potential record - :return: bool + :returns: bool """ return Session.query(cls.m).get(item_id) is not None diff --git a/ckanext/attribution/routes/user.py b/ckanext/attribution/routes/user.py index 38841d2..7608f6a 100644 --- a/ckanext/attribution/routes/user.py +++ b/ckanext/attribution/routes/user.py @@ -18,7 +18,7 @@ def datasets(username): Render a list of datasets that this user has contributed to. :param username: The username - :return: str + :returns: str """ try: toolkit.check_access('user_show', {}, {'id': username}) From 751b4f63abf7636ccbd90f9d27b64a88f3e2caf9 Mon Sep 17 00:00:00 2001 From: Ginger Burns Date: Thu, 31 Oct 2024 10:01:12 +0000 Subject: [PATCH 18/18] docs: fill some empty parameters --- ckanext/attribution/commands/migration/parser.py | 4 ++-- ckanext/attribution/lib/helpers.py | 6 +++--- ckanext/attribution/logic/actions/meta/help.py | 14 +++++++------- ckanext/attribution/model/agent.py | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ckanext/attribution/commands/migration/parser.py b/ckanext/attribution/commands/migration/parser.py index 5a78d6b..17fc324 100644 --- a/ckanext/attribution/commands/migration/parser.py +++ b/ckanext/attribution/commands/migration/parser.py @@ -129,8 +129,8 @@ def split(self, txt): Uses multiple sub-methods to attempt to split the text into individual contributors. - :param txt: - :returns: + :param txt: a string containing multiple contributor names + :returns: a list of names """ lines = [ln.strip() for ln in txt.split('\n')] segments = [ diff --git a/ckanext/attribution/lib/helpers.py b/ckanext/attribution/lib/helpers.py index 3afce8f..c76c7b3 100644 --- a/ckanext/attribution/lib/helpers.py +++ b/ckanext/attribution/lib/helpers.py @@ -16,7 +16,7 @@ def can_edit(): """ Check editing permissions for updating agent directly. - :returns: + :returns: True if user can edit agents, False if not """ try: permitted = toolkit.check_access('agent_update', {}, {}) @@ -34,8 +34,8 @@ def get_contributions(pkg_id): Template access for the :func:`~ckanext.attribution.model.crud.PackageQuery.get_contributions` query method. - :param pkg_id: - :returns: + :param pkg_id: the ID of the package + :returns: list of activities associated with the package """ return PackageQuery.get_contributions(pkg_id) diff --git a/ckanext/attribution/logic/actions/meta/help.py b/ckanext/attribution/logic/actions/meta/help.py index d0a865a..0136149 100644 --- a/ckanext/attribution/logic/actions/meta/help.py +++ b/ckanext/attribution/logic/actions/meta/help.py @@ -169,7 +169,7 @@ :type external_id: str :param external_id_scheme: external scheme, e.g. orcid :type external_id_scheme: str -:returns: +:returns: dict containing the ID if valid and any errors """ # SHOW ============================================================================================= @@ -281,8 +281,8 @@ :type start_date: datetime.date, optional :param end_date: when the affiliation ended (e.g. when a researcher left an institution) :type end_date: datetime.date, optional -:param context: -:param data_dict: +:param context: request context +:param data_dict: request data :returns: The updated agent affiliation record. :rtype: dict """ @@ -307,8 +307,8 @@ :type user_id: str, optional :param name: name of an organisation [org only] :type name: str, optional -:param context: -:param data_dict: +:param context: request context +:param data_dict: request data :returns: The updated agent record. :rtype: dict """ @@ -339,8 +339,8 @@ :type level: str, optional :param time: time activity took place :type time: datetime.datetime, optional -:param context: -:param data_dict: +:param context: request context +:param data_dict: request data :returns: New contribution activity record. :rtype: dict """ diff --git a/ckanext/attribution/model/agent.py b/ckanext/attribution/model/agent.py index 646f939..cacb7e8 100644 --- a/ckanext/attribution/model/agent.py +++ b/ckanext/attribution/model/agent.py @@ -55,9 +55,9 @@ def display_name(self): @property def standardised_name(self): """ - Family name first for persons. + Name in a standardised format. - :returns: + :returns: full name (family name first) for person names, just name for other """ if self.agent_type == 'person': return ', '.join([self.family_name, self.given_names])