pyinat / naturtag Goto Github PK
View Code? Open in Web Editor NEWTag your nature photos with iNat taxonomy and observation metadata
Home Page: https://naturtag.readthedocs.io
License: MIT License
Tag your nature photos with iNat taxonomy and observation metadata
Home Page: https://naturtag.readthedocs.io
License: MIT License
The purpose of this will be to take any images with partial metadata (for example, just a taxon ID), and update them with full metadata.
--recursive
optionMost of the necessary pieces are already implemented, they just need to be combined and wrapped in a CLI command.
The CLI should be able to:
This is a more complex/far-off feature idea, but a very useful one. Currently, the app only supports tagging one taxon or observation at a time. These features would make it suitable for processing many at once.
pygments
to highlight metadataQuick notes on new user-observed taxa tab:
GET /observations/species_counts
pyinaturalist
for additional endpoint(s)Goes with #50. I'll need to pick one of the two types of feature:
Both the CLI and GUI could optionally append the taxon name to the updated image(s), like:
$ naturtag -t 792988 IMG_2020_02_02.jpg
Written to IMG_2020_02_02_Dryobates pubescens_(Downy_Woodpecker).jpg
A more advanced feature would be to take a file path template, with metadata fields as placeholders, for example:
~/Observations/{year}/{month}/IMG_{date}_{time}_{taxon.name}_({taxon.preferred_common_name})
For dates, python date format strings could be used.
There are some known issues with KivyMD DataTables as of 0.104.1
. It appears that they will be fixed in the next release, however.
I will probably hold off on the next naturtag release until those fixes are released.
Scenario: an image was tagged previously with enough info to look up an existing taxon and/or observation.
rank=name
formatted keywords or DwC metadataCurrently this only aims to support handling a single taxon or observation at a time. Handling a set of images associated with multiple taxa or observations may be out of scope, or a cool (but complicated) future feature.
Often there can be a large number of GET /taxa
API requests made in a short amount of time. Currently this is done naively by fetching a single taxon record at a time and caching the result, so any subsequent requests for taxon_id=x
will get the cached result. The problem with doing bulk requests instead is that a request for taxon_id=x,y,z
would not result in any subsequent cache hit for taxon_id=x
, taxon_id=x,z
, etc.
So in other words, in the long term, there won't be any redundant requests for a given taxon, but in the short term, naturtag can reach the API rate limit while building up the cache.
There are lots of potential solutions to this:
requests-cache
, manually build and query a local SQLite db of taxon data (just a relevant subset of columns).requests-cache
to create individual cache entries for bulk requests; e.g. a request for taxon_id=x,y,z
will create separate cache entries for taxon_id=x
, taxon_id=y
, taxon_id=z
.This would work by specifying a full scientific name:
naturtag --taxon-name 'Dirona picta'
Performing a fuzzy search (with potentially multiple results) will take a bit more work and can be a separate issue.
This will be a small status bar at the bottom of the screen, used to display I/O progress and status messages.
For easier access when exploring taxa, it would be useful to have a list of recently selected items. Related to #17.
{id: num_views}
The UI should provide a feature to search taxa by name, with autocomplete functionality similar to the iNat web UI.
GET /taxa_autocomplete
API endpointOne of the two following options would be useful:
This option would store all settings, cache, thumbnails, etc. in the application's own directory instead of the system app directory (~\AppData\Local
, ~/.local/
, etc.).
DATA_DIR
Currently the config file is also stored in the data dir, so would need some other way to specify where to look for the initial config file
Again, running under MacOS Mojave command line.
naturtag -t 48978 # seems to run correctly
naturtag -c -t 48978 # gives multiple identical values for common names
naturtag -d -x -t 48978 Dirona_picta.jpg # multiple errors, below. Let me know if I can help.
Directory Thumbnail, entry 0x0201: Data area exceeds data buffer, ignoring it.
Directory Thumbnail, entry 0x0201: Data area exceeds data buffer, ignoring it.
Directory Thumbnail, entry 0x0201: Data area exceeds data buffer, ignoring it.
Directory Thumbnail, entry 0x0201: Data area exceeds data buffer, ignoring it.
Directory Thumbnail, entry 0x0201: Data area exceeds data buffer, ignoring it.
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/bin/naturtag", line 33, in
sys.exit(load_entry_point('naturtag==0.6.0', 'console_scripts', 'naturtag')())
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/core.py", line 829, in call
return self.main(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/decorators.py", line 21, in new_func
return f(get_current_context(), *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/naturtag/cli.py", line 122, in tag
glob_paths(image_paths),
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/naturtag/tagger.py", line 26, in tag_images
all_metadata.append(tag_image(image_path, keywords, dwc_metadata, create_xmp_sidecar))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/naturtag/tagger.py", line 35, in tag_image
metadata.write(create_xmp_sidecar=create_xmp_sidecar)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/naturtag/models/image_metadata.py", line 96, in write
self._write(self.image_path)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/naturtag/models/image_metadata.py", line 112, in _write
img.modify_xmp(self.xmp)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyexiv2/core.py", line 61, in modify_xmp
self.img.modify_xmp(self._dumps(data), encoding)
RuntimeError: XMP Toolkit error 102: Composite nodes can't have values
Failed to encode XMP metadata.
Add the ability to save a selected taxon. Related to #14.
MDListItem
During prototyping/early development, known bugs and other quirks will be listed here instead of in separate issues.
jpg
but not jpeg
, PIL accepts jpeg
but not jpg
generate_thumbnails()
will flip them by default.AsyncImage
?HoverBehavior
?glob
uses os.path.normcase
, which is case-insensitive only on Windows!)In addition to searching by name with autocompletion (issue #4), the UI should provide additional search filters for most of the relevant parameters available in the GET /taxa
API endpoint.
locale
and preferred_place_id
(defined in settings; see issue #13 )Follow-up from #4:
get_images_from_dir
On main image selector screen:
Note: KivyMD's ContextMenu seems to be broken currently. Using kivy-garden.contextmenu instead.
Moving other items to issue #29
A number of methods are possible to improve performance and minimize disk I/O load on the iNaturalist API:
AsyncImage
)GET /taxa
)Currently, only thumbnails are shown for local photos.
When a taxon is selected (either by ID or by future search features), the UI should display basic info about it, including:
For example, if a file is named:
IMG_2020_02_02_Dryobates pubescens.jpg
I tried to install naturtag today 2020-07-21 on Mac OS. with pip. There seems to be some version issue with pyinaturalist that I don't understand. naturtag wants pyinaturalist v. 0.10.0.dev206, but when I run naturtag at the command line I get the following error:
ImportError: cannot import name 'get_observation_species_counts' from 'pyinaturalist.node_api' (/Users/alan/opt/anaconda3/lib/python3.7/site-packages/pyinaturalist/node_api.py)
I looked at various versions and it seems that get_observation_species_counts is not defined in pyinaturalist v. 0.10.0.dev206 but is defined in v. 0.11.0. I'm not a python programmer, and I am relatively clueless, so not sure if this is a bug or user error.
Since there is no DWC response format available for GET /taxa
, we'll just search for a random observation with this taxon ID, strip off the observation metadata, and keep only the taxon metadata.
Looks like a bug in handling the button state. Could be in either kivy or kivymd, but I need to do some more digging before reporting a bug.
This is failing on assert(self in touch.ud)
. If that's failing, that probably means that on_touch_down()
somehow wasn't called before on_touch_up()
.
Traceback (most recent call last):
File "D:/Workspace/naturtag/naturtag/app/app.py", line 288, in <module>
main()
File "D:/Workspace/naturtag/naturtag/app/app.py", line 284, in main
NaturtagApp().run()
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\app.py", line 950, in run
runTouchApp()
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\base.py", line 573, in runTouchApp
EventLoop.mainloop()
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\base.py", line 347, in mainloop
self.idle()
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\base.py", line 391, in idle
self.dispatch_input()
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\base.py", line 342, in dispatch_input
post_dispatch_input(*pop(0))
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\base.py", line 308, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "D:\Workspace\naturtag\venv\lib\site-packages\kivymd\uix\behaviors\ripplebehavior.py", line 245, in on_touch_up
return super().on_touch_up(touch)
File "D:\Workspace\naturtag\venv\lib\site-packages\kivy\uix\behaviors\button.py", line 164, in on_touch_up
assert(self in touch.ud)
AssertionError
It will simplify a lot of common operations if API response JSON were to be wrapped with python models (dataclasses), likely using attrs
.
@mainthread
for steps that need to communicate back to UIThis would use the /taxon_autocomplete
endpoint, with the potential for multiple results. In that case, the CLI should prompt the user with a list of candidates to select.
This will speed up initial browsing of some of the most commonly observed taxa.
Atlas
?The UI should provide a screen to view an image's metadata.
When an observation is selected, the UI should display basic info about it, including:
The UI should provide a Settings page with various options that will persist in a config file in ~/.local
/ %APPDATA%
.
Moving this from #16. Getting occasional TooManyRequestsForUrl
response from iNaturalist API when loading lots of taxon thumbnails. Mainly for children of the currently selected taxon (esp. when listing a large number of species under a genus)
The UI should have the same basic features as the CLI described in #1, plus:
ProcessPoolExecutor
...If possible, the UI should display a taxonomy tree similar to the one shown in the 'Taxonomy' tab on iNaturalist.
There are many possible performance optimizations for this, to avoid making an API call for every click. Pre-fetch and cache ancestor/child taxa records, pre-generate portions of the tree (could use taxon-keyword-gen?), etc. Will need to get further in implementation to determine what's feasible.
Follow-up from #4 and #20 . The taxon search completion is still a little clunky.
Brown mar
|morated stink bugFloatLayout
)A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.