ebird-api-data 0.1.0__tar.gz → 0.1.1__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.
Files changed (39) hide show
  1. ebird_api_data-0.1.1/.gitignore +31 -0
  2. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/PKG-INFO +6 -27
  3. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/pyproject.toml +13 -10
  4. ebird_api_data-0.1.1/src/ebird/api/data/__init__.py +1 -0
  5. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/admin.py +4 -12
  6. ebird_api_data-0.1.1/src/ebird/api/data/locale/en/LC_MESSAGES/django.mo +0 -0
  7. ebird_api_data-0.1.1/src/ebird/api/data/locale/en/LC_MESSAGES/django.po +676 -0
  8. ebird_api_data-0.1.1/src/ebird/api/data/templates/admin/data/species/change_list_object_tools.html +13 -0
  9. ebird_api_data-0.1.1/src/ebird/api/data/templates/admin/data/species/fetch_species.html +52 -0
  10. ebird_api_data-0.1.1/src/ebird/api/data/templates/data/widgets/translation_field.html +10 -0
  11. ebird_api_data-0.1.0/setup.cfg +0 -4
  12. ebird_api_data-0.1.0/src/ebird/api/data/__init__.py +0 -1
  13. ebird_api_data-0.1.0/src/ebird_api_data.egg-info/PKG-INFO +0 -206
  14. ebird_api_data-0.1.0/src/ebird_api_data.egg-info/SOURCES.txt +0 -30
  15. ebird_api_data-0.1.0/src/ebird_api_data.egg-info/dependency_links.txt +0 -1
  16. ebird_api_data-0.1.0/src/ebird_api_data.egg-info/requires.txt +0 -5
  17. ebird_api_data-0.1.0/src/ebird_api_data.egg-info/top_level.txt +0 -1
  18. ebird_api_data-0.1.0/tests/test_loader.py +0 -26
  19. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/LICENSE +0 -0
  20. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/README.rst +0 -0
  21. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/apps.py +0 -0
  22. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/fields.py +0 -0
  23. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/loaders.py +0 -0
  24. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/management/__init__.py +0 -0
  25. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/management/commands/__init__.py +0 -0
  26. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/management/commands/add_checklists.py +0 -0
  27. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/migrations/0001_initial.py +0 -0
  28. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/migrations/__init__.py +0 -0
  29. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/__init__.py +0 -0
  30. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/checklist.py +0 -0
  31. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/country.py +0 -0
  32. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/county.py +0 -0
  33. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/filter.py +0 -0
  34. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/location.py +0 -0
  35. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/observation.py +0 -0
  36. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/observer.py +0 -0
  37. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/species.py +0 -0
  38. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/models/state.py +0 -0
  39. {ebird_api_data-0.1.0 → ebird_api_data-0.1.1}/src/ebird/api/data/widgets.py +0 -0
@@ -0,0 +1,31 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[co]
4
+ *.egg*
5
+
6
+ # Editor temp files
7
+ *~
8
+
9
+ # Ignore dot files except those required for the project
10
+ .*
11
+ !.editorconfig
12
+ !.env.example
13
+ !.envrc
14
+ !.gitignore
15
+ !.gitkeep
16
+ !.pre-commit-config.yaml
17
+ !.readthedocs.yaml
18
+
19
+ # data
20
+ *.sqlite3
21
+ *.csv
22
+
23
+ !ebird_basic_dataset_sample.csv
24
+ !MyEBirdData.csv
25
+
26
+ #docs
27
+ _build/
28
+
29
+ # directories
30
+ build/
31
+ logs/
@@ -1,39 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ebird-api-data
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: eBird API Data is a reusable Django app for loading data from eBird into a database.
5
5
  Author-email: Stuart MacKay <smackay@flagstonesoftware.com>
6
- License: The MIT License (MIT)
7
-
8
- Copyright (c) 2025 Stuart MacKay
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
-
28
- Keywords: checklists,observations,species,Django,eBird,models
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: Django,checklists,eBird,models,observations,species
29
9
  Classifier: Development Status :: 5 - Production/Stable
30
- Classifier: Intended Audience :: Science/Research
31
10
  Classifier: Framework :: Django
32
11
  Classifier: Framework :: Django :: 4.2
33
12
  Classifier: Framework :: Django :: 5.0
34
13
  Classifier: Framework :: Django :: 5.1
35
14
  Classifier: Framework :: Django :: 5.2
36
- Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Intended Audience :: Science/Research
37
16
  Classifier: Natural Language :: English
38
17
  Classifier: Programming Language :: Python :: 3.10
39
18
  Classifier: Programming Language :: Python :: 3.11
@@ -42,12 +21,12 @@ Classifier: Programming Language :: Python :: 3.13
42
21
  Classifier: Topic :: Scientific/Engineering
43
22
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
44
23
  Requires-Python: >=3.10
45
- Description-Content-Type: text/x-rst
46
24
  Requires-Dist: beautifulsoup4>=4.13.3
47
25
  Requires-Dist: django>=4.2
48
26
  Requires-Dist: ebird-api-requests>=4.0.1
49
27
  Requires-Dist: ebird-codes>=0.0.2
50
28
  Requires-Dist: lxml>=6.0.0
29
+ Description-Content-Type: text/x-rst
51
30
 
52
31
  eBird API Data
53
32
  ==============
