refactor: centralize ICONS in constants module
- create core/constants.py with centralized ICONS definition - remove duplicate ICONS definitions from multiple modules - add emoji alternatives for better terminal support - update all modules to use centralized constants - export ICONS from package __init__.py This eliminates code duplication and provides a single source of truth for UI icons used throughout the application.
This commit is contained in:
parent
0f74e5dab2
commit
93d54ebc61
5 changed files with 64 additions and 48 deletions
|
@ -51,6 +51,7 @@ from .core import (
|
|||
Person,
|
||||
PrimitiveMetadataField,
|
||||
)
|
||||
from .core.constants import ICONS
|
||||
from .processing import (
|
||||
CitationBuilder,
|
||||
MetadataProcessor,
|
||||
|
@ -80,6 +81,8 @@ __all__ = [
|
|||
"Institution",
|
||||
"License",
|
||||
"Abstract",
|
||||
# Constants
|
||||
"ICONS",
|
||||
# Metadata fields
|
||||
"BaseMetadataField",
|
||||
"PrimitiveMetadataField",
|
||||
|
|
|
@ -10,6 +10,7 @@ from typing import Any
|
|||
|
||||
from rich.console import Console
|
||||
|
||||
from ..core.constants import ICONS
|
||||
from ..core.models import Abstract, License
|
||||
from .client import APIClient
|
||||
|
||||
|
@ -66,9 +67,6 @@ class AbstractProcessor:
|
|||
Retrieves and processes abstracts from CrossRef and OpenAlex.
|
||||
"""
|
||||
|
||||
# Icons for console output - TODO: should be moved to a constants module
|
||||
ICONS = {"info": "ℹ️", "warning": "⚠️", "error": "❌"}
|
||||
|
||||
def __init__(self, api_client: APIClient, console: Console | None = None):
|
||||
"""
|
||||
Initialize with an APIClient instance.
|
||||
|
@ -98,7 +96,7 @@ class AbstractProcessor:
|
|||
|
||||
if license.short in license_ok:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['info']} License {license.name} allows derivative works. Pulling abstract from CrossRef.",
|
||||
f"\n{ICONS['info']} License {license.name} allows derivative works. Pulling abstract from CrossRef.",
|
||||
style="info",
|
||||
)
|
||||
crossref_abstract = self._get_crossref_abstract(doi)
|
||||
|
@ -106,18 +104,18 @@ class AbstractProcessor:
|
|||
return Abstract(text=crossref_abstract, source="crossref")
|
||||
else:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['warning']} No abstract found in CrossRef!",
|
||||
f"\n{ICONS['warning']} No abstract found in CrossRef!",
|
||||
style="warning",
|
||||
)
|
||||
else:
|
||||
if license.name:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['info']} License {license.name} does not allow derivative works. Reconstructing abstract from OpenAlex!",
|
||||
f"\n{ICONS['info']} License {license.name} does not allow derivative works. Reconstructing abstract from OpenAlex!",
|
||||
style="info",
|
||||
)
|
||||
else:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['info']} Custom license does not allow derivative works. Reconstructing abstract from OpenAlex!",
|
||||
f"\n{ICONS['info']} Custom license does not allow derivative works. Reconstructing abstract from OpenAlex!",
|
||||
style="info",
|
||||
)
|
||||
|
||||
|
@ -126,12 +124,12 @@ class AbstractProcessor:
|
|||
return Abstract(text=openalex_abstract, source="openalex")
|
||||
else:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['warning']} No abstract found in OpenAlex!",
|
||||
f"\n{ICONS['warning']} No abstract found in OpenAlex!",
|
||||
style="warning",
|
||||
)
|
||||
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['warning']} No abstract found in either CrossRef nor OpenAlex!",
|
||||
f"\n{ICONS['warning']} No abstract found in either CrossRef nor OpenAlex!",
|
||||
style="warning",
|
||||
)
|
||||
return Abstract(text="", source="none")
|
||||
|
|
|
@ -23,28 +23,10 @@ from rich.progress import (
|
|||
from rich.table import Table
|
||||
from rich.theme import Theme
|
||||
|
||||
from .core.constants import ICONS
|
||||
from .processing.metadata import MetadataProcessor
|
||||
from .utils.validation import normalize_doi, sanitize_filename, validate_email_address
|
||||
|
||||
# Console icons for user-friendly output
|
||||
ICONS = {
|
||||
"success": "✓", # Simple checkmark
|
||||
"error": "✗", # Simple X
|
||||
"warning": "!", # Simple exclamation
|
||||
"info": "ℹ", # Info symbol
|
||||
"processing": "⋯", # Three dots
|
||||
"done": "∎", # Filled square
|
||||
"file": "⨳", # Document symbol
|
||||
"folder": "⊞", # Folder symbol
|
||||
"clock": "◷", # Clock symbol
|
||||
"search": "⌕", # Search symbol
|
||||
"data": "≡", # Three lines
|
||||
"doi": "∾", # Link symbol
|
||||
"total": "∑", # Sum symbol
|
||||
"save": "⤓", # Save/download arrow
|
||||
"upload": "⤒", # Upload arrow
|
||||
}
|
||||
|
||||
# Theme configuration for Rich console output
|
||||
THEME = Theme(
|
||||
{
|
||||
|
|
43
doi2dataset/core/constants.py
Normal file
43
doi2dataset/core/constants.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Constants for doi2dataset.
|
||||
|
||||
This module contains shared constants used across the application,
|
||||
including console icons and other configuration values.
|
||||
"""
|
||||
|
||||
# Console icons for user-friendly output
|
||||
ICONS = {
|
||||
# Status indicators
|
||||
"success": "✓", # Simple checkmark
|
||||
"error": "✗", # Simple X / ❌ (emoji alternative)
|
||||
"warning": "!", # Simple exclamation / ⚠️ (emoji alternative)
|
||||
"info": "ℹ", # Info symbol / ℹ️ (emoji alternative)
|
||||
# Process indicators
|
||||
"processing": "⋯", # Three dots / ⚙️ (emoji alternative)
|
||||
"done": "∎", # Filled square
|
||||
# File/data indicators
|
||||
"file": "⨳", # Document symbol
|
||||
"folder": "⊞", # Folder symbol
|
||||
"save": "⤓", # Save/download arrow
|
||||
"upload": "⤒", # Upload arrow
|
||||
# UI elements
|
||||
"clock": "◷", # Clock symbol
|
||||
"search": "⌕", # Search symbol
|
||||
"data": "≡", # Three lines
|
||||
"doi": "∾", # Link symbol
|
||||
"total": "∑", # Sum symbol
|
||||
}
|
||||
|
||||
# Alternative emoji-based icons for better visibility in some terminals
|
||||
EMOJI_ICONS = {
|
||||
"success": "✅",
|
||||
"error": "❌",
|
||||
"warning": "⚠️",
|
||||
"info": "ℹ️",
|
||||
"processing": "⚙️",
|
||||
"upload": "📤",
|
||||
"save": "💾",
|
||||
}
|
||||
|
||||
# Default icon set preference
|
||||
DEFAULT_ICONS = ICONS
|
|
@ -16,6 +16,7 @@ from rich.progress import Progress, TaskID
|
|||
from ..api.client import APIClient
|
||||
from ..api.processors import AbstractProcessor, LicenseProcessor
|
||||
from ..core.config import Config
|
||||
from ..core.constants import ICONS
|
||||
from ..core.metadata_fields import (
|
||||
CompoundMetadataField,
|
||||
ControlledVocabularyMetadataField,
|
||||
|
@ -41,17 +42,6 @@ class MetadataProcessor:
|
|||
building metadata blocks, and optionally uploading the dataset.
|
||||
"""
|
||||
|
||||
# Icons for console output - TODO: should be moved to a constants module
|
||||
ICONS = {
|
||||
"processing": "⚙️",
|
||||
"success": "✅",
|
||||
"error": "❌",
|
||||
"warning": "⚠️",
|
||||
"info": "ℹ️",
|
||||
"upload": "📤",
|
||||
"save": "💾",
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
doi: str,
|
||||
|
@ -131,7 +121,7 @@ class MetadataProcessor:
|
|||
dict[str, Any]: The constructed metadata dictionary.
|
||||
"""
|
||||
self.console.print(
|
||||
f"{self.ICONS['processing']} Processing DOI: {self.doi}", style="info"
|
||||
f"{ICONS['processing']} Processing DOI: {self.doi}", style="info"
|
||||
)
|
||||
|
||||
data = self._fetch_data()
|
||||
|
@ -148,7 +138,7 @@ class MetadataProcessor:
|
|||
self._update_progress()
|
||||
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['success']} Successfully processed: {self.doi}\n",
|
||||
f"\n{ICONS['success']} Successfully processed: {self.doi}\n",
|
||||
style="success",
|
||||
)
|
||||
return metadata
|
||||
|
@ -177,14 +167,14 @@ class MetadataProcessor:
|
|||
|
||||
if response is None or response.status_code != 201:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['error']} Failed to upload to Dataverse: {url}",
|
||||
f"\n{ICONS['error']} Failed to upload to Dataverse: {url}",
|
||||
style="error",
|
||||
)
|
||||
raise ValueError(f"Failed to upload to Dataverse: {url}")
|
||||
else:
|
||||
perma = response.json().get("data", {}).get("persistentId", "")
|
||||
self.console.print(
|
||||
f"{self.ICONS['upload']} Dataset uploaded to: {config.DATAVERSE['dataverse']} with ID {perma}",
|
||||
f"{ICONS['upload']} Dataset uploaded to: {config.DATAVERSE['dataverse']} with ID {perma}",
|
||||
style="info",
|
||||
)
|
||||
|
||||
|
@ -205,7 +195,7 @@ class MetadataProcessor:
|
|||
|
||||
if response is None or response.status_code != 200:
|
||||
self.console.print(
|
||||
f"\n{self.ICONS['error']} Failed to fetch data for DOI: {self.doi}",
|
||||
f"\n{ICONS['error']} Failed to fetch data for DOI: {self.doi}",
|
||||
style="error",
|
||||
)
|
||||
raise ValueError(f"Failed to fetch data for DOI: {self.doi}")
|
||||
|
@ -238,7 +228,7 @@ class MetadataProcessor:
|
|||
|
||||
if not corresponding_authors:
|
||||
self.console.print(
|
||||
f"{self.ICONS['warning']} No corresponding authors explicitly declared; PIs are used as a fallback!",
|
||||
f"{ICONS['warning']} No corresponding authors explicitly declared; PIs are used as a fallback!",
|
||||
style="warning",
|
||||
)
|
||||
pis = self._get_involved_pis(data)
|
||||
|
@ -371,7 +361,7 @@ class MetadataProcessor:
|
|||
return f"<p>This {doc_type} was published on {publication_date} in <i>{journal}</i></p>"
|
||||
|
||||
self.console.print(
|
||||
f"{self.ICONS['warning']} No abstract header added, missing information (journal, publication date and/or document type)",
|
||||
f"{ICONS['warning']} No abstract header added, missing information (journal, publication date and/or document type)",
|
||||
style="warning",
|
||||
)
|
||||
return ""
|
||||
|
@ -461,12 +451,12 @@ class MetadataProcessor:
|
|||
metadata, f, indent=4, ensure_ascii=False, cls=CustomEncoder
|
||||
)
|
||||
self.console.print(
|
||||
f"{self.ICONS['save']} Metadata saved in: {self.output_path}",
|
||||
f"{ICONS['save']} Metadata saved in: {self.output_path}",
|
||||
style="info",
|
||||
)
|
||||
except Exception as e:
|
||||
self.console.print(
|
||||
f"{self.ICONS['error']} Error saving metadata: {str(e)}\n",
|
||||
f"{ICONS['error']} Error saving metadata: {str(e)}\n",
|
||||
style="error",
|
||||
)
|
||||
raise
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue