pub-analyzer 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pub-analyzer might be problematic. Click here for more details.
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/PKG-INFO +1 -1
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/report.tcss +4 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/works_extended.typ +1 -1
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/models/work.py +3 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/cards.py +7 -3
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/export.py +23 -20
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pyproject.toml +8 -8
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/LICENSE +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/README.md +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/author.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/body.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/buttons.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/checkbox.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/datatable.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/institution.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/main.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/search.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/tabs.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/css/tree.tcss +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/identifier.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/render.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/report.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/author_resume.typ +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/report.typ +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/sources.typ +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/works.typ +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/main.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/models/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/models/author.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/models/institution.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/models/report.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/models/source.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/author/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/author/cards.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/author/core.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/author/tables.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/body.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/common/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/common/card.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/common/filesystem.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/common/input.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/common/modal.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/common/selector.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/institution/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/institution/cards.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/institution/core.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/institution/tables.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/author.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/core.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/institution.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/locations.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/source.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/report/work.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/search/__init__.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/search/core.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/search/results.py +0 -0
- {pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/widgets/sidebar.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pub-analyzer
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A text user interface, written in python, which automates the generation of scientific production reports using OpenAlex
|
|
5
5
|
Home-page: https://github.com/alejandrgaspar/pub-analyzer
|
|
6
6
|
License: MIT
|
{pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/works_extended.typ
RENAMED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
#align(center)[_Authorships_]
|
|
25
25
|
#parbreak()
|
|
26
26
|
{% for authorship in work.work.authorships[:10] %}
|
|
27
|
-
- *{{ authorship.author_position }}:* #text({% if authorship.author.display_name == report.author.display_name %}rgb("909d63"){% endif %})[{{ authorship.author.display_name }}]
|
|
27
|
+
- *{{ authorship.author_position }}:* #underline([#link("{{ authorship.author.orcid or authorship.author.id }}")[#text({% if authorship.author.display_name == report.author.display_name %}rgb("909d63"){% endif %})[{{ authorship.author.display_name }}]]])
|
|
28
28
|
{% endfor %}
|
|
29
29
|
{% if work.work.authorships|length > 10 %}
|
|
30
30
|
- *...*
|
|
@@ -93,6 +93,9 @@ class Work(BaseModel):
|
|
|
93
93
|
authorships: list[Authorship]
|
|
94
94
|
|
|
95
95
|
cited_by_count: int
|
|
96
|
+
"""This number comes from the OpenAlex API, represents ALL citations to this work, and may not always be correct.
|
|
97
|
+
To use a verified number that respects the applied filters use [WorkReport][pub_analyzer.models.report.WorkReport].
|
|
98
|
+
"""
|
|
96
99
|
|
|
97
100
|
referenced_works: list[HttpUrl]
|
|
98
101
|
cited_by_api_url: HttpUrl
|
|
@@ -117,8 +117,12 @@ class CitationMetricsCard(Card):
|
|
|
117
117
|
|
|
118
118
|
def compose(self) -> ComposeResult:
|
|
119
119
|
"""Compose card."""
|
|
120
|
+
type_a_count = self.work_report.citation_resume.type_a_count
|
|
121
|
+
type_b_count = self.work_report.citation_resume.type_b_count
|
|
122
|
+
cited_by_count = type_a_count + type_b_count
|
|
123
|
+
|
|
120
124
|
yield Label('[italic]Citation[/italic]', classes='card-title')
|
|
121
125
|
|
|
122
|
-
yield Label(f'[bold]Count:[/bold] {
|
|
123
|
-
yield Label(f'[bold]Type A:[/bold] {
|
|
124
|
-
yield Label(f'[bold]Type B:[/bold] {
|
|
126
|
+
yield Label(f'[bold]Count:[/bold] {cited_by_count}')
|
|
127
|
+
yield Label(f'[bold]Type A:[/bold] {type_a_count}')
|
|
128
|
+
yield Label(f'[bold]Type B:[/bold] {type_b_count}')
|
|
@@ -4,7 +4,7 @@ import pathlib
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from enum import Enum
|
|
6
6
|
|
|
7
|
-
from textual import on
|
|
7
|
+
from textual import on, work
|
|
8
8
|
from textual.app import ComposeResult
|
|
9
9
|
from textual.containers import Horizontal, Vertical, VerticalScroll
|
|
10
10
|
from textual.widgets import Button, Label
|
|
@@ -59,33 +59,36 @@ class ExportReportPane(VerticalScroll):
|
|
|
59
59
|
else:
|
|
60
60
|
self.query_one(Button).disabled = True
|
|
61
61
|
|
|
62
|
+
@work(exclusive=True, thread=True)
|
|
63
|
+
async def _export_report(self, file_type: ExportFileType, file_path: pathlib.Path) -> None:
|
|
64
|
+
"""Export report."""
|
|
65
|
+
match file_type:
|
|
66
|
+
case self.ExportFileType.JSON:
|
|
67
|
+
with open(file_path, mode="w", encoding="utf-8") as file:
|
|
68
|
+
file.write(self.report.model_dump_json(indent=2, by_alias=True))
|
|
69
|
+
case self.ExportFileType.PDF:
|
|
70
|
+
report_bytes = await render_report(report=self.report, file_path=file_path)
|
|
71
|
+
with open(file_path, mode="wb") as file:
|
|
72
|
+
file.write(report_bytes)
|
|
73
|
+
|
|
74
|
+
self.app.call_from_thread(
|
|
75
|
+
self.app.notify,
|
|
76
|
+
title="Report exported successfully!",
|
|
77
|
+
message=f"The report was exported correctly. You can go see it at [i]{file_path}[/]",
|
|
78
|
+
timeout=20.0
|
|
79
|
+
)
|
|
80
|
+
|
|
62
81
|
@on(Button.Pressed, "#export-report-button")
|
|
63
82
|
async def export_report(self) -> None:
|
|
64
|
-
"""
|
|
83
|
+
"""Handle export report button."""
|
|
65
84
|
export_path = self.query_one(FileSystemSelector).path_selected
|
|
66
85
|
file_name = self.query_one(Input).value
|
|
67
86
|
file_type = self.query_one(self.ExportTypeSelector).value
|
|
68
87
|
|
|
69
|
-
if export_path and file_name:
|
|
88
|
+
if export_path and file_name and file_type:
|
|
70
89
|
file_path = export_path.joinpath(file_name)
|
|
71
|
-
|
|
72
|
-
match file_type:
|
|
73
|
-
case self.ExportFileType.JSON:
|
|
74
|
-
with open(file_path, mode="w", encoding="utf-8") as file:
|
|
75
|
-
file.write(self.report.model_dump_json(indent=2, by_alias=True))
|
|
76
|
-
case self.ExportFileType.PDF:
|
|
77
|
-
report_bytes = await render_report(report=self.report, file_path=file_path)
|
|
78
|
-
with open(file_path, mode="wb") as file:
|
|
79
|
-
file.write(report_bytes)
|
|
80
|
-
case _:
|
|
81
|
-
raise NotImplementedError
|
|
82
|
-
|
|
90
|
+
self._export_report(file_type=file_type, file_path=file_path)
|
|
83
91
|
self.query_one(Button).disabled = True
|
|
84
|
-
self.app.notify(
|
|
85
|
-
title="Report exported successfully!",
|
|
86
|
-
message=f"The report was exported correctly. You can go see it at [i]{file_path}[/]",
|
|
87
|
-
timeout=20.0
|
|
88
|
-
)
|
|
89
92
|
|
|
90
93
|
def compose(self) -> ComposeResult:
|
|
91
94
|
"""Compose content pane."""
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "pub-analyzer"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "A text user interface, written in python, which automates the generation of scientific production reports using OpenAlex"
|
|
9
9
|
|
|
10
10
|
authors = ["Alejandro Gaspar <alejandro@gaspar.land>"]
|
|
@@ -49,11 +49,11 @@ jinja2 = "3.1.2"
|
|
|
49
49
|
[tool.poetry.group.dev.dependencies]
|
|
50
50
|
textual-dev = "1.1.0"
|
|
51
51
|
|
|
52
|
-
pre-commit = "3.
|
|
52
|
+
pre-commit = "3.4.0"
|
|
53
53
|
mypy = "1.5.1"
|
|
54
|
-
ruff = "0.0.
|
|
54
|
+
ruff = "0.0.287"
|
|
55
55
|
|
|
56
|
-
pytest = "7.4.
|
|
56
|
+
pytest = "7.4.1"
|
|
57
57
|
pytest-asyncio = "0.21.1"
|
|
58
58
|
respx = "0.20.2"
|
|
59
59
|
vcrpy = "5.1.0"
|
|
@@ -61,16 +61,16 @@ pytest-recording = "0.13.0"
|
|
|
61
61
|
|
|
62
62
|
[tool.poetry.group.docs.dependencies]
|
|
63
63
|
mkdocs = "1.5.2"
|
|
64
|
-
mkdocs-material = "9.2.
|
|
64
|
+
mkdocs-material = "9.2.8"
|
|
65
65
|
|
|
66
|
-
mkdocstrings = {extras = ["python"], version = "0.
|
|
67
|
-
mkdocstrings-python = "1.6.
|
|
66
|
+
mkdocstrings = {extras = ["python"], version = "0.23.0"}
|
|
67
|
+
mkdocstrings-python = "1.6.1"
|
|
68
68
|
|
|
69
69
|
[tool.mypy]
|
|
70
70
|
strict = true
|
|
71
71
|
|
|
72
72
|
[tool.ruff]
|
|
73
|
-
required-version = "0.0.
|
|
73
|
+
required-version = "0.0.287"
|
|
74
74
|
target-version = "py310"
|
|
75
75
|
|
|
76
76
|
line-length = 140
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/author_resume.typ
RENAMED
|
File without changes
|
|
File without changes
|
{pub_analyzer-0.1.1 → pub_analyzer-0.1.2}/pub_analyzer/internal/templates/author/sources.typ
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|