@@ -1,13 +1,10 @@
1
- [build-system]
2
- build-backend = "setuptools.build_meta"
3
- requires = ["setuptools >= 61.0"]
4
-
5
1
  [project]
6
2
  name = "ebird-api-data"
7
- version = "0.1.0"
3
+ version = "0.1.1"
8
4
  description = "eBird API Data is a reusable Django app for loading data from eBird into a database."
9
5
  keywords = ["checklists", "observations", "species", "Django", "eBird", "models"]
10
- license = { file = "LICENSE" }
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
11
8
  authors = [
12
9
  {name = "Stuart MacKay", email = "smackay@flagstonesoftware.com"},
13
10
  ]
@@ -28,7 +25,6 @@ classifiers = [
28
25
  "Framework :: Django :: 5.0",
29
26
  "Framework :: Django :: 5.1",
30
27
  "Framework :: Django :: 5.2",
31
- "License :: OSI Approved :: MIT License",
32
28
  "Natural Language :: English",
33
29
  "Programming Language :: Python :: 3.10",
34
30
  "Programming Language :: Python :: 3.11",
@@ -38,8 +34,15 @@ classifiers = [
38
34
  "Topic :: Scientific/Engineering :: Information Analysis",
39
35
  ]
40
36
 
41
- [tool.setuptools]
42
- license-files = []
37
+ [build-system]
38
+ requires = ["hatchling"]
39
+ build-backend = "hatchling.build"
40
+
41
+ [tool.hatch.build.targets.sdist]
42
+ only-include=["src"]
43
+
44
+ [tool.hatch.build.targets.wheel]
45
+ packages=["src/ebird"]
43
46
 
44
47
  [tool.uv]
45
48
  dev-dependencies = [
@@ -61,7 +64,7 @@ dev-dependencies = [
61
64
  ]
62
65
 
63
66
  [tool.bumpversion]
64
- current_version = "0.1.0"
67
+ current_version = "0.1.1"
65
68
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
66
69
  serialize = ["{major}.{minor}.{patch}"]
67
70
  ignore_missing_version = false
@@ -0,0 +1 @@
1
+ __version__ = "0.1.1"
@@ -142,7 +142,7 @@ class CountyAdmin(admin.ModelAdmin):
142
142
 
143
143
  @admin.register(models.Location)
144
144
  class LocationAdmin(admin.ModelAdmin):
145
- list_display = ("identifier", "names", "county", "state", "country")
145
+ list_display = ("identifier", "name", "county", "state", "country")
146
146
  list_select_related = ("country", "county", "state")
147
147
  ordering = ("-identifier",)
148
148
  search_fields = (
@@ -154,13 +154,9 @@ class LocationAdmin(admin.ModelAdmin):
154
154
  )
155
155
  readonly_fields = ("identifier",)
156
156
 
157
- @admin.display(description=_("Name / Byname"))
158
- def names(self, obj):
159
- return format_html("%s<br/>%s" % (obj.name, obj.byname))
160
-
161
157
  def formfield_for_dbfield(self, db_field, request, **kwargs):
162
158
  field = super().formfield_for_dbfield(db_field, request, **kwargs)
163
- if db_field.name == "byname":
159
+ if db_field.name == "original":
164
160
  field.widget = TextInput(attrs={"class": "vLargeTextField"})
165
161
  elif db_field.name == "name":
166
162
  field.widget = TextInput(attrs={"class": "vLargeTextField"})
@@ -271,19 +267,15 @@ class ObservationAdmin(admin.ModelAdmin):
271
267
 
272
268
  @admin.register(models.Observer)
273
269
  class ObserverAdmin(admin.ModelAdmin):
274
- list_display = ("names", "identifier", "multiple", "enabled")
270
+ list_display = ("name", "identifier", "multiple", "enabled")
275
271
  ordering = ("name",)
276
272
  search_fields = ("name", "identifier")
277
273
  list_filter = ("multiple", "enabled")
278
274
  form = ObservationForm
279
275
 
280
- @admin.display(description=_("Name / Byname"))
281
- def names(self, obj):
282
- return format_html("%s<br/>%s" % (obj.name, obj.byname))
283
-
284
276
  def formfield_for_dbfield(self, db_field, request, **kwargs):
285
277
  field = super().formfield_for_dbfield(db_field, request, **kwargs)
286
- if db_field.name == "byname":
278
+ if db_field.name == "original":
287
279
  field.widget = TextInput(attrs={"class": "vTextField"})
288
280
  elif db_field.name == "name":
289
281
  field.widget = TextInput(attrs={"class": "vTextField"})
@@ -0,0 +1,676 @@
1
+ # SOME DESCRIPTIVE TITLE.
2
+ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
+ # This file is distributed under the same license as the PACKAGE package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PACKAGE VERSION\n"
10
+ "Report-Msgid-Bugs-To: \n"
11
+ "POT-Creation-Date: 2025-07-10 14:08+0000\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "Language: \n"
16
+ "MIME-Version: 1.0\n"
17
+ "Content-Type: text/plain; charset=UTF-8\n"
18
+ "Content-Transfer-Encoding: 8bit\n"
19
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
20
+ #: admin.py:26
21
+ msgid "Observation"
22
+ msgstr ""
23
+
24
+ #: admin.py:31
25
+ msgid "Common name"
26
+ msgstr ""
27
+
28
+ #: admin.py:35
29
+ msgid "Scientific name"
30
+ msgstr ""
31
+
32
+ #: admin.py:157 admin.py:280
33
+ msgid "Name / Byname"
34
+ msgstr ""
35
+
36
+ #: admin.py:248 models/species.py:16
37
+ msgid "Species"
38
+ msgstr ""
39
+
40
+ #: admin.py:297
41
+ msgid "The eBird code for the species, e.g. cangoo, for Canada Goose."
42
+ msgstr ""
43
+
44
+ #: apps.py:8 models/checklist.py:168 models/location.py:143
45
+ #: models/observation.py:167 models/observer.py:38 models/species.py:86
46
+ msgid "Data"
47
+ msgstr ""
48
+
49
+ #: models/checklist.py:7 models/observation.py:41
50
+ msgid "checklist"
51
+ msgstr ""
52
+
53
+ #: models/checklist.py:8
54
+ msgid "checklists"
55
+ msgstr ""
56
+
57
+ #: models/checklist.py:13
58
+ msgid "The date and time the checklist was added to eBird."
59
+ msgstr ""
60
+
61
+ #: models/checklist.py:14
62
+ msgid "created"
63
+ msgstr ""
64
+
65
+ #: models/checklist.py:20 models/observation.py:22
66
+ msgid "The date and time the eBird checklist was last edited."
67
+ msgstr ""
68
+
69
+ #: models/checklist.py:21 models/observation.py:23
70
+ msgid "edited"
71
+ msgstr ""
72
+
73
+ #: models/checklist.py:25
74
+ msgid "Is the checklist published?"
75
+ msgstr ""
76
+
77
+ #: models/checklist.py:26 models/observation.py:28
78
+ msgid "published"
79
+ msgstr ""
80
+
81
+ #: models/checklist.py:31 models/location.py:69 models/observation.py:33
82
+ #: models/observer.py:11
83
+ msgid "identifier"
84
+ msgstr ""
85
+
86
+ #: models/checklist.py:32
87
+ msgid "The unique identifier for the checklist."
88
+ msgstr ""
89
+
90
+ #: models/checklist.py:39 models/country.py:7 models/location.py:87
91
+ #: models/observation.py:65
92
+ msgid "country"
93
+ msgstr ""
94
+
95
+ #: models/checklist.py:40
96
+ msgid "The country where the checklist was made."
97
+ msgstr ""
98
+
99
+ #: models/checklist.py:47 models/location.py:95 models/observation.py:73
100
+ #: models/state.py:7
101
+ msgid "state"
102
+ msgstr ""
103
+
104
+ #: models/checklist.py:48
105
+ msgid "The state where the checklist was made."
106
+ msgstr ""
107
+
108
+ #: models/checklist.py:57 models/county.py:7 models/location.py:105
109
+ #: models/observation.py:83
110
+ msgid "county"
111
+ msgstr ""
112
+
113
+ #: models/checklist.py:58
114
+ msgid "The county where the checklist was made."
115
+ msgstr ""
116
+
117
+ #: models/checklist.py:65 models/filter.py:39 models/location.py:64
118
+ #: models/observation.py:91
119
+ msgid "location"
120
+ msgstr ""
121
+
122
+ #: models/checklist.py:66
123
+ msgid "The location where checklist was made."
124
+ msgstr ""
125
+
126
+ #: models/checklist.py:73 models/observation.py:57 models/observer.py:7
127
+ msgid "observer"
128
+ msgstr ""
129
+
130
+ #: models/checklist.py:74
131
+ msgid "The person who submitted the checklist."
132
+ msgstr ""
133
+
134
+ #: models/checklist.py:80
135
+ msgid "observer count"
136
+ msgstr ""
137
+
138
+ #: models/checklist.py:81
139
+ msgid "The total number of observers."
140
+ msgstr ""
141
+
142
+ #: models/checklist.py:87
143
+ msgid "species count"
144
+ msgstr ""
145
+
146
+ #: models/checklist.py:88
147
+ msgid "The number of species reported."
148
+ msgstr ""
149
+
150
+ #: models/checklist.py:93 models/observation.py:97
151
+ msgid "date"
152
+ msgstr ""
153
+
154
+ #: models/checklist.py:94
155
+ msgid "The date the checklist was started."
156
+ msgstr ""
157
+
158
+ #: models/checklist.py:100 models/observation.py:104
159
+ msgid "time"
160
+ msgstr ""
161
+
162
+ #: models/checklist.py:101
163
+ msgid "The time the checklist was started."
164
+ msgstr ""
165
+
166
+ #: models/checklist.py:108 models/observation.py:112
167
+ msgid "date & time"
168
+ msgstr ""
169
+
170
+ #: models/checklist.py:109
171
+ msgid "The date and time the checklist was started."
172
+ msgstr ""
173
+
174
+ #: models/checklist.py:114
175
+ msgid "protocol code"
176
+ msgstr ""
177
+
178
+ #: models/checklist.py:115
179
+ msgid "The code used to identify the protocol."
180
+ msgstr ""
181
+
182
+ #: models/checklist.py:120
183
+ msgid "project code"
184
+ msgstr ""
185
+
186
+ #: models/checklist.py:121
187
+ msgid "The code used to identify the project (portal)."
188
+ msgstr ""
189
+
190
+ #: models/checklist.py:127
191
+ msgid "duration"
192
+ msgstr ""
193
+
194
+ #: models/checklist.py:128
195
+ msgid "The number of minutes spent counting."
196
+ msgstr ""
197
+
198
+ #: models/checklist.py:136
199
+ msgid "distance"
200
+ msgstr ""
201
+
202
+ #: models/checklist.py:137
203
+ msgid "The distance, in metres, covered while travelling."
204
+ msgstr ""
205
+
206
+ #: models/checklist.py:145
207
+ msgid "area"
208
+ msgstr ""
209
+
210
+ #: models/checklist.py:146
211
+ msgid "The area covered, in hectares."
212
+ msgstr ""
213
+
214
+ #: models/checklist.py:151
215
+ msgid "complete"
216
+ msgstr ""
217
+
218
+ #: models/checklist.py:152
219
+ msgid "All species seen are reported."
220
+ msgstr ""
221
+
222
+ #: models/checklist.py:157 models/observation.py:156
223
+ msgid "comments"
224
+ msgstr ""
225
+
226
+ #: models/checklist.py:158
227
+ msgid "Any comments about the checklist."
228
+ msgstr ""
229
+
230
+ #: models/checklist.py:163 models/location.py:131
231
+ msgid "url"
232
+ msgstr ""
233
+
234
+ #: models/checklist.py:164
235
+ msgid "URL where the original checklist can be viewed."
236
+ msgstr ""
237
+
238
+ #: models/checklist.py:169
239
+ msgid "Data describing a Checklist."
240
+ msgstr ""
241
+
242
+ #: models/country.py:8
243
+ msgid "countries"
244
+ msgstr ""
245
+
246
+ #: models/country.py:13 models/county.py:13 models/state.py:13
247
+ msgid "code"
248
+ msgstr ""
249
+
250
+ #: models/country.py:14
251
+ msgid "The code used to identify the country."
252
+ msgstr ""
253
+
254
+ #: models/country.py:18 models/county.py:18 models/filter.py:22
255
+ #: models/location.py:79 models/observer.py:16 models/state.py:18
256
+ msgid "name"
257
+ msgstr ""
258
+
259
+ #: models/country.py:18
260
+ msgid "The name of the country."
261
+ msgstr ""
262
+
263
+ #: models/country.py:22 models/county.py:22 models/state.py:22
264
+ msgid "place"
265
+ msgstr ""
266
+
267
+ #: models/country.py:22
268
+ msgid "The hierarchical name of the country."
269
+ msgstr ""
270
+
271
+ #: models/county.py:8
272
+ msgid "counties"
273
+ msgstr ""
274
+
275
+ #: models/county.py:14
276
+ msgid "The code used to identify the county."
277
+ msgstr ""
278
+
279
+ #: models/county.py:18
280
+ msgid "The name of the county."
281
+ msgstr ""
282
+
283
+ #: models/county.py:22
284
+ msgid "The hierarchical name of the county."
285
+ msgstr ""
286
+
287
+ #: models/filter.py:13
288
+ msgid "filter"
289
+ msgstr ""
290
+
291
+ #: models/filter.py:14
292
+ msgid "filters"
293
+ msgstr ""
294
+
295
+ #: models/filter.py:17
296
+ msgid "Is the filter active?"
297
+ msgstr ""
298
+
299
+ #: models/filter.py:18
300
+ msgid "enabled"
301
+ msgstr ""
302
+
303
+ #: models/filter.py:22
304
+ msgid "The name of the filter."
305
+ msgstr ""
306
+
307
+ #: models/filter.py:29 models/observation.py:49 models/species.py:22
308
+ #: models/species.py:23
309
+ msgid "species"
310
+ msgstr ""
311
+
312
+ #: models/filter.py:30
313
+ msgid "The species used to find matching Observations."
314
+ msgstr ""
315
+
316
+ #: models/filter.py:40
317
+ msgid "The location used to find matching Observations."
318
+ msgstr ""
319
+
320
+ #: models/filter.py:47
321
+ msgid "update species"
322
+ msgstr ""
323
+
324
+ #: models/filter.py:48
325
+ msgid "Matching Observations are updated to this species."
326
+ msgstr ""
327
+
328
+ #: models/location.py:65
329
+ msgid "locations"
330
+ msgstr ""
331
+
332
+ #: models/location.py:70
333
+ msgid "The unique identifier for the location."
334
+ msgstr ""
335
+
336
+ #: models/location.py:74 models/observer.py:21
337
+ msgid "original name"
338
+ msgstr ""
339
+
340
+ #: models/location.py:75
341
+ msgid "The original name of the location from eBird."
342
+ msgstr ""
343
+
344
+ #: models/location.py:80
345
+ msgid "The display name of the location."
346
+ msgstr ""
347
+
348
+ #: models/location.py:88
349
+ msgid "The country for the location."
350
+ msgstr ""
351
+
352
+ #: models/location.py:96
353
+ msgid "The state for the location."
354
+ msgstr ""
355
+
356
+ #: models/location.py:106
357
+ msgid "The county for the location."
358
+ msgstr ""
359
+
360
+ #: models/location.py:114
361
+ msgid "latitude"
362
+ msgstr ""
363
+
364
+ #: models/location.py:115
365
+ msgid "The decimal latitude of the location, relative to the equator."
366
+ msgstr ""
367
+
368
+ #: models/location.py:123
369
+ msgid "longitude"
370
+ msgstr ""
371
+
372
+ #: models/location.py:125
373
+ msgid "The decimal longitude of the location, relative to the prime meridian."
374
+ msgstr ""
375
+
376
+ #: models/location.py:132
377
+ msgid "URL of the location page on eBird."
378
+ msgstr ""
379
+
380
+ #: models/location.py:138
381
+ msgid "is hotspot"
382
+ msgstr ""
383
+
384
+ #: models/location.py:139
385
+ msgid "Is the location a hotspot."
386
+ msgstr ""
387
+
388
+ #: models/location.py:144
389
+ msgid "Data describing a Location."
390
+ msgstr ""
391
+
392
+ #: models/observation.py:16
393
+ msgid "observation"
394
+ msgstr ""
395
+
396
+ #: models/observation.py:17
397
+ msgid "observations"
398
+ msgstr ""
399
+
400
+ #: models/observation.py:27
401
+ msgid "Is the observation published?"
402
+ msgstr ""
403
+
404
+ #: models/observation.py:34
405
+ msgid "A global unique identifier for the observation."
406
+ msgstr ""
407
+
408
+ #: models/observation.py:42
409
+ msgid "The checklist this observation belongs to."
410
+ msgstr ""
411
+
412
+ #: models/observation.py:50
413
+ msgid "The identified species."
414
+ msgstr ""
415
+
416
+ #: models/observation.py:58
417
+ msgid "The person who made the observation."
418
+ msgstr ""
419
+
420
+ #: models/observation.py:66
421
+ msgid "The country where the observation was made."
422
+ msgstr ""
423
+
424
+ #: models/observation.py:74
425
+ msgid "The state where the observation was made."
426
+ msgstr ""
427
+
428
+ #: models/observation.py:84
429
+ msgid "The county where the observation was made."
430
+ msgstr ""
431
+
432
+ #: models/observation.py:92
433
+ msgid "The location where the observation was made."
434
+ msgstr ""
435
+
436
+ #: models/observation.py:98
437
+ msgid "The date the observation was made."
438
+ msgstr ""
439
+
440
+ #: models/observation.py:105
441
+ msgid "The time the observation was made."
442
+ msgstr ""
443
+
444
+ #: models/observation.py:113
445
+ msgid "The date and time the observation was made."
446
+ msgstr ""
447
+
448
+ #: models/observation.py:118
449
+ msgid "count"
450
+ msgstr ""
451
+
452
+ #: models/observation.py:119
453
+ msgid "The number of birds seen."
454
+ msgstr ""
455
+
456
+ #: models/observation.py:124
457
+ msgid "has audio"
458
+ msgstr ""
459
+
460
+ #: models/observation.py:125
461
+ msgid "Have audio recordings been uploaded to the Macaulay library."
462
+ msgstr ""
463
+
464
+ #: models/observation.py:130
465
+ msgid "has photos"
466
+ msgstr ""
467
+
468
+ #: models/observation.py:131
469
+ msgid "Have photos been uploaded to the Macaulay library."
470
+ msgstr ""
471
+
472
+ #: models/observation.py:136
473
+ msgid "has video"
474
+ msgstr ""
475
+
476
+ #: models/observation.py:137
477
+ msgid "Have video recordings been uploaded to the Macaulay library."
478
+ msgstr ""
479
+
480
+ #: models/observation.py:142
481
+ msgid "Approved"
482
+ msgstr ""
483
+
484
+ #: models/observation.py:143
485
+ msgid "Has the observation been accepted."
486
+ msgstr ""
487
+
488
+ #: models/observation.py:148
489
+ msgid "Reason"
490
+ msgstr ""
491
+
492
+ #: models/observation.py:150
493
+ msgid "The reason given for the observation to be marked as not approved."
494
+ msgstr ""
495
+
496
+ #: models/observation.py:157
497
+ msgid "Any comments about the observation."
498
+ msgstr ""
499
+
500
+ #: models/observation.py:162
501
+ msgid "URN"
502
+ msgstr ""
503
+
504
+ #: models/observation.py:163
505
+ msgid "The globally unique identifier for the observation."
506
+ msgstr ""
507
+
508
+ #: models/observation.py:168
509
+ msgid "Data describing an Observation."
510
+ msgstr ""
511
+
512
+ #: models/observer.py:8
513
+ msgid "observers"
514
+ msgstr ""
515
+
516
+ #: models/observer.py:12
517
+ msgid "The code for the person submitted the checklist."
518
+ msgstr ""
519
+
520
+ #: models/observer.py:17
521
+ msgid "The display name of the observer."
522
+ msgstr ""
523
+
524
+ #: models/observer.py:22
525
+ msgid "The original name of the observer from eBird."
526
+ msgstr ""
527
+
528
+ #: models/observer.py:27
529
+ msgid "Multiple accounts"
530
+ msgstr ""
531
+
532
+ #: models/observer.py:28
533
+ msgid "Is the name used by more than one eBird account."
534
+ msgstr ""
535
+
536
+ #: models/observer.py:33
537
+ msgid "Enabled"
538
+ msgstr ""
539
+
540
+ #: models/observer.py:34
541
+ msgid "Load checklists from the eBird observer."
542
+ msgstr ""
543
+
544
+ #: models/observer.py:39
545
+ msgid "Data describing an Observer."
546
+ msgstr ""
547
+
548
+ #: models/species.py:15
549
+ msgid "All categories"
550
+ msgstr ""
551
+
552
+ #: models/species.py:17
553
+ msgid "Subspecies"
554
+ msgstr ""
555
+
556
+ #: models/species.py:18
557
+ msgid "Domestic"
558
+ msgstr ""
559
+
560
+ #: models/species.py:19
561
+ msgid "Hybrid"
562
+ msgstr ""
563
+
564
+ #: models/species.py:28
565
+ msgid "taxonomy order"
566
+ msgstr ""
567
+
568
+ #: models/species.py:29
569
+ msgid "The position in the eBird/Clements taxonomic order."
570
+ msgstr ""
571
+
572
+ #: models/species.py:34
573
+ msgid "order"
574
+ msgstr ""
575
+
576
+ #: models/species.py:36
577
+ msgid "The order, e.g. Struthioniformes, from the eBird/Clements taxonomy."
578
+ msgstr ""
579
+
580
+ #: models/species.py:43
581
+ msgid "category"
582
+ msgstr ""
583
+
584
+ #: models/species.py:44
585
+ msgid "The category from the eBird/Clements taxonomy."
586
+ msgstr ""
587
+
588
+ #: models/species.py:49
589
+ msgid "species code"
590
+ msgstr ""
591
+
592
+ #: models/species.py:50
593
+ msgid "The species code, e.g. ostric2, used in the eBird API."
594
+ msgstr ""
595
+
596
+ #: models/species.py:55
597
+ msgid "family code"
598
+ msgstr ""
599
+
600
+ #: models/species.py:56
601
+ msgid "The family code, e.g. struth1, used in the eBird API."
602
+ msgstr ""
603
+
604
+ #: models/species.py:60
605
+ msgid "common name"
606
+ msgstr ""
607
+
608
+ #: models/species.py:61
609
+ msgid "The species common name in the eBird/Clements taxonomy."
610
+ msgstr ""
611
+
612
+ #: models/species.py:65
613
+ msgid "scientific name"
614
+ msgstr ""
615
+
616
+ #: models/species.py:66
617
+ msgid "The species scientific name in the eBird/Clements taxonomy."
618
+ msgstr ""
619
+
620
+ #: models/species.py:71
621
+ msgid "family common name"
622
+ msgstr ""
623
+
624
+ #: models/species.py:73
625
+ msgid "The common name for the species family in the eBird/Clements taxonomy."
626
+ msgstr ""
627
+
628
+ #: models/species.py:79
629
+ msgid "family scientific name"
630
+ msgstr ""
631
+
632
+ #: models/species.py:81
633
+ msgid ""
634
+ "The scientific name for the species family in the eBird/Clements taxonomy."
635
+ msgstr ""
636
+
637
+ #: models/species.py:87
638
+ msgid "Data describing a Species."
639
+ msgstr ""
640
+
641
+ #: models/state.py:8
642
+ msgid "states"
643
+ msgstr ""
644
+
645
+ #: models/state.py:14
646
+ msgid "The code used to identify the state."
647
+ msgstr ""
648
+
649
+ #: models/state.py:18
650
+ msgid "The name of the state."
651
+ msgstr ""
652
+
653
+ #: models/state.py:22
654
+ msgid "The hierarchical name of the state."
655
+ msgstr ""
656
+
657
+ #: templates/admin/data/species/change_list_object_tools.html:8
658
+ #, python-format
659
+ msgid "Load %(name)s"
660
+ msgstr ""
661
+
662
+ #: templates/admin/data/species/fetch_species.html:11
663
+ msgid "Home"
664
+ msgstr ""
665
+
666
+ #: templates/admin/data/species/fetch_species.html:21
667
+ msgid "Fetch Species"
668
+ msgstr ""
669
+
670
+ #: templates/admin/data/species/fetch_species.html:22
671
+ msgid "Add a species from the eBird taxonomy to the Species table."
672
+ msgstr ""
673
+
674
+ #: templates/admin/data/species/fetch_species.html:50
675
+ msgid "Fetch"
676
+ msgstr ""
@@ -0,0 +1,13 @@
1
+ {% extends 'admin/change_list_object_tools.html' %}
2
+ {% load i18n %}
3
+
4
+ {% block object-tools-items %}
5
+ {% if has_add_permission %}
6
+ <li>
7
+ <a href="{{ fetch_species_url }}" class="addlink">
8
+ {% blocktranslate with cl.opts.verbose_name as name %}Load {{ name }}{% endblocktranslate %}
9
+ </a>
10
+ </li>
11
+ {% endif %}
12
+ {{ block.super }}
13
+ {% endblock %}
@@ -0,0 +1,52 @@
1
+ {% extends "admin/base_site.html" %}
2
+ {% load i18n admin_urls admin_urls admin_modify static %}
3
+
4
+ {% block extrastyle %}
5
+ {{ block.super }}
6
+ <link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">
7
+ {% endblock %}
8
+
9
+ {% block breadcrumbs %}
10
+ <div class="breadcrumbs">
11
+ <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
12
+ <span> › </span>
13
+ <a href="{% url 'admin:app_list' app_label='data' %}">Data</a>
14
+ <span> › </span>
15
+ <a href="{% url 'admin:data_species_changelist' %}">Species</a>
16
+ <span> › Fetch</span>
17
+ </div>
18
+ {% endblock %}
19
+
20
+ {% block content %}
21
+ <h1>{% trans "Fetch Species" %}</h1>
22
+ <p>{% blocktranslate %}Add a species from the eBird taxonomy to the Species table.{% endblocktranslate %}</p>
23
+ <form action="" method="post">
24
+ {% csrf_token %}
25
+ <fieldset class="module aligned">
26
+ <div class="form-row">
27
+ <div>
28
+ <div class="flex-container">
29
+ <label for="{{ form.species_code.id_for_label }}" class="form-label">{{ form.species_code.label }}</label>
30
+ <div id="{{ form.species_code.id }}">
31
+ <input id="{{ form.species_code.id_for_label }}"
32
+ type="text"
33
+ name="{{ form.species_code.name }}"
34
+ {% if form.species_code.value != None %}
35
+ value="{{ form.species_code.value|stringformat:'s' }}"
36
+ {% endif %}
37
+ maxlength="{{ form.species_code.field.max_length }}"
38
+ {% if form.species_code.field.required %}required{% endif %}
39
+ class="vTextField">
40
+ {% if form.species_code.help_text %}
41
+ <div>
42
+ <small class="form-text text-muted">{{ form.species_code.help_text }}</small>
43
+ </div>
44
+ {% endif %}
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </fieldset>
50
+ <input type="submit" name="apply" value="{% trans 'Fetch' %}" />
51
+ </form>
52
+ {% endblock %}
@@ -0,0 +1,10 @@
1
+ <div id="{{ widget.attrs.id }}">
2
+ {% for subwidget in widget.subwidgets %}
3
+ <div {% if not forloop.last %}style="margin-bottom: 0.5rem"{% endif %}>
4
+ {% include subwidget.template_name with widget=subwidget %}
5
+ <div class="help" style="margin-left: 0; padding-left: 0">
6
+ <div>{{ subwidget.attrs.locale }}</div>
7
+ </div>
8
+ </div>
9
+ {% endfor %}
10
+ </div>
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
@@ -1 +0,0 @@
1
- __version__ = "0.1.0"
@@ -1,206 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: ebird-api-data
3
- Version: 0.1.0
4
- Summary: eBird API Data is a reusable Django app for loading data from eBird into a database.
5
- Author-email: Stuart MacKay <smackay@flagstonesoftware.com>
6
- License: The MIT License (MIT)
7
-
8
- Copyright (c) 2025 Stuart MacKay
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
-
28
- Keywords: checklists,observations,species,Django,eBird,models
29
- Classifier: Development Status :: 5 - Production/Stable
30
- Classifier: Intended Audience :: Science/Research
31
- Classifier: Framework :: Django
32
- Classifier: Framework :: Django :: 4.2
33
- Classifier: Framework :: Django :: 5.0
34
- Classifier: Framework :: Django :: 5.1
35
- Classifier: Framework :: Django :: 5.2
36
- Classifier: License :: OSI Approved :: MIT License
37
- Classifier: Natural Language :: English
38
- Classifier: Programming Language :: Python :: 3.10
39
- Classifier: Programming Language :: Python :: 3.11
40
- Classifier: Programming Language :: Python :: 3.12
41
- Classifier: Programming Language :: Python :: 3.13
42
- Classifier: Topic :: Scientific/Engineering
43
- Classifier: Topic :: Scientific/Engineering :: Information Analysis
44
- Requires-Python: >=3.10
45
- Description-Content-Type: text/x-rst
46
- Requires-Dist: beautifulsoup4>=4.13.3
47
- Requires-Dist: django>=4.2
48
- Requires-Dist: ebird-api-requests>=4.0.1
49
- Requires-Dist: ebird-codes>=0.0.2
50
- Requires-Dist: lxml>=6.0.0
51
-
52
- eBird API Data
53
- ==============
54
- eBird API Data is a reusable Django app for loading data from eBird into a database.
55
-
56
- Overview
57
- --------
58
- .. overview-start
59
-
60
- The Cornell Laboratory of Ornithology in Ithaca, New York runs the eBird database
61
- which collects observations of birds from all over the world. All the observations
62
- are published on `eBird.org`_, and they also make them available via an `API`_.
63
- This project contains a loader and models to take data from the API and load it into
64
- a database. From there you can analyse the data with python, jupyter notebooks, or
65
- build a web site.
66
-
67
- To get started, you will need to `sign up`_ for an eBird account, if you don't
68
- already have one and `register`_ to get an API key. Make sure you read and
69
- understand the `Terms of use`_, and remember bandwidth and servers cost money,
70
- so don't abuse the service. If you need large numbers of observations, then
71
- sign up to receive the `eBird Basic Dataset`_.
72
-
73
- .. _eBird.org: https://ebird.org
74
- .. _API: https://documenter.getpostman.com/view/664302/S1ENwy59
75
- .. _sign up: https://secure.birds.cornell.edu/identity/account/create
76
- .. _register: https://ebird.org/data/download
77
- .. _Terms of use: https://www.birds.cornell.edu/home/ebird-api-terms-of-use/
78
- .. _eBird Basic Dataset: https://science.ebird.org/en/use-ebird-data/download-ebird-data-products
79
-
80
- .. overview-end
81
-
82
- Install
83
- -------
84
- .. install-start
85
-
86
- You can use either `pip`_ or `uv`_ to download the `package`_ from PyPI and
87
- install it into a virtualenv:
88
-
89
- .. code-block:: console
90
-
91
- pip install ebird-api-data
92
-
93
- or:
94
-
95
- .. code-block:: console
96
-
97
- uv add ebird-api-data
98
-
99
- Update ``INSTALLED_APPS`` in your Django setting:
100
-
101
- .. code-block:: python
102
-
103
- INSTALLED_APPS = [
104
- ...
105
- ebird.api.data
106
- ]
107
-
108
- Finally, run the migrations to create the tables:
109
-
110
- .. code-block:: python
111
-
112
- python manage.py migrate
113
-
114
- .. _pip: https://pip.pypa.io/en/stable/
115
- .. _uv: https://docs.astral.sh/uv/
116
- .. _package: https://pypi.org/project/ebird-api-data/
117
-
118
- .. install-end
119
-
120
- Demo
121
- ----
122
-
123
- .. demo-start
124
-
125
- If you check out the code from the repository there is a fully functioning
126
- Django site. It only contains the admin pages, but that is sufficient for
127
- you to browse the data.
128
-
129
- .. code-block:: console
130
-
131
- git clone git@github.com:StuartMacKay/ebird-api-data.git
132
- cd ebird-api-data
133
-
134
- Create the virtual environment:
135
-
136
- .. code-block:: console
137
-
138
- uv venv
139
-
140
- Activate it:
141
-
142
- .. code-block:: console
143
-
144
- source venv/bin/activate
145
-
146
- Install the requirements:
147
-
148
- .. code-block:: console
149
-
150
- uv sync
151
-
152
- Run the database migrations:
153
-
154
- .. code-block:: console
155
-
156
- python manage.py migrate
157
-
158
- Create a user:
159
-
160
- .. code-block:: console
161
-
162
- python manage.py createsuperuser
163
-
164
- Create a copy of the .env.example file and add your API key:
165
-
166
- .. code-block:: console
167
-
168
- cp .env.example .env
169
-
170
- .. code-block:: console
171
-
172
- EBIRD_API_KEY=<my api key>
173
-
174
- Now, download data from the API:
175
-
176
- .. code-block:: console
177
-
178
- python manage.py add_checklists --days 2 US-NY-109
179
-
180
- This loads all the checklists, submitted in the past two days by birders in
181
- Tompkins County, New York, where the Cornell Lab is based. You can use any
182
- location code used by eBird, whether it's for a country, state/region, or
183
- county. Remember, read the terms of use.
184
-
185
- Run the demo:
186
-
187
- .. code-block:: console
188
-
189
- python manage.py runserver
190
-
191
- Now log into the `Django Admin <http:localhost:8000/admin>` to browse the tables.
192
-
193
- .. demo-end
194
-
195
- Project Information
196
- -------------------
197
-
198
- * Documentation: https://ebird-api-data.readthedocs.io/en/latest/
199
- * Issues: https://github.com/StuartMacKay/ebird-api-data/issues
200
- * Repository: https://github.com/StuartMacKay/ebird-api-data
201
-
202
- The app is tested on Python 3.10+, and officially supports Django 4.2, 5.0 and 5.1.
203
-
204
- eBird API Data is released under the terms of the `MIT`_ license.
205
-
206
- .. _MIT: https://opensource.org/licenses/MIT
@@ -1,30 +0,0 @@
1
- LICENSE
2
- README.rst
3
- pyproject.toml
4
- src/ebird/api/data/__init__.py
5
- src/ebird/api/data/admin.py
6
- src/ebird/api/data/apps.py
7
- src/ebird/api/data/fields.py
8
- src/ebird/api/data/loaders.py
9
- src/ebird/api/data/widgets.py
10
- src/ebird/api/data/management/__init__.py
11
- src/ebird/api/data/management/commands/__init__.py
12
- src/ebird/api/data/management/commands/add_checklists.py
13
- src/ebird/api/data/migrations/0001_initial.py
14
- src/ebird/api/data/migrations/__init__.py
15
- src/ebird/api/data/models/__init__.py
16
- src/ebird/api/data/models/checklist.py
17
- src/ebird/api/data/models/country.py
18
- src/ebird/api/data/models/county.py
19
- src/ebird/api/data/models/filter.py
20
- src/ebird/api/data/models/location.py
21
- src/ebird/api/data/models/observation.py
22
- src/ebird/api/data/models/observer.py
23
- src/ebird/api/data/models/species.py
24
- src/ebird/api/data/models/state.py
25
- src/ebird_api_data.egg-info/PKG-INFO
26
- src/ebird_api_data.egg-info/SOURCES.txt
27
- src/ebird_api_data.egg-info/dependency_links.txt
28
- src/ebird_api_data.egg-info/requires.txt
29
- src/ebird_api_data.egg-info/top_level.txt
30
- tests/test_loader.py
@@ -1,5 +0,0 @@
1
- beautifulsoup4>=4.13.3
2
- django>=4.2
3
- ebird-api-requests>=4.0.1
4
- ebird-codes>=0.0.2
5
- lxml>=6.0.0
@@ -1,26 +0,0 @@
1
- import random
2
-
3
- from django.conf import settings
4
- from django.core.management import call_command
5
-
6
- from ebird.api.requests import get_regions
7
- from faker import Faker
8
-
9
- import pytest
10
-
11
- pytestmark = pytest.mark.django_db
12
-
13
-
14
- @pytest.fixture()
15
- def region():
16
- country = Faker().country_code()
17
- if regions := get_regions(settings.EBIRD_API_KEY, "subnational1", country):
18
- codes = [region["code"] for region in regions]
19
- code = random.choice(codes)
20
- else:
21
- code = country
22
- return code
23
-
24
-
25
- def test_loader(region):
26
- call_command("add_checklists", "--days", 2, region)
File without changes