diff --git a/HISTORY.md b/HISTORY.md index b3bb8224..dce26e57 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,7 @@ * Add `validate_token()` function to manually check if an access token is valid * Support rate limits less than one request per second (example: `ClientSession(per_second=0.5)`) * Allow setting lockfile path used for multiprocess rate limiting (example: `ClientSession(lock_path='/tmp/pyinat.lock')`) +* Add support for font-awesome based icons ## 0.19.0 (2023-12-12) diff --git a/pyinaturalist/constants.py b/pyinaturalist/constants.py index 27cc1e4f..be8584e5 100644 --- a/pyinaturalist/constants.py +++ b/pyinaturalist/constants.py @@ -1,4 +1,5 @@ # ruff: noqa: F401 +from dataclasses import dataclass from datetime import date, datetime, timedelta from os.path import abspath, dirname, join from pathlib import Path @@ -8,6 +9,7 @@ from platformdirs import user_data_dir from pyrate_limiter.sqlite_bucket import LOCK_PATH as DEFAULT_LOCK_PATH + # iNaturalist URLs API_V0 = 'https://www.inaturalist.org' API_V1 = 'https://api.inaturalist.org/v1' @@ -86,6 +88,7 @@ 48222: 'Chromista', 47686: 'Protozoa', } + ICONIC_EMOJI = { 0: '❓', 1: '🐾', @@ -102,6 +105,60 @@ 48222: '🟢', 47686: '🦠', } + +COLORS = { + 'blue': '#5778a4', + 'orange': '#e49444', + 'red': '#d1615d', + 'teal': '#85b6b2', + 'green': '#6a9f58', + 'yellow': '#e7ca60', + 'purple': '#a87c9f', + 'pink': '#f1a2a9', + 'brown': '#967662', + 'grey': '#b8b0ac', + 'black': '#000000', +} + + +@dataclass +class FontAwesomeIcon: + prefix: str + name: str + color: str + size: int = 16 + + def __str__(self): + return ( + f'' + ) + + def __repr__(self): + return f'' + + +ICONIC_FONT_AWESOME = { + 0: FontAwesomeIcon('fa-solid', 'fa-question-circle', 'grey'), + 1: FontAwesomeIcon('fa-solid', 'fa-paw', 'black'), + 3: FontAwesomeIcon('fa-solid', 'fa-dove', 'teal'), + 20978: FontAwesomeIcon('fa-solid', 'fa-frog', 'green'), + 26036: FontAwesomeIcon('fa-solid', 'fa-dragon', 'green'), + 40151: FontAwesomeIcon('fa-solid', 'fa-cat', 'orange'), + 47178: FontAwesomeIcon('fa-solid', 'fa-fish', 'blue'), + 47115: FontAwesomeIcon('fa-solid', 'fa-worm', 'pink'), + 47119: FontAwesomeIcon('fa-solid', 'fa-spider', 'black'), + 47158: FontAwesomeIcon('fa-solid', 'fa-mosquito', 'purple'), + 47126: FontAwesomeIcon('fa-solid', 'fa-leaf', 'green'), + 47170: FontAwesomeIcon('fa-solid', 'fa-bacteria', 'brown'), # mushroom + 48222: FontAwesomeIcon('fa-solid', 'fa-bowling-ball', 'green'), + 47686: FontAwesomeIcon('fa-solid', 'fa-disease', 'green'), +} + +assert set(ICONIC_TAXA.keys()) == set(ICONIC_EMOJI.keys()) +assert set(ICONIC_TAXA.keys()) == set(ICONIC_FONT_AWESOME.keys()) + ROOT_TAXON_ID = 48460 # Taxonomic ranks that can be filtered on, and numeric values for comparison diff --git a/pyinaturalist/docs/__init__.py b/pyinaturalist/docs/__init__.py index 2d374970..9bd6a93a 100644 --- a/pyinaturalist/docs/__init__.py +++ b/pyinaturalist/docs/__init__.py @@ -7,6 +7,7 @@ from pyinaturalist.docs.docstrings import ApiDocstring, copy_annotations, copy_docstrings from pyinaturalist.docs.emoji import EMOJI +from pyinaturalist.docs.font_awesome_icons import EXTENDED_FONT_AWESOME_ICONS from pyinaturalist.docs.signatures import ( copy_doc_signature, copy_signatures, diff --git a/pyinaturalist/docs/font_awesome_icons.py b/pyinaturalist/docs/font_awesome_icons.py new file mode 100644 index 00000000..8b8230e3 --- /dev/null +++ b/pyinaturalist/docs/font_awesome_icons.py @@ -0,0 +1,142 @@ +"""Extended list of font-awesome icons to represent taxa""" + +from pyinaturalist.constants import FontAwesomeIcon + +EXTENDED_FONT_AWESOME_ICONS = { + 0: FontAwesomeIcon('fa-solid', 'fa-question-circle', 'grey'), + # Birds + 3: FontAwesomeIcon('fa-solid', 'fa-dove', 'teal'), + # Pheasants, Grouse, and Allies + 574: FontAwesomeIcon('fa-solid', 'fa-feather', 'teal'), + 879: FontAwesomeIcon('fa-solid', 'fa-kiwi-bird', 'brown'), + 71261: FontAwesomeIcon('fa-solid', 'fa-crow', 'black'), + 6888: FontAwesomeIcon('fa-solid', 'fa-kiwi-bird', 'green'), + 1199: FontAwesomeIcon('fa-solid', 'fa-kiwi-bird', 'brown'), + 67569: FontAwesomeIcon('fa-solid', 'fa-kiwi-bird', 'pink'), + 2708: FontAwesomeIcon('fa-solid', 'fa-dove', 'teal'), + 6913: FontAwesomeIcon('fa-solid', 'fa-dove', 'teal'), + 67564: FontAwesomeIcon('fa-solid', 'fa-kiwi-bird', 'blue'), + 19350: FontAwesomeIcon('fa-solid', 'fa-crow', 'brown'), + 18874: FontAwesomeIcon('fa-solid', 'fa-kiwi-bird', 'green'), + # Amphibians + reptiles + 20978: FontAwesomeIcon('fa-solid', 'fa-frog', 'green'), + 26036: FontAwesomeIcon('fa-solid', 'fa-dragon', 'green'), + 26039: FontAwesomeIcon('fa-solid', 'fa-dragon', 'green'), + 39532: FontAwesomeIcon('fa-solid', 'fa-dragon', 'green'), + 85553: FontAwesomeIcon('fa-solid', 'fa-worm', 'green'), + # Mammals + 786045: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 43579: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 846280: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 47144: FontAwesomeIcon('fa-solid', 'fa-dog', 'brown'), + 42048: FontAwesomeIcon('fa-solid', 'fa-dog', 'grey'), + 42054: FontAwesomeIcon('fa-solid', 'fa-dog', 'red'), + 41660: FontAwesomeIcon('fa-solid', 'fa-dog', 'brown'), + 41944: FontAwesomeIcon('fa-solid', 'fa-cat', 'orange'), + 846273: FontAwesomeIcon('fa-solid', 'fa-cat', 'yellow'), + 43328: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 42158: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 42406: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 568826: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 848343: FontAwesomeIcon('fa-solid', 'fa-paw', 'pink'), + 568847: FontAwesomeIcon('fa-solid', 'fa-horse', 'grey'), + 42348: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 846209: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 925150: FontAwesomeIcon('fa-solid', 'fa-horse', 'brown'), + 43691: FontAwesomeIcon('fa-solid', 'fa-horse', 'grey'), + 43698: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 43094: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 45933: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 43791: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 533971: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 40268: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 41636: FontAwesomeIcon('fa-solid', 'fa-paw', 'brown'), + 848319: FontAwesomeIcon('fa-solid', 'fa-paw', 'brown'), + 42981: FontAwesomeIcon('fa-solid', 'fa-paw', 'grey'), + 53537: FontAwesomeIcon('fa-solid', 'fa-paw', 'brown'), + 41770: FontAwesomeIcon('fa-solid', 'fa-paw', 'grey'), + 526556: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + 41871: FontAwesomeIcon('fa-solid', 'fa-otter', 'black'), + 846287: FontAwesomeIcon('fa-solid', 'fa-otter', 'brown'), + # Fish + 47178: FontAwesomeIcon('fa-solid', 'fa-fish', 'blue'), + 47233: FontAwesomeIcon('fa-solid', 'fa-fish-fins', 'blue'), + 47177: FontAwesomeIcon('fa-solid', 'fa-fish', 'blue'), + 372843: FontAwesomeIcon('fa-solid', 'fa-otter', 'blue'), + 152871: FontAwesomeIcon('fa-solid', 'fa-otter', 'blue'), + 41479: FontAwesomeIcon('fa-solid', 'fa-otter', 'blue'), + 47273: FontAwesomeIcon('fa-solid', 'fa-fish-fins', 'blue'), + # Molluscs + 47115: FontAwesomeIcon('fa-solid', 'fa-worm', 'blue'), + 47459: FontAwesomeIcon('fa-solid', 'fa-worm', 'blue'), + 127352: FontAwesomeIcon('fa-solid', 'fa-worm', 'blue'), + # Arthropods + 85493: FontAwesomeIcon('fa-solid', 'fa-shrimp', 'red'), + 144114: FontAwesomeIcon('fa-solid', 'fa-shrimp', 'red'), + 311310: FontAwesomeIcon('fa-solid', 'fa-shrimp', 'red'), + 47119: FontAwesomeIcon('fa-solid', 'fa-spider', 'black'), + 48894: FontAwesomeIcon('fa-solid', 'fa-spider', 'black'), + 172373: FontAwesomeIcon('fa-solid', 'fa-spider', 'black'), + 48900: FontAwesomeIcon('fa-solid', 'fa-spider', 'black'), + 372739: FontAwesomeIcon('fa-solid', 'fa-worm', 'green'), + 144128: FontAwesomeIcon('fa-solid', 'fa-worm', 'green'), + 47822: FontAwesomeIcon('fa-solid', 'fa-mosquito', 'brown'), + 153429: FontAwesomeIcon('fa-solid', 'fa-mosquito', 'brown'), + 81769: FontAwesomeIcon('fa-solid', 'fa-mosquito', 'brown'), + 47651: FontAwesomeIcon('fa-solid', 'fa-locust', 'green'), + 47157: FontAwesomeIcon('fa-solid', 'fa-locust', 'teal'), + 47201: FontAwesomeIcon('fa-solid', 'fa-mosquito', 'yellow'), + 47336: FontAwesomeIcon('fa-solid', 'fa-mosquito', 'yellow'), + 48511: FontAwesomeIcon('fa-solid', 'fa-bug', 'brown'), + 47208: FontAwesomeIcon('fa-solid', 'fa-bug', 'brown'), + 471714: FontAwesomeIcon('fa-solid', 'fa-bugs', 'brown'), + # Plants + 47126: FontAwesomeIcon('fa-solid', 'fa-seedling', 'green'), + 136329: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 47903: FontAwesomeIcon('fa-solid', 'fa-sun-plant-wilt', 'brown'), + 47162: FontAwesomeIcon('fa-solid', 'fa-wheat-awn', 'yellow'), + 121943: FontAwesomeIcon('fa-solid', 'fa-pagelines', 'green'), + 70233: FontAwesomeIcon('fa-solid', 'fa-seedling', 'green'), + 48866: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 544534: FontAwesomeIcon('fa-solid', 'fa-bowling-ball', 'brown'), + 47605: FontAwesomeIcon('fa-solid', 'fa-fan', 'yellow'), + 605446: FontAwesomeIcon('fa-solid', 'fa-fan', 'yellow'), + 47690: FontAwesomeIcon('fa-solid', 'fa-fan', 'pink'), + 48796: FontAwesomeIcon('fa-solid', 'fa-fan', 'pink'), + 47329: FontAwesomeIcon('fa-solid', 'fa-fan', 'pink'), + 47148: FontAwesomeIcon('fa-solid', 'fa-fan', 'red'), + 47727: FontAwesomeIcon('fa-solid', 'fa-canadian-maple-leaf', 'red'), + 53548: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 47853: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 151882: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 50998: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 47567: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 71434: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 47194: FontAwesomeIcon('fa-solid', 'fa-tree', 'green'), + 48699: FontAwesomeIcon('fa-solid', 'fa-carrot', 'orange'), + 47204: FontAwesomeIcon('fa-solid', 'fa-seedling', 'green'), + 71291: FontAwesomeIcon('fa-solid', 'fa-wine-bottle', 'red'), + 48620: FontAwesomeIcon('fa-solid', 'fa-bowling-ball', 'orange'), + 62910: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 50623: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 723302: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 49570: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'yellow'), + 48874: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'green'), + 47351: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 47733: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'green'), + 55849: FontAwesomeIcon('fa-solid', 'fa-pepper-hot', 'grey'), + 48516: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 48517: FontAwesomeIcon('fa-solid', 'fa-pepper-hot', 'red'), + 62848: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 635417: FontAwesomeIcon('fa-solid', 'fa-wheat-awn', 'yellow'), + 55150: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'green'), + 50299: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'red'), + 634914: FontAwesomeIcon('fa-solid', 'fa-apple-whole', 'blue'), + # Other + 1: FontAwesomeIcon('fa-solid', 'fa-paw', 'black'), + 47491: FontAwesomeIcon('fa-solid', 'fa-worm', 'pink'), + 47170: FontAwesomeIcon('fa-solid', 'fa-bacteria', 'brown'), # mushroom + 48222: FontAwesomeIcon('fa-solid', 'fa-bowling-ball', 'green'), + 67333: FontAwesomeIcon('fa-solid', 'fa-bacterium', 'green'), + 131236: FontAwesomeIcon('fa-solid', 'fa-virus', 'red'), +}