localcosmos-app-kit 0.9.18__py3-none-any.whl → 0.10.0__py3-none-any.whl
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.
- app_kit/appbuilder/AppReleaseBuilder.py +111 -53
- app_kit/appbuilder/JSONBuilders/TaxonProfilesJSONBuilder.py +38 -15
- app_kit/appbuilder/JSONBuilders/__pycache__/TaxonProfilesJSONBuilder.cpython-313.pyc +0 -0
- app_kit/appbuilder/TaxonBuilder.py +35 -28
- app_kit/appbuilder/__pycache__/AppReleaseBuilder.cpython-313.pyc +0 -0
- app_kit/appbuilder/__pycache__/TaxonBuilder.cpython-313.pyc +0 -0
- app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/manage_taxon.html +1 -1
- app_kit/features/taxon_profiles/forms.py +12 -37
- app_kit/features/taxon_profiles/models.py +29 -36
- app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/create_taxon_profile.html +1 -1
- app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_form.html +35 -54
- app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_morphotype.html +2 -1
- app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/nature_guide_taxonlist.html +2 -2
- app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/non_nature_guide_taxonlist.html +1 -1
- app_kit/features/taxon_profiles/templates/taxon_profiles/manage_taxon_profile.html +4 -4
- app_kit/features/taxon_profiles/urls.py +3 -0
- app_kit/features/taxon_profiles/views.py +44 -32
- {localcosmos_app_kit-0.9.18.dist-info → localcosmos_app_kit-0.10.0.dist-info}/METADATA +1 -1
- {localcosmos_app_kit-0.9.18.dist-info → localcosmos_app_kit-0.10.0.dist-info}/RECORD +22 -23
- app_kit/tests/TESTS_ROOT/media_for_tests/test/imagestore/31/a6a11b61d65ee19c4c22caa0682288ff.jpg +0 -0
- {localcosmos_app_kit-0.9.18.dist-info → localcosmos_app_kit-0.10.0.dist-info}/WHEEL +0 -0
- {localcosmos_app_kit-0.9.18.dist-info → localcosmos_app_kit-0.10.0.dist-info}/licenses/LICENCE +0 -0
- {localcosmos_app_kit-0.9.18.dist-info → localcosmos_app_kit-0.10.0.dist-info}/top_level.txt +0 -0
|
@@ -1959,6 +1959,63 @@ class AppReleaseBuilder(AppBuilderBase):
|
|
|
1959
1959
|
localized_long_text = self.get_localized_taxonprofile_text(text_dict['longTextKey'], glossarized_locale, app_locale)
|
|
1960
1960
|
|
|
1961
1961
|
return localized_short_text, localized_long_text
|
|
1962
|
+
|
|
1963
|
+
def get_localized_taxon_profile(self, profile_json, language_code):
|
|
1964
|
+
|
|
1965
|
+
glossarized_locale_filepath = self._app_glossarized_locale_filepath(language_code)
|
|
1966
|
+
|
|
1967
|
+
glossarized_locale = {}
|
|
1968
|
+
|
|
1969
|
+
if os.path.isfile(glossarized_locale_filepath):
|
|
1970
|
+
with open(glossarized_locale_filepath, 'r') as f:
|
|
1971
|
+
glossarized_locale = json.loads(f.read())
|
|
1972
|
+
|
|
1973
|
+
app_locale = self.meta_app.localizations[language_code]
|
|
1974
|
+
|
|
1975
|
+
localized_profile_json = profile_json.copy()
|
|
1976
|
+
|
|
1977
|
+
localized_short_profile = self.get_localized_taxonprofile_text(localized_profile_json['shortProfile'], glossarized_locale, app_locale)
|
|
1978
|
+
localized_profile_json['shortProfile'] = localized_short_profile
|
|
1979
|
+
|
|
1980
|
+
for index, text_dict in enumerate(profile_json['texts'], 0):
|
|
1981
|
+
|
|
1982
|
+
localized_short_text, localized_long_text = self.get_localized_taxonprofile_taxon_text(text_dict, glossarized_locale, app_locale)
|
|
1983
|
+
|
|
1984
|
+
localized_profile_json['texts'][index]['shortText'] = localized_short_text
|
|
1985
|
+
localized_profile_json['texts'][index]['longText'] = localized_long_text
|
|
1986
|
+
|
|
1987
|
+
|
|
1988
|
+
for c_index, category in enumerate(profile_json['categorizedTexts'], 0):
|
|
1989
|
+
|
|
1990
|
+
localized_category = category.copy()
|
|
1991
|
+
|
|
1992
|
+
localized_category_name = self.get_localized_taxonprofile_text(category['category'], glossarized_locale, app_locale)
|
|
1993
|
+
|
|
1994
|
+
if localized_category:
|
|
1995
|
+
localized_category['category'] = localized_category_name
|
|
1996
|
+
|
|
1997
|
+
for index, text_dict in enumerate(category['texts'], 0):
|
|
1998
|
+
localized_short_text, localized_long_text = self.get_localized_taxonprofile_taxon_text(text_dict, glossarized_locale, app_locale)
|
|
1999
|
+
|
|
2000
|
+
localized_category['texts'][index]['shortText'] = localized_short_text
|
|
2001
|
+
localized_category['texts'][index]['longText'] = localized_long_text
|
|
2002
|
+
|
|
2003
|
+
localized_profile_json['categorizedTexts'][c_index] = localized_category
|
|
2004
|
+
|
|
2005
|
+
# localize seo, no glossarized locale
|
|
2006
|
+
localized_seo = localized_profile_json['seo'].copy()
|
|
2007
|
+
title = localized_seo['title']
|
|
2008
|
+
meta_description = localized_seo['metaDescription']
|
|
2009
|
+
|
|
2010
|
+
if title and title in app_locale:
|
|
2011
|
+
localized_seo = app_locale[title]
|
|
2012
|
+
|
|
2013
|
+
if meta_description and meta_description in app_locale:
|
|
2014
|
+
localized_seo['metaDescription'] = app_locale[meta_description]
|
|
2015
|
+
|
|
2016
|
+
localized_profile_json['seo'] = localized_seo
|
|
2017
|
+
|
|
2018
|
+
return localized_profile_json
|
|
1962
2019
|
|
|
1963
2020
|
def _build_TaxonProfiles(self, app_generic_content):
|
|
1964
2021
|
|
|
@@ -1993,6 +2050,11 @@ class AppReleaseBuilder(AppBuilderBase):
|
|
|
1993
2050
|
|
|
1994
2051
|
if not os.path.isdir(app_absolute_taxonprofiles_path):
|
|
1995
2052
|
os.makedirs(app_absolute_taxonprofiles_path)
|
|
2053
|
+
|
|
2054
|
+
# morphotype paths
|
|
2055
|
+
app_relative_morphotype_profiles_folder = os.path.join(app_relative_taxonprofiles_folder, 'morphotypes')
|
|
2056
|
+
self.build_features[generic_content_type]['localizedMorphotypeFiles'] = {}
|
|
2057
|
+
app_absolute_morphotype_profiles_path = os.path.join(app_absolute_taxonprofiles_path, 'morphotypes')
|
|
1996
2058
|
|
|
1997
2059
|
|
|
1998
2060
|
collected_taxa = taxon_profiles.collected_taxa(published_only=True)
|
|
@@ -2081,8 +2143,10 @@ class AppReleaseBuilder(AppBuilderBase):
|
|
|
2081
2143
|
self.build_features[generic_content_type]['localizedFiles'] = {}
|
|
2082
2144
|
|
|
2083
2145
|
for profile_taxon in active_collected_taxa:
|
|
2146
|
+
|
|
2147
|
+
morphotype = None
|
|
2084
2148
|
|
|
2085
|
-
profile_json = jsonbuilder.build_taxon_profile(profile_taxon,
|
|
2149
|
+
profile_json = jsonbuilder.build_taxon_profile(profile_taxon, morphotype,
|
|
2086
2150
|
languages=self.meta_app.languages())
|
|
2087
2151
|
|
|
2088
2152
|
if profile_json is not None:
|
|
@@ -2101,64 +2165,13 @@ class AppReleaseBuilder(AppBuilderBase):
|
|
|
2101
2165
|
# localized taxon profiles for faster language load
|
|
2102
2166
|
for language_code in self.meta_app.languages():
|
|
2103
2167
|
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
glossarized_locale = {}
|
|
2107
|
-
|
|
2108
|
-
if os.path.isfile(glossarized_locale_filepath):
|
|
2109
|
-
with open(glossarized_locale_filepath, 'r') as f:
|
|
2110
|
-
glossarized_locale = json.loads(f.read())
|
|
2168
|
+
localized_profile_json = self.get_localized_taxon_profile(profile_json, language_code)
|
|
2111
2169
|
|
|
2112
2170
|
relative_localized_taxonprofiles_folder = os.path.join(
|
|
2113
2171
|
app_relative_taxonprofiles_folder, language_code)
|
|
2114
2172
|
|
|
2115
2173
|
if language_code not in self.build_features[generic_content_type]['localizedFiles']:
|
|
2116
2174
|
self.build_features[generic_content_type]['localizedFiles'][language_code] = '/{0}'.format(relative_localized_taxonprofiles_folder)
|
|
2117
|
-
|
|
2118
|
-
app_locale = self.meta_app.localizations[language_code]
|
|
2119
|
-
|
|
2120
|
-
localized_profile_json = profile_json.copy()
|
|
2121
|
-
|
|
2122
|
-
localized_short_profile = self.get_localized_taxonprofile_text(localized_profile_json['shortProfile'], glossarized_locale, app_locale)
|
|
2123
|
-
localized_profile_json['shortProfile'] = localized_short_profile
|
|
2124
|
-
|
|
2125
|
-
for index, text_dict in enumerate(profile_json['texts'], 0):
|
|
2126
|
-
|
|
2127
|
-
localized_short_text, localized_long_text = self.get_localized_taxonprofile_taxon_text(text_dict, glossarized_locale, app_locale)
|
|
2128
|
-
|
|
2129
|
-
localized_profile_json['texts'][index]['shortText'] = localized_short_text
|
|
2130
|
-
localized_profile_json['texts'][index]['longText'] = localized_long_text
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
for c_index, category in enumerate(profile_json['categorizedTexts'], 0):
|
|
2134
|
-
|
|
2135
|
-
localized_category = category.copy()
|
|
2136
|
-
|
|
2137
|
-
localized_category_name = self.get_localized_taxonprofile_text(category['category'], glossarized_locale, app_locale)
|
|
2138
|
-
|
|
2139
|
-
if localized_category:
|
|
2140
|
-
localized_category['category'] = localized_category_name
|
|
2141
|
-
|
|
2142
|
-
for index, text_dict in enumerate(category['texts'], 0):
|
|
2143
|
-
localized_short_text, localized_long_text = self.get_localized_taxonprofile_taxon_text(text_dict, glossarized_locale, app_locale)
|
|
2144
|
-
|
|
2145
|
-
localized_category['texts'][index]['shortText'] = localized_short_text
|
|
2146
|
-
localized_category['texts'][index]['longText'] = localized_long_text
|
|
2147
|
-
|
|
2148
|
-
localized_profile_json['categorizedTexts'][c_index] = localized_category
|
|
2149
|
-
|
|
2150
|
-
# localize seo, no glossarized locale
|
|
2151
|
-
localized_seo = localized_profile_json['seo'].copy()
|
|
2152
|
-
title = localized_seo['title']
|
|
2153
|
-
meta_description = localized_seo['metaDescription']
|
|
2154
|
-
|
|
2155
|
-
if title and title in app_locale:
|
|
2156
|
-
localized_seo = app_locale[title]
|
|
2157
|
-
|
|
2158
|
-
if meta_description and meta_description in app_locale:
|
|
2159
|
-
localized_seo['metaDescription'] = app_locale[meta_description]
|
|
2160
|
-
|
|
2161
|
-
localized_profile_json['seo'] = localized_seo
|
|
2162
2175
|
|
|
2163
2176
|
absolute_localized_taxonprofiles_folder = os.path.join(
|
|
2164
2177
|
app_absolute_taxonprofiles_path, language_code)
|
|
@@ -2177,7 +2190,52 @@ class AppReleaseBuilder(AppBuilderBase):
|
|
|
2177
2190
|
|
|
2178
2191
|
with open(localized_profile_filepath, 'w', encoding='utf-8') as f:
|
|
2179
2192
|
json.dump(localized_profile_json, f, indent=4, ensure_ascii=False)
|
|
2193
|
+
|
|
2194
|
+
# build morphotype profiles
|
|
2195
|
+
morphotypes = []
|
|
2196
|
+
taxon_profile = TaxonProfile.objects.filter(taxon_profiles=taxon_profiles,
|
|
2197
|
+
taxon_source=profile_taxon.taxon_source, taxon_latname=profile_taxon.taxon_latname,
|
|
2198
|
+
taxon_author=profile_taxon.taxon_author).first()
|
|
2199
|
+
|
|
2200
|
+
if taxon_profile and taxon_profile.morphotype_profiles:
|
|
2201
|
+
morphotypes = taxon_profile.morphotype_profiles.values_list('morphotype', flat=True)
|
|
2180
2202
|
|
|
2203
|
+
|
|
2204
|
+
for morphotype in morphotypes:
|
|
2205
|
+
|
|
2206
|
+
morphotype_profile_json = jsonbuilder.build_taxon_profile(profile_taxon, morphotype,
|
|
2207
|
+
languages=self.meta_app.languages())
|
|
2208
|
+
|
|
2209
|
+
if morphotype_profile_json is not None:
|
|
2210
|
+
|
|
2211
|
+
for language_code in self.meta_app.languages():
|
|
2212
|
+
|
|
2213
|
+
localized_profile_json = self.get_localized_taxon_profile(morphotype_profile_json, language_code)
|
|
2214
|
+
|
|
2215
|
+
relative_localized_morphotype_profiles_folder = os.path.join(
|
|
2216
|
+
app_relative_morphotype_profiles_folder, language_code)
|
|
2217
|
+
|
|
2218
|
+
if language_code not in self.build_features[generic_content_type]['localizedMorphotypeFiles']:
|
|
2219
|
+
self.build_features[generic_content_type]['localizedMorphotypeFiles'][language_code] = '/{0}'.format(relative_localized_morphotype_profiles_folder)
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
absolute_localized_morphotype_profiles_folder = os.path.join(
|
|
2223
|
+
app_absolute_morphotype_profiles_path, language_code)
|
|
2224
|
+
|
|
2225
|
+
if not os.path.isdir(absolute_localized_morphotype_profiles_folder):
|
|
2226
|
+
os.makedirs(absolute_localized_morphotype_profiles_folder)
|
|
2227
|
+
|
|
2228
|
+
localized_source_folder = os.path.join(absolute_localized_morphotype_profiles_folder,
|
|
2229
|
+
profile_taxon.taxon_source)
|
|
2230
|
+
|
|
2231
|
+
if not os.path.isdir(localized_source_folder):
|
|
2232
|
+
os.makedirs(localized_source_folder)
|
|
2233
|
+
|
|
2234
|
+
localized_morphotype_profile_filepath = os.path.join(localized_source_folder,
|
|
2235
|
+
'{0}_{1}.json'.format(profile_taxon.name_uuid, morphotype))
|
|
2236
|
+
|
|
2237
|
+
with open(localized_morphotype_profile_filepath, 'w', encoding='utf-8') as f:
|
|
2238
|
+
json.dump(morphotype_profile_json, f, indent=4, ensure_ascii=False)
|
|
2181
2239
|
|
|
2182
2240
|
|
|
2183
2241
|
# build search index and registry
|
|
@@ -52,7 +52,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
52
52
|
installed_taxonomic_sources = [s[0] for s in settings.TAXONOMY_DATABASES]
|
|
53
53
|
return installed_taxonomic_sources
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
'''
|
|
56
56
|
def collect_node_traits(self, node):
|
|
57
57
|
|
|
58
58
|
#self.app_release_builder.logger.info('collecting node traits for {0}'.format(node.meta_node.name))
|
|
@@ -95,6 +95,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
95
95
|
#self.app_release_builder.logger.info('finished collecting')
|
|
96
96
|
|
|
97
97
|
return node_traits
|
|
98
|
+
'''
|
|
98
99
|
|
|
99
100
|
|
|
100
101
|
def get_vernacular_name_from_nature_guides(self, lazy_taxon):
|
|
@@ -109,7 +110,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
109
110
|
return template_contents
|
|
110
111
|
|
|
111
112
|
# languages is for the vernacular name only, the rest are keys for translation
|
|
112
|
-
def build_taxon_profile(self, profile_taxon, languages):
|
|
113
|
+
def build_taxon_profile(self, profile_taxon, morphotype, languages):
|
|
113
114
|
|
|
114
115
|
lazy_taxon = LazyTaxon(instance=profile_taxon)
|
|
115
116
|
|
|
@@ -118,7 +119,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
118
119
|
# get the profile
|
|
119
120
|
db_profile = TaxonProfile.objects.filter(taxon_profiles=self.generic_content,
|
|
120
121
|
taxon_source=profile_taxon.taxon_source, taxon_latname=profile_taxon.taxon_latname,
|
|
121
|
-
taxon_author=profile_taxon.taxon_author).first()
|
|
122
|
+
taxon_author=profile_taxon.taxon_author, morphotype=morphotype).first()
|
|
122
123
|
|
|
123
124
|
|
|
124
125
|
taxon_profile_json = self.app_release_builder.taxa_builder.serialize_taxon_extended(lazy_taxon)
|
|
@@ -126,8 +127,9 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
126
127
|
# if the taxonomic db got updated, still use the old taxon latname and author here
|
|
127
128
|
taxon_profile_json['taxonLatname'] = lazy_taxon.taxon_latname
|
|
128
129
|
taxon_profile_json['taxonAuthor'] = lazy_taxon.taxon_author
|
|
130
|
+
images = []
|
|
129
131
|
|
|
130
|
-
images = self.app_release_builder.taxa_builder.serialize_taxon_images(lazy_taxon)
|
|
132
|
+
images = self.app_release_builder.taxa_builder.serialize_taxon_images(lazy_taxon, morphotype=morphotype)
|
|
131
133
|
|
|
132
134
|
is_featured = False
|
|
133
135
|
if db_profile:
|
|
@@ -139,6 +141,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
139
141
|
|
|
140
142
|
taxon_profile_json.update({
|
|
141
143
|
'taxonProfileId': db_profile.id if db_profile else None,
|
|
144
|
+
'morphotype': db_profile.morphotype if db_profile else None,
|
|
142
145
|
'vernacular' : {},
|
|
143
146
|
'allVernacularNames' : {},
|
|
144
147
|
'nodeNames' : [], # if the taxon occurs in a nature guide, primary_language only
|
|
@@ -151,7 +154,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
151
154
|
'synonyms' : [],
|
|
152
155
|
'templateContents' : [],
|
|
153
156
|
'genericForms' : self.collect_usable_generic_forms(profile_taxon),
|
|
154
|
-
'taxonRelationships': self.collect_taxon_relationships(profile_taxon),
|
|
157
|
+
'taxonRelationships': self.collect_taxon_relationships(profile_taxon) if not morphotype else [],
|
|
155
158
|
'tags' : [],
|
|
156
159
|
'seo': {
|
|
157
160
|
'title': None,
|
|
@@ -162,14 +165,15 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
162
165
|
'isFeatured': is_featured,
|
|
163
166
|
})
|
|
164
167
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
if not morphotype:
|
|
169
|
+
synonyms = profile_taxon.synonyms()
|
|
170
|
+
for synonym in synonyms:
|
|
171
|
+
synonym_entry = {
|
|
172
|
+
'taxonLatname' : synonym.taxon_latname,
|
|
173
|
+
'taxonAuthor' : synonym.taxon_author,
|
|
174
|
+
}
|
|
171
175
|
|
|
172
|
-
|
|
176
|
+
taxon_profile_json['synonyms'].append(synonym_entry)
|
|
173
177
|
|
|
174
178
|
for language_code in languages:
|
|
175
179
|
|
|
@@ -186,6 +190,24 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
186
190
|
|
|
187
191
|
# template contents
|
|
188
192
|
taxon_profile_json['templateContents'] = self.get_taxon_profile_template_content_links(profile_taxon, language_code)
|
|
193
|
+
|
|
194
|
+
# respect additional languages for vernacular names as defined in taxon profiles options
|
|
195
|
+
include_vernacular_names_languages_option = self.generic_content.get_option(self.meta_app,
|
|
196
|
+
'include_vernacular_names_languages')
|
|
197
|
+
if include_vernacular_names_languages_option:
|
|
198
|
+
additional_languages = [lang.strip() for lang in include_vernacular_names_languages_option.split(',') if lang.strip()]
|
|
199
|
+
for language_code in additional_languages:
|
|
200
|
+
if language_code not in languages:
|
|
201
|
+
preferred_vernacular_name = lazy_taxon.get_preferred_vernacular_name(language_code,
|
|
202
|
+
self.meta_app)
|
|
203
|
+
|
|
204
|
+
taxon_profile_json['vernacular'][language_code] = preferred_vernacular_name
|
|
205
|
+
|
|
206
|
+
all_vernacular_names = profile_taxon.all_vernacular_names(self.meta_app,
|
|
207
|
+
languages=[language_code])
|
|
208
|
+
|
|
209
|
+
names_list = [name_reference['name'] for name_reference in all_vernacular_names]
|
|
210
|
+
taxon_profile_json['allVernacularNames'][language_code] = names_list
|
|
189
211
|
|
|
190
212
|
# get taxon_profile_images
|
|
191
213
|
if db_profile:
|
|
@@ -207,7 +229,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
207
229
|
# get information (traits, node_names) from nature guides if possible
|
|
208
230
|
# collect node images
|
|
209
231
|
# only use occurrences in nature guides of this app
|
|
210
|
-
node_occurrences = self.app_release_builder.taxa_builder.get_nature_guide_occurrences(lazy_taxon)
|
|
232
|
+
node_occurrences = self.app_release_builder.taxa_builder.get_nature_guide_occurrences(lazy_taxon, morphotype=morphotype)
|
|
211
233
|
|
|
212
234
|
# collect traits of upward branch in tree (higher taxa)
|
|
213
235
|
parent_nuids = set([])
|
|
@@ -287,7 +309,8 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
287
309
|
|
|
288
310
|
if db_profile:
|
|
289
311
|
|
|
290
|
-
|
|
312
|
+
if not morphotype:
|
|
313
|
+
taxon_profile_json['morphotypeProfiles'] = self.collect_morphotype_profiles(db_profile, languages)
|
|
291
314
|
|
|
292
315
|
taxon_profile_json['shortProfile'] = db_profile.short_profile
|
|
293
316
|
|
|
@@ -469,7 +492,7 @@ class TaxonProfilesJSONBuilder(JSONBuilder):
|
|
|
469
492
|
'taxonProfileId': morphotype.id,
|
|
470
493
|
'parentTaxonProfileId': taxon_profile.id,
|
|
471
494
|
'morphotype': morphotype.morphotype,
|
|
472
|
-
'taxon': self.app_release_builder.taxa_builder.
|
|
495
|
+
'taxon': self.app_release_builder.taxa_builder.serialize_taxon_extended(lazy_taxon),
|
|
473
496
|
'vernacular' : {},
|
|
474
497
|
'image': image_entry,
|
|
475
498
|
}
|
|
Binary file
|
|
@@ -41,8 +41,7 @@ class TaxaBuilder(ContentImagesJSONBuilder):
|
|
|
41
41
|
|
|
42
42
|
def serialize_taxon(self, lazy_taxon):
|
|
43
43
|
taxon_serializer = TaxonSerializer(lazy_taxon, self)
|
|
44
|
-
return taxon_serializer.serialize()
|
|
45
|
-
|
|
44
|
+
return taxon_serializer.serialize()
|
|
46
45
|
|
|
47
46
|
def serialize_taxon_extended(self, lazy_taxon):
|
|
48
47
|
taxon_serializer = TaxonSerializer(lazy_taxon, self)
|
|
@@ -66,9 +65,9 @@ class TaxaBuilder(ContentImagesJSONBuilder):
|
|
|
66
65
|
accepted_name_uuid)
|
|
67
66
|
|
|
68
67
|
|
|
69
|
-
def serialize_taxon_images(self, lazy_taxon):
|
|
68
|
+
def serialize_taxon_images(self, lazy_taxon, morphotype=None):
|
|
70
69
|
taxon_serializer = TaxonSerializer(lazy_taxon, self)
|
|
71
|
-
return taxon_serializer.serialize_images()
|
|
70
|
+
return taxon_serializer.serialize_images(morphotype=morphotype)
|
|
72
71
|
|
|
73
72
|
|
|
74
73
|
def get_nature_guide_ids(self):
|
|
@@ -80,7 +79,7 @@ class TaxaBuilder(ContentImagesJSONBuilder):
|
|
|
80
79
|
return self.nature_guide_ids
|
|
81
80
|
|
|
82
81
|
|
|
83
|
-
def get_nature_guide_occurrences(self, lazy_taxon):
|
|
82
|
+
def get_nature_guide_occurrences(self, lazy_taxon, morphotype=None):
|
|
84
83
|
nature_guide_ids = self.get_nature_guide_ids()
|
|
85
84
|
|
|
86
85
|
if lazy_taxon.taxon_source in self.installed_taxonomic_sources:
|
|
@@ -88,6 +87,7 @@ class TaxaBuilder(ContentImagesJSONBuilder):
|
|
|
88
87
|
meta_nodes = MetaNode.objects.filter(
|
|
89
88
|
nature_guide_id__in=nature_guide_ids,
|
|
90
89
|
node_type='result',
|
|
90
|
+
morphotype=morphotype,
|
|
91
91
|
name_uuid = lazy_taxon.name_uuid).values_list('pk', flat=True)
|
|
92
92
|
|
|
93
93
|
node_occurrences = NatureGuidesTaxonTree.objects.filter(nature_guide_id__in=nature_guide_ids,
|
|
@@ -211,12 +211,13 @@ class TaxonSerializer:
|
|
|
211
211
|
|
|
212
212
|
return taxon_json_copy
|
|
213
213
|
|
|
214
|
-
def get_taxon_profile(self):
|
|
214
|
+
def get_taxon_profile(self, morphotype=None):
|
|
215
215
|
taxon_profile = None
|
|
216
216
|
|
|
217
217
|
taxon_profile_qry = TaxonProfile.objects.filter(
|
|
218
218
|
taxon_profiles=self.taxa_builder.taxon_profiles,
|
|
219
|
-
name_uuid=self.lazy_taxon.name_uuid
|
|
219
|
+
name_uuid=self.lazy_taxon.name_uuid,
|
|
220
|
+
morphotype=morphotype).first()
|
|
220
221
|
|
|
221
222
|
if taxon_profile_qry and taxon_profile_qry.publication_status != 'draft':
|
|
222
223
|
taxon_profile = taxon_profile_qry
|
|
@@ -224,19 +225,23 @@ class TaxonSerializer:
|
|
|
224
225
|
return taxon_profile
|
|
225
226
|
|
|
226
227
|
|
|
227
|
-
def serialize_images(self):
|
|
228
|
+
def serialize_images(self, morphotype=None):
|
|
228
229
|
|
|
229
230
|
name_uuid_str = str(self.lazy_taxon.name_uuid)
|
|
231
|
+
cache_key=name_uuid_str
|
|
232
|
+
|
|
233
|
+
if morphotype:
|
|
234
|
+
cache_key = name_uuid_str + '_' + morphotype
|
|
230
235
|
|
|
231
|
-
if
|
|
232
|
-
taxon_images = self.taxa_builder.cache['images'][
|
|
236
|
+
if cache_key in self.taxa_builder.cache['images']:
|
|
237
|
+
taxon_images = self.taxa_builder.cache['images'][cache_key]
|
|
233
238
|
|
|
234
239
|
else:
|
|
235
240
|
|
|
236
241
|
collected_content_image_ids = set([])
|
|
237
242
|
collected_image_store_ids = set([])
|
|
238
243
|
|
|
239
|
-
taxon_profile = self.get_taxon_profile()
|
|
244
|
+
taxon_profile = self.get_taxon_profile(morphotype=morphotype)
|
|
240
245
|
|
|
241
246
|
taxon_images = {
|
|
242
247
|
'primary': None,
|
|
@@ -272,8 +277,9 @@ class TaxonSerializer:
|
|
|
272
277
|
taxon_images['primary'] = image_entry
|
|
273
278
|
|
|
274
279
|
|
|
280
|
+
|
|
275
281
|
# images from nature guides
|
|
276
|
-
node_occurrences = self.taxa_builder.get_nature_guide_occurrences(self.lazy_taxon)
|
|
282
|
+
node_occurrences = self.taxa_builder.get_nature_guide_occurrences(self.lazy_taxon, morphotype=morphotype)
|
|
277
283
|
|
|
278
284
|
for node in node_occurrences:
|
|
279
285
|
|
|
@@ -297,30 +303,31 @@ class TaxonSerializer:
|
|
|
297
303
|
|
|
298
304
|
if taxon_images['primary'] == None:
|
|
299
305
|
taxon_images['primary'] = image_entry
|
|
300
|
-
|
|
306
|
+
|
|
301
307
|
|
|
302
308
|
# get taxonomic images
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
309
|
+
if not morphotype:
|
|
310
|
+
content_images_taxon = ContentImage.objects.filter(image_store__taxon_source=self.lazy_taxon.taxon_source,
|
|
311
|
+
image_store__taxon_latname=self.lazy_taxon.taxon_latname,
|
|
312
|
+
image_store__taxon_author=self.lazy_taxon.taxon_author).exclude(
|
|
313
|
+
pk__in=list(collected_content_image_ids))
|
|
307
314
|
|
|
308
|
-
|
|
315
|
+
#self.app_release_builder.logger.info('Found {0} images for {1}'.format(taxon_images.count(), profile_taxon.taxon_latname))
|
|
309
316
|
|
|
310
|
-
|
|
317
|
+
for taxon_image in content_images_taxon:
|
|
311
318
|
|
|
312
|
-
|
|
319
|
+
if taxon_image is not None and taxon_image.id not in collected_content_image_ids and taxon_image.image_store.id not in collected_image_store_ids:
|
|
313
320
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
321
|
+
image_entry = self.taxa_builder.get_image_json(taxon_image)
|
|
322
|
+
taxon_images['taxonImages'].append(image_entry)
|
|
323
|
+
|
|
324
|
+
if taxon_images['primary'] == None:
|
|
325
|
+
taxon_images['primary'] = image_entry
|
|
319
326
|
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
collected_content_image_ids.add(taxon_image.id)
|
|
328
|
+
collected_image_store_ids.add(taxon_image.image_store.id)
|
|
322
329
|
|
|
323
|
-
self.taxa_builder.cache['images'][
|
|
330
|
+
self.taxa_builder.cache['images'][cache_key] = taxon_images
|
|
324
331
|
|
|
325
332
|
taxon_images_copy = copy.deepcopy(taxon_images)
|
|
326
333
|
|
|
Binary file
|
|
Binary file
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<div class="mt-5">
|
|
30
30
|
<h3>{% trans 'Taxon Profile' %}</h3>
|
|
31
31
|
{% if taxon_profile %}
|
|
32
|
-
<a href="{% url 'manage_taxon_profile' meta_app.id
|
|
32
|
+
<a href="{% url 'manage_taxon_profile' meta_app.id taxon_profile.id %}">{{ taxon }}</a>
|
|
33
33
|
{% else %}
|
|
34
34
|
{% trans 'This taxon does not have a taxon profile' %}
|
|
35
35
|
{% endif %}
|
|
@@ -29,6 +29,9 @@ class TaxonProfilesOptionsForm(GenericFormChoicesMixin, GenericContentOptionsFor
|
|
|
29
29
|
|
|
30
30
|
enable_taxonomic_navigation = forms.BooleanField(required=False, label=_('Enable Taxonomic Navigation'))
|
|
31
31
|
|
|
32
|
+
include_vernacular_names_languages = forms.CharField(required=False, label=_('Include Vernacular Names Languages'),
|
|
33
|
+
help_text=_('A comma-separated list of language codes (e.g. "en,de,fr") to include vernacular names from. Leave empty to include all available languages.'))
|
|
34
|
+
|
|
32
35
|
version = forms.CharField(help_text=_('You can manually set you own version here. This will not affect the automated versioning.'), required=False)
|
|
33
36
|
|
|
34
37
|
|
|
@@ -94,8 +97,6 @@ class ManageTaxonTextsForm(LocalizeableForm):
|
|
|
94
97
|
|
|
95
98
|
self.layoutable_simple_fields = []
|
|
96
99
|
|
|
97
|
-
self.has_categories = False
|
|
98
|
-
|
|
99
100
|
super().__init__(*args, **kwargs)
|
|
100
101
|
|
|
101
102
|
categories = [None] + list(TaxonTextTypeCategory.objects.filter(taxon_profiles=taxon_profiles))
|
|
@@ -105,34 +106,12 @@ class ManageTaxonTextsForm(LocalizeableForm):
|
|
|
105
106
|
if taxon_profile.taxon_text_set:
|
|
106
107
|
allowed_text_types = taxon_profile.taxon_text_set.text_types.values_list('pk', flat=True)
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
self.has_categories = True
|
|
110
|
-
|
|
111
|
-
for category_index, category in enumerate(categories, 1):
|
|
112
|
-
|
|
113
|
-
types = TaxonTextType.objects.filter(taxon_profiles=taxon_profiles, category=category, pk__in=allowed_text_types).order_by('category', 'position')
|
|
114
|
-
|
|
115
|
-
category_label = 'uncategorized'
|
|
116
|
-
if category:
|
|
117
|
-
category_label = category.name
|
|
118
|
-
|
|
119
|
-
category_helper_field = forms.CharField(widget=forms.HiddenInput(), label=category_label, required=False)
|
|
120
|
-
category_helper_field.category = category
|
|
121
|
-
category_helper_field.is_category_field = True
|
|
122
|
-
category_helper_field.text_type_count = types.count()
|
|
123
|
-
category_helper_field.is_first_category = False
|
|
124
|
-
category_helper_field.is_last = False
|
|
125
|
-
|
|
126
|
-
if category_index == 2:
|
|
127
|
-
category_helper_field.is_first_category = True
|
|
128
|
-
|
|
129
|
-
if not types:
|
|
130
|
-
category_helper_field.is_last = True
|
|
109
|
+
for category in categories:
|
|
131
110
|
|
|
132
|
-
|
|
111
|
+
types = TaxonTextType.objects.filter(taxon_profiles=taxon_profiles, category=category, pk__in=allowed_text_types).order_by('category', 'position')
|
|
133
112
|
|
|
134
113
|
for field_index, text_type in enumerate(types, 1):
|
|
135
|
-
|
|
114
|
+
|
|
136
115
|
short_text_field_name = text_type.text_type
|
|
137
116
|
|
|
138
117
|
self.text_type_map[short_text_field_name] = text_type
|
|
@@ -143,14 +122,17 @@ class ManageTaxonTextsForm(LocalizeableForm):
|
|
|
143
122
|
required=False, label=short_text_field_label, validators=[json_compatible])
|
|
144
123
|
short_text_field.taxon_text_type = text_type
|
|
145
124
|
short_text_field.is_short_version = True
|
|
146
|
-
short_text_field.is_last = False
|
|
147
125
|
short_text_field.taxon_text = None
|
|
126
|
+
short_text_field.category = None
|
|
148
127
|
|
|
149
128
|
self.fields[short_text_field_name] = short_text_field
|
|
150
129
|
self.localizeable_fields.append(short_text_field_name)
|
|
151
130
|
self.fields[short_text_field_name].language = self.language
|
|
152
131
|
self.layoutable_simple_fields.append(short_text_field_name)
|
|
153
132
|
|
|
133
|
+
if field_index == 1:
|
|
134
|
+
short_text_field.category = category
|
|
135
|
+
|
|
154
136
|
|
|
155
137
|
if settings.APP_KIT_ENABLE_TAXON_PROFILES_LONG_TEXTS == True:
|
|
156
138
|
long_text_field_name = self.get_long_text_form_field_name(text_type)
|
|
@@ -162,19 +144,12 @@ class ManageTaxonTextsForm(LocalizeableForm):
|
|
|
162
144
|
required=False, label=long_text_field_label, validators=[json_compatible])
|
|
163
145
|
long_text_field.taxon_text_type = text_type
|
|
164
146
|
long_text_field.is_short_version = False
|
|
165
|
-
long_text_field.is_last = False
|
|
166
147
|
|
|
167
148
|
self.fields[long_text_field_name] = long_text_field
|
|
168
149
|
self.localizeable_fields.append(long_text_field_name)
|
|
169
150
|
self.fields[long_text_field_name].language = self.language
|
|
170
151
|
self.layoutable_simple_fields.append(long_text_field_name)
|
|
171
|
-
|
|
172
|
-
if field_index == len(types):
|
|
173
|
-
if settings.APP_KIT_ENABLE_TAXON_PROFILES_LONG_TEXTS == True:
|
|
174
|
-
long_text_field.is_last = True
|
|
175
|
-
else:
|
|
176
|
-
short_text_field.is_last = True
|
|
177
|
-
|
|
152
|
+
|
|
178
153
|
if taxon_profile:
|
|
179
154
|
content = TaxonText.objects.filter(taxon_text_type=text_type,
|
|
180
155
|
taxon_profile=taxon_profile).first()
|
|
@@ -185,7 +160,7 @@ class ManageTaxonTextsForm(LocalizeableForm):
|
|
|
185
160
|
if settings.APP_KIT_ENABLE_TAXON_PROFILES_LONG_TEXTS == True:
|
|
186
161
|
long_text_field.initial = content.long_text
|
|
187
162
|
long_text_field.taxon_text = content
|
|
188
|
-
|
|
163
|
+
|
|
189
164
|
|
|
190
165
|
def get_long_text_form_field_name(self, text_type):
|
|
191
166
|
|
|
@@ -87,51 +87,44 @@ class TaxonProfiles(GenericContent):
|
|
|
87
87
|
def get_primary_localization(self, meta_app=None):
|
|
88
88
|
locale = super().get_primary_localization(meta_app)
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
'taxon_source' : lazy_taxon.taxon_source,
|
|
96
|
-
'taxon_latname' : lazy_taxon.taxon_latname,
|
|
97
|
-
'taxon_author' : lazy_taxon.taxon_author,
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
taxon_profile = TaxonProfile.objects.filter(taxon_profiles=self, **taxon_query).first()
|
|
101
|
-
|
|
102
|
-
if taxon_profile:
|
|
90
|
+
all_taxon_profiles = TaxonProfile.objects.filter(taxon_profiles=self)
|
|
91
|
+
for taxon_profile in all_taxon_profiles:
|
|
92
|
+
|
|
93
|
+
if taxon_profile.publication_status == 'draft':
|
|
94
|
+
continue
|
|
103
95
|
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
if taxon_profile.morphotype:
|
|
97
|
+
locale[taxon_profile.morphotype] = taxon_profile.morphotype
|
|
106
98
|
|
|
107
|
-
|
|
99
|
+
for text in taxon_profile.texts():
|
|
108
100
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
101
|
+
# text_type_key = 'taxon_text_{0}'.format(text.taxon_text_type.id)
|
|
102
|
+
# short: use name as key (-> no duplicates in translation matrix)
|
|
103
|
+
text_type_key = text.taxon_text_type.text_type
|
|
104
|
+
locale[text_type_key] = text.taxon_text_type.text_type
|
|
105
|
+
|
|
106
|
+
# text.text is a bad key, because if text.text changes, the translation is gone
|
|
107
|
+
# text.text are long texts, so use a different key which survives text changes
|
|
108
|
+
# locale[text.text] = text.text
|
|
117
109
|
|
|
118
|
-
|
|
110
|
+
short_text_key = self.get_short_text_key(text)
|
|
119
111
|
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
if text.text:
|
|
113
|
+
locale[short_text_key] = text.text
|
|
122
114
|
|
|
123
|
-
|
|
115
|
+
long_text_key = self.get_long_text_key(text)
|
|
124
116
|
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
if text.long_text:
|
|
118
|
+
locale[long_text_key] = text.long_text
|
|
127
119
|
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
content_images_primary_localization = taxon_profile.get_content_images_primary_localization()
|
|
121
|
+
locale.update(content_images_primary_localization)
|
|
122
|
+
|
|
123
|
+
short_profile = taxon_profile.short_profile
|
|
124
|
+
if short_profile:
|
|
125
|
+
locale[short_profile] = short_profile
|
|
130
126
|
|
|
131
|
-
|
|
132
|
-
if short_profile:
|
|
133
|
-
locale[short_profile] = short_profile
|
|
134
|
-
|
|
127
|
+
|
|
135
128
|
navigation = TaxonProfilesNavigation.objects.filter(taxon_profiles=self).first()
|
|
136
129
|
|
|
137
130
|
if navigation:
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<script>
|
|
33
33
|
var modal = $("#Modal");
|
|
34
34
|
modal.modal("hide");
|
|
35
|
-
window.location = "{% url 'manage_taxon_profile' meta_app.id
|
|
35
|
+
window.location = "{% url 'manage_taxon_profile' meta_app.id taxon_profile.id %}";
|
|
36
36
|
</script>
|
|
37
37
|
{% endif %}
|
|
38
38
|
{% endblock %}
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_form.html
CHANGED
|
@@ -1,70 +1,51 @@
|
|
|
1
1
|
{% load i18n static localcosmos_tags %}
|
|
2
2
|
{% if text_types %}
|
|
3
|
-
<form id="taxon-text-types-form" method="POST" action="{% url 'manage_taxon_profile' meta_app.id
|
|
3
|
+
<form id="taxon-text-types-form" method="POST" action="{% url 'manage_taxon_profile' meta_app.id taxon_profile.id %}"
|
|
4
|
+
>{% csrf_token %}
|
|
4
5
|
<div id="text-types-form-fields">
|
|
5
6
|
{% for field in form %}
|
|
6
|
-
{% if field.field.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<div id="order-ctype-{{ text_type_content_type.id }}{% if field.field.category %}-{{ field.field.category.id }}{% endif %}-container" {% if field.field.category %}data-object-id="{{ field.field.category.id }}"{% endif %} class="text-type-category-container">
|
|
7
|
+
{% if field.field.category %}
|
|
8
|
+
<h2>
|
|
9
|
+
{{ field.field.category }}
|
|
10
|
+
</h2>
|
|
11
11
|
{% endif %}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{% if field.is_hidden %}
|
|
15
|
-
{% if field.field.category %}
|
|
16
|
-
<h2>
|
|
17
|
-
{{ field.field.category }}
|
|
18
|
-
</h2>
|
|
12
|
+
<div class="row">
|
|
13
|
+
<div class="col-12">
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{%
|
|
15
|
+
{% if field.is_hidden %}
|
|
16
|
+
{{ field }}
|
|
17
|
+
{% else %}
|
|
18
|
+
<div class="form-group {% if field.errors %}has-error{% endif %}">
|
|
19
|
+
|
|
20
|
+
<h4>
|
|
21
|
+
{{ field.label }}
|
|
22
|
+
{% if field.field.taxon_text_type %}
|
|
23
|
+
{% if show_text_length_badges %}{% if field.field.is_short_version %}<span class="badge badge-info">{% trans 'short version' %}</span>{% else %}<span class="badge badge-primary">{% trans 'long version' %}</span>{% endif %} {% endif %}
|
|
28
24
|
{% endif %}
|
|
29
|
-
|
|
30
|
-
{% else %}
|
|
31
|
-
<div class="form-group {% if field.errors %}has-error{% endif %}">
|
|
25
|
+
</h4>
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{% if show_text_length_badges %}{% if field.field.is_short_version %}<span class="badge badge-info">{% trans 'short version' %}</span>{% else %}<span class="badge badge-primary">{% trans 'long version' %}</span>{% endif %} {% endif %}
|
|
37
|
-
{% endif %}
|
|
38
|
-
</h4>
|
|
27
|
+
{% if field.field.language %}
|
|
28
|
+
<img src="{% static 'localcosmos_server/images/countries/' %}{{ field.field.language }}.gif" /> {{ field.field.language }}
|
|
29
|
+
{% endif %}
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
{{ field }}
|
|
32
|
+
{% if field.help_text %}
|
|
33
|
+
<small class="form-text text-muted">{{ field.help_text }}</small>
|
|
34
|
+
{% endif %}
|
|
35
|
+
</div>
|
|
43
36
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
{%
|
|
37
|
+
{% if field.field.taxon_text and field.field.is_short_version %}
|
|
38
|
+
{% with content_instance=field.field.taxon_text %}
|
|
39
|
+
<div id="content-images-list-{{ content_instance|ctype_id }}-{{ content_instance.id }}" class="taxon-text-images-container">
|
|
40
|
+
{% include 'app_kit/ajax/content_images_list.html' %}
|
|
48
41
|
</div>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{% include 'app_kit/ajax/content_images_list.html' %}
|
|
54
|
-
</div>
|
|
55
|
-
{% endwith %}
|
|
56
|
-
{% endif %}
|
|
57
|
-
<br><br>
|
|
58
|
-
{% endif %}
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
{% if field.field.is_last %}
|
|
42
|
+
{% endwith %}
|
|
43
|
+
{% endif %}
|
|
44
|
+
<br><br>
|
|
45
|
+
{% endif %}
|
|
62
46
|
</div>
|
|
63
|
-
|
|
47
|
+
</div>
|
|
64
48
|
{% endfor %}
|
|
65
|
-
{% if form.has_categories %}
|
|
66
|
-
<!--</div>-->
|
|
67
|
-
{% endif %}
|
|
68
49
|
</div>
|
|
69
50
|
|
|
70
51
|
<div class="row">
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_morphotype.html
CHANGED
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
{% if success %}
|
|
24
24
|
<script>
|
|
25
25
|
{% if created %}
|
|
26
|
-
|
|
26
|
+
// taxon_profile is the created morphotype profile
|
|
27
|
+
window.location.href = "{% url 'manage_taxon_profile' meta_app.id taxon_profile.id %}";
|
|
27
28
|
{% else %}
|
|
28
29
|
// Reload the page to show the updated morphotype
|
|
29
30
|
$('#Modal').modal('hide');
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
{% if meta_node.taxon %}
|
|
8
8
|
{% get_taxon_profile meta_app meta_node.taxon as profile %}
|
|
9
9
|
{% if profile %}
|
|
10
|
-
<a href="{% url 'manage_taxon_profile' meta_app.id
|
|
10
|
+
<a href="{% url 'manage_taxon_profile' meta_app.id profile.id %}">
|
|
11
11
|
{{ meta_node.name }} <i>{{ meta_node.taxon_latname }} {{ meta_node.taxon_author }}</i>
|
|
12
12
|
</a>
|
|
13
13
|
{% if profile.publication_status == 'draft' %}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
{% get_nature_guide_taxon meta_node nature_guide as taxon %}
|
|
24
24
|
{% get_taxon_profile meta_app taxon as non_taxon_profile %}
|
|
25
25
|
{% if non_taxon_profile %}
|
|
26
|
-
<a href="{% url 'manage_taxon_profile' meta_app.id
|
|
26
|
+
<a href="{% url 'manage_taxon_profile' meta_app.id non_taxon_profile.id %}">
|
|
27
27
|
{{ meta_node.name }}
|
|
28
28
|
</a>
|
|
29
29
|
{% if non_taxon_profile.publication_status == 'draft' %}
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/non_nature_guide_taxonlist.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<ul>
|
|
4
4
|
{% for profile in non_nature_guide_taxon_profiles %}
|
|
5
5
|
<li>
|
|
6
|
-
<a href="{% url 'manage_taxon_profile' meta_app.id
|
|
6
|
+
<a href="{% url 'manage_taxon_profile' meta_app.id profile.id %}">
|
|
7
7
|
<i>{{ profile.taxon_latname }} {{ profile.taxon_author }}</i>
|
|
8
8
|
</a>
|
|
9
9
|
{% if profile.publication_status == 'draft' %}
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
</div>
|
|
93
93
|
{% for duplicate in possible_duplicates %}
|
|
94
94
|
<i>
|
|
95
|
-
<a href="{% url 'manage_taxon_profile' meta_app.id
|
|
95
|
+
<a href="{% url 'manage_taxon_profile' meta_app.id duplicate.id %}">{{ duplicate.taxon_latname }} {{ duplicate.taxon_author }}</a>
|
|
96
96
|
</i>
|
|
97
97
|
{% endfor %}
|
|
98
98
|
</div>
|
|
@@ -111,10 +111,10 @@
|
|
|
111
111
|
</div>
|
|
112
112
|
</div>
|
|
113
113
|
{% endif %}
|
|
114
|
-
{% if taxon_profile.morphotype %}
|
|
114
|
+
{% if taxon_profile.morphotype and taxon_profile.parent_profile %}
|
|
115
115
|
<div class="row">
|
|
116
116
|
<div class="col-12">
|
|
117
|
-
{% trans 'This is a morphotype of:' %} <a href="{% url 'manage_taxon_profile' meta_app.id
|
|
117
|
+
{% trans 'This is a morphotype of:' %} <a href="{% url 'manage_taxon_profile' meta_app.id taxon_profile.parent_profile.id %}">
|
|
118
118
|
{{ taxon }}
|
|
119
119
|
</a>
|
|
120
120
|
</div>
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
{% if taxon_profile.morphotype_profiles %}
|
|
132
132
|
{% for morphotype in taxon_profile.morphotype_profiles %}
|
|
133
133
|
<div>
|
|
134
|
-
<a href="{% url 'manage_taxon_profile' meta_app.id
|
|
134
|
+
<a href="{% url 'manage_taxon_profile' meta_app.id morphotype.id %}">
|
|
135
135
|
{{ morphotype.morphotype }}
|
|
136
136
|
</a>
|
|
137
137
|
</div>
|
|
@@ -10,6 +10,9 @@ urlpatterns = [
|
|
|
10
10
|
views.CreateTaxonProfile.as_view(), name='create_taxon_profile'),
|
|
11
11
|
path('manage-taxon-profile/<int:meta_app_id>/<int:taxon_profiles_id>/<str:taxon_source>/<uuid:name_uuid>/',
|
|
12
12
|
views.ManageTaxonProfile.as_view(), name='manage_taxon_profile'),
|
|
13
|
+
# this should be the future wherever possible, as it is more robust (does not rely on taxon_source and name_uuid to be unchanged)
|
|
14
|
+
path('manage-taxon-profile/<int:meta_app_id>/<int:taxon_profile_id>/',
|
|
15
|
+
views.ManageTaxonProfile.as_view(), name='manage_taxon_profile'),
|
|
13
16
|
path('delete-taxon-profile/<int:meta_app_id>/<int:pk>/',
|
|
14
17
|
views.DeleteTaxonProfile.as_view(), name='delete_taxon_profile'),
|
|
15
18
|
# morphotypes
|
|
@@ -298,16 +298,22 @@ class ManageTaxonProfile(CreateTaxonProfileMixin, MetaAppFormLanguageMixin, Form
|
|
|
298
298
|
|
|
299
299
|
def set_taxon(self, request, **kwargs):
|
|
300
300
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
301
|
+
if 'taxon_profile_id' in kwargs:
|
|
302
|
+
self.taxon_profile = TaxonProfile.objects.get(pk=kwargs['taxon_profile_id'])
|
|
303
|
+
self.taxon_profiles = self.taxon_profile.taxon_profiles
|
|
304
|
+
|
|
305
|
+
else:
|
|
305
306
|
|
|
306
|
-
|
|
307
|
+
self.taxon_profiles = TaxonProfiles.objects.get(pk=kwargs['taxon_profiles_id'])
|
|
307
308
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
taxon_source = kwargs['taxon_source']
|
|
310
|
+
name_uuid = kwargs['name_uuid']
|
|
311
|
+
|
|
312
|
+
morphotype = kwargs.get('morphotype', None)
|
|
313
|
+
|
|
314
|
+
self.taxon_profile = TaxonProfile.objects.get(taxon_profiles=self.taxon_profiles,
|
|
315
|
+
taxon_source=taxon_source, name_uuid=name_uuid,
|
|
316
|
+
morphotype=morphotype)
|
|
311
317
|
|
|
312
318
|
self.taxon = LazyTaxon(instance=self.taxon_profile)
|
|
313
319
|
|
|
@@ -744,44 +750,50 @@ class CollectTaxonImages(MetaAppFormLanguageMixin, TemplateView):
|
|
|
744
750
|
return images
|
|
745
751
|
|
|
746
752
|
def get_taxon_images(self, exclude=[]):
|
|
747
|
-
|
|
748
|
-
|
|
753
|
+
|
|
754
|
+
images = []
|
|
755
|
+
|
|
756
|
+
if not self.taxon_profile.morphotype:
|
|
757
|
+
images = ContentImage.objects.filter(image_store__taxon_source=self.taxon.taxon_source,
|
|
758
|
+
image_store__taxon_latname=self.taxon.taxon_latname).exclude(pk__in=exclude)
|
|
749
759
|
|
|
750
760
|
return images
|
|
751
761
|
|
|
752
762
|
# images can be on MetNode or NatureGuidesTaxonTree
|
|
753
763
|
def get_nature_guide_images(self, exclude=[]):
|
|
754
764
|
|
|
755
|
-
meta_nodes = MetaNode.objects.filter(taxon_source=self.taxon.taxon_source,
|
|
756
|
-
taxon_latname=self.taxon.taxon_latname, taxon_author=self.taxon.taxon_author, morphotype=self.morphotype)
|
|
757
|
-
|
|
758
765
|
nature_guide_images = []
|
|
766
|
+
|
|
767
|
+
if not self.taxon_profile.morphotype:
|
|
768
|
+
|
|
769
|
+
meta_nodes = MetaNode.objects.filter(taxon_source=self.taxon.taxon_source,
|
|
770
|
+
taxon_latname=self.taxon.taxon_latname, taxon_author=self.taxon.taxon_author, morphotype=self.morphotype)
|
|
759
771
|
|
|
760
|
-
|
|
772
|
+
if meta_nodes:
|
|
761
773
|
|
|
762
|
-
|
|
774
|
+
meta_node_ids = meta_nodes.values_list('id', flat=True)
|
|
763
775
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
776
|
+
meta_node_content_type = ContentType.objects.get_for_model(MetaNode)
|
|
777
|
+
meta_node_images = ContentImage.objects.filter(content_type=meta_node_content_type,
|
|
778
|
+
object_id__in=meta_node_ids).exclude(pk__in=exclude)
|
|
779
|
+
|
|
780
|
+
exclude += list(meta_node_images.values_list('id', flat=True))
|
|
781
|
+
nature_guide_images += list(meta_node_images)
|
|
770
782
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
783
|
+
|
|
784
|
+
nodes = NatureGuidesTaxonTree.objects.filter(meta_node__taxon_source=self.taxon.taxon_source,
|
|
785
|
+
meta_node__taxon_latname=self.taxon.taxon_latname,
|
|
786
|
+
meta_node__taxon_author=self.taxon.taxon_author)
|
|
775
787
|
|
|
776
|
-
|
|
788
|
+
if nodes:
|
|
777
789
|
|
|
778
|
-
|
|
790
|
+
node_ids = nodes.values_list('id', flat=True)
|
|
779
791
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
792
|
+
node_content_type = ContentType.objects.get_for_model(NatureGuidesTaxonTree)
|
|
793
|
+
node_images = ContentImage.objects.filter(content_type=node_content_type,
|
|
794
|
+
object_id__in=node_ids).exclude(pk__in=exclude)
|
|
795
|
+
|
|
796
|
+
nature_guide_images += list(node_images)
|
|
785
797
|
|
|
786
798
|
|
|
787
799
|
return nature_guide_images
|
|
@@ -37,10 +37,10 @@ app_kit/app_kit_api/tests/__pycache__/test_serializers.cpython-311.pyc,sha256=Xv
|
|
|
37
37
|
app_kit/app_kit_api/tests/__pycache__/test_views.cpython-311.pyc,sha256=jzyuIXHjnoubiVjdoa5h2YxGSTAomhTxhyxfZBqVf1o,10161
|
|
38
38
|
app_kit/appbuilder/AppBuilderBase.py,sha256=mDwmMd0Fdl-wedTYWEK8AcHfiAhvjxFBGOkLrGavwTs,29160
|
|
39
39
|
app_kit/appbuilder/AppPreviewBuilder.py,sha256=C0oSh_i1Cx4vLW01T0qJeo-MrtqqjD72Hh43k4kG5EI,6845
|
|
40
|
-
app_kit/appbuilder/AppReleaseBuilder.py,sha256=
|
|
40
|
+
app_kit/appbuilder/AppReleaseBuilder.py,sha256=up6NEc5l46FdPBWH2iW6XZKMET_s1PEJ4Jq2J0Wiges,134050
|
|
41
41
|
app_kit/appbuilder/ContentImageBuilder.py,sha256=k9YdH2d5oIyfbeoA9H_DaUigc1SQ69WnXFy9e00DdfA,7332
|
|
42
42
|
app_kit/appbuilder/GBIFlib.py,sha256=iGj01hrk0iG-qjEkPM8ez_lNKL_zJedPTS3oUZDd8vg,989
|
|
43
|
-
app_kit/appbuilder/TaxonBuilder.py,sha256=
|
|
43
|
+
app_kit/appbuilder/TaxonBuilder.py,sha256=BQcu1EWn-eGrTZhrbVCDdRsjBQ9nsjpUKaJMIXgbA8A,16390
|
|
44
44
|
app_kit/appbuilder/__init__.py,sha256=PIqSBvR4NFND1zb_KOryk3PFZ5yhiGwaZIZSRSTp1JY,152
|
|
45
45
|
app_kit/appbuilder/precompile_fulltree.py,sha256=Lrf5j0xGY2FgpuuWdUrfef1ZlLs-GntFYpngtZ5pTF0,2005
|
|
46
46
|
app_kit/appbuilder/JSONBuilders/BackboneTaxonomyJSONBuilder.py,sha256=worozLAgqxKJSdBzQ45zlCL3l4BnpZAYX-Dl4SfmwUs,6488
|
|
@@ -52,7 +52,7 @@ app_kit/appbuilder/JSONBuilders/GlossaryJSONBuilder.py,sha256=7pITMctTmEVRbyb7Dl
|
|
|
52
52
|
app_kit/appbuilder/JSONBuilders/JSONBuilder.py,sha256=BssXm7ueXghCmHHmWsnQekQdbE4g0UIIQ59a6k0Bzts,6010
|
|
53
53
|
app_kit/appbuilder/JSONBuilders/MapJSONBuilder.py,sha256=NgP5g_H0sfq5VRkoHdMzkQUGLgUofcwG1R2xe6vUS9U,2792
|
|
54
54
|
app_kit/appbuilder/JSONBuilders/NatureGuideJSONBuilder.py,sha256=LZgyfc0e2xhTB9XES6fgm_vmL-O7VBBXsRdNDapgu5E,25498
|
|
55
|
-
app_kit/appbuilder/JSONBuilders/TaxonProfilesJSONBuilder.py,sha256=
|
|
55
|
+
app_kit/appbuilder/JSONBuilders/TaxonProfilesJSONBuilder.py,sha256=tvHz0--awo5Rvsc_nPNGvwbPKLAuNXUh4RX0erZOTZM,36345
|
|
56
56
|
app_kit/appbuilder/JSONBuilders/TemplateContentJSONBuilder.py,sha256=zWF7SNeRosbOi876boXp0tpIYXVs04fKtauK9Fr_DRs,7382
|
|
57
57
|
app_kit/appbuilder/JSONBuilders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
58
|
app_kit/appbuilder/JSONBuilders/generic_forms_JSON_specification,sha256=dFabBHtkfzJqB2zNSRR2OaIyroYr1nEw_qY6VFZF7dQ,6720
|
|
@@ -74,7 +74,7 @@ app_kit/appbuilder/JSONBuilders/__pycache__/NatureGuideJSONBuilder.cpython-311.p
|
|
|
74
74
|
app_kit/appbuilder/JSONBuilders/__pycache__/NatureGuideJSONBuilder.cpython-313.pyc,sha256=jF5kdrd9eYsIuLJtophN4ptZB67MM1poI4Oao2aY8RU,25376
|
|
75
75
|
app_kit/appbuilder/JSONBuilders/__pycache__/TaxonJSONBuilder.cpython-311.pyc,sha256=nEt3jd6Pf4lb0QnFpU7QPg9bsKa68z0Vh8C85t4CMO0,9663
|
|
76
76
|
app_kit/appbuilder/JSONBuilders/__pycache__/TaxonProfilesJSONBuilder.cpython-311.pyc,sha256=bffiRE-WzCN3s0sz00rFuuu8c0qFL7kRq97XwtuRnoo,22862
|
|
77
|
-
app_kit/appbuilder/JSONBuilders/__pycache__/TaxonProfilesJSONBuilder.cpython-313.pyc,sha256
|
|
77
|
+
app_kit/appbuilder/JSONBuilders/__pycache__/TaxonProfilesJSONBuilder.cpython-313.pyc,sha256=y3XVQ4f5zXWVClaO6vQLNXKklpt7K4ymnix51Xnu5Ok,29288
|
|
78
78
|
app_kit/appbuilder/JSONBuilders/__pycache__/TemplateContentJSONBuilder.cpython-311.pyc,sha256=7fGagTetGK129h057h6dPXMSwggBX03uHOm3_dr3ueE,5932
|
|
79
79
|
app_kit/appbuilder/JSONBuilders/__pycache__/TemplateContentJSONBuilder.cpython-313.pyc,sha256=lXf1kZuOMRWsHmnP1aN7UJIPEfWF-PhiMyyZ9FfY1Tg,6501
|
|
80
80
|
app_kit/appbuilder/JSONBuilders/__pycache__/__init__.cpython-311.pyc,sha256=MxwSyVkGIkNVrjjMZzXCHh9k7_ytM6tzgpNTaCtDNn4,211
|
|
@@ -84,13 +84,13 @@ app_kit/appbuilder/__pycache__/AppBuilderBase.cpython-313.pyc,sha256=GTLt_n208ej
|
|
|
84
84
|
app_kit/appbuilder/__pycache__/AppPreviewBuilder.cpython-311.pyc,sha256=5kKHNjUuOfp31cqB_ZO175x-wGgVVhqX8YkHWSlX--k,8245
|
|
85
85
|
app_kit/appbuilder/__pycache__/AppPreviewBuilder.cpython-313.pyc,sha256=C7-mLN6yGvDrknbBamjKkI9fxjfT3djrdr3-8Fhc7HQ,7526
|
|
86
86
|
app_kit/appbuilder/__pycache__/AppReleaseBuilder.cpython-311.pyc,sha256=ZAHDJfyKvQzTsyFHIjvRjCiCn1dzObCPp6XYWCGHZmI,126739
|
|
87
|
-
app_kit/appbuilder/__pycache__/AppReleaseBuilder.cpython-313.pyc,sha256=
|
|
87
|
+
app_kit/appbuilder/__pycache__/AppReleaseBuilder.cpython-313.pyc,sha256=_88iSOHywr1q1eKR6zJLdemnjwvIrL2kldxx0mZcrT0,131779
|
|
88
88
|
app_kit/appbuilder/__pycache__/ContentImageBuilder.cpython-311.pyc,sha256=EyL2LamJkdU_7O_F0j3vwtTYjInblFSPKmlPLyXvSuE,8920
|
|
89
89
|
app_kit/appbuilder/__pycache__/ContentImageBuilder.cpython-313.pyc,sha256=K6b-GlHYhM0SWlniDyyFfKdK_QF7kHN8yFahn2ETCa8,8737
|
|
90
90
|
app_kit/appbuilder/__pycache__/GBIFlib.cpython-311.pyc,sha256=NNB_AHGQnN0ld82WuJHxGn5RthLO_fGkpVAfAHaDyMU,1945
|
|
91
91
|
app_kit/appbuilder/__pycache__/GBIFlib.cpython-313.pyc,sha256=13SE5Ayqrg8n90KGWbLE7rQ-UPaU2Q0XbY5dQENpXTA,1962
|
|
92
92
|
app_kit/appbuilder/__pycache__/TaxonBuilder.cpython-311.pyc,sha256=7JVnCo4-CVmaX_EIzU05is5ySaqWPA86QBlFM-B4Trw,16273
|
|
93
|
-
app_kit/appbuilder/__pycache__/TaxonBuilder.cpython-313.pyc,sha256=
|
|
93
|
+
app_kit/appbuilder/__pycache__/TaxonBuilder.cpython-313.pyc,sha256=fNSv6AE_6jLLNiXE4SFVpSHv6_hVkeSUIGmaFJxLkao,17166
|
|
94
94
|
app_kit/appbuilder/__pycache__/__init__.cpython-311.pyc,sha256=KkcyxSIx1hiGZkOwMG8qWGJQ-RPacWMKpfpnP-naNv4,388
|
|
95
95
|
app_kit/appbuilder/__pycache__/__init__.cpython-313.pyc,sha256=iHwg7gUn2XzOOz0SNmIeY6GVMxTcc5NKM3gzSz4pLnA,329
|
|
96
96
|
app_kit/appbuilder/app/frontends/Multiverse/settings.json,sha256=dCcy0ZGor57YhlrPUJVj-IADrF413gBBWFUfletZW6g,2026
|
|
@@ -154,7 +154,7 @@ app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/add_taxon_form.html
|
|
|
154
154
|
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/manage_backbone_taxa_form.html,sha256=wVUAExurrDbck2SD9pwL4IWdOx0Z-QHWU9idNbnc5VY,1529
|
|
155
155
|
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/manage_backbonetaxonomy.html,sha256=0EehuPUlE6-g7miYOycv_j2aZPqmU-Ykwd_bpC3LdMM,4101
|
|
156
156
|
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/manage_fulltree_form.html,sha256=uqw8OL3dGy7_iZzGxgGc3KHNSsGHVBniBx2FQSrM8h0,622
|
|
157
|
-
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/manage_taxon.html,sha256=
|
|
157
|
+
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/manage_taxon.html,sha256=Rsn0XHwq4n_Zk4iPVi_MKb3sB6z6L2KeaZPP82tZi4Y,1846
|
|
158
158
|
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/remove_backbone_taxon.html,sha256=-9t83d771KmyoeENWqvxrxyoI7zOK5-sHL_rLdHxsP0,1206
|
|
159
159
|
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/swap_taxon.html,sha256=6soId42pD0s-vxCSNE8RNNotSfSWOINmMk3Eyo9hlMM,7469
|
|
160
160
|
app_kit/features/backbonetaxonomy/templates/backbonetaxonomy/taxon_relationships.html,sha256=jBFcbS1CJnd0b9IqSMGcfDFR-tmHygOs4wSBfFekPEo,5503
|
|
@@ -398,10 +398,10 @@ app_kit/features/nature_guides/tests/__pycache__/test_views.cpython-311.pyc,sha2
|
|
|
398
398
|
app_kit/features/taxon_profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
399
399
|
app_kit/features/taxon_profiles/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
|
|
400
400
|
app_kit/features/taxon_profiles/apps.py,sha256=c0nynglV50B8qvXTnu7v6LZHT6N5nOTayOasKICAAJE,119
|
|
401
|
-
app_kit/features/taxon_profiles/forms.py,sha256=
|
|
402
|
-
app_kit/features/taxon_profiles/models.py,sha256=
|
|
403
|
-
app_kit/features/taxon_profiles/urls.py,sha256=
|
|
404
|
-
app_kit/features/taxon_profiles/views.py,sha256=
|
|
401
|
+
app_kit/features/taxon_profiles/forms.py,sha256=jBvYFgKAG9_gpCG3dfE97KQTnTiKjTIOQenmeXVE62g,16131
|
|
402
|
+
app_kit/features/taxon_profiles/models.py,sha256=kllsA7VTgD5a8KVyHAUV0udMcv7Keg5hd5x1LcrmR3I,23855
|
|
403
|
+
app_kit/features/taxon_profiles/urls.py,sha256=IhJOF7HIPOw-VanBzJtSanKOdAgWL1vKy9evcHD3Bzw,11098
|
|
404
|
+
app_kit/features/taxon_profiles/views.py,sha256=gIZTKT7bdnHOBhNgLqpLsTtkAjARbMPDnHC4Y1lXoBQ,61750
|
|
405
405
|
app_kit/features/taxon_profiles/zip_import.py,sha256=aYFEtaMjn5Qebj0eaOeM-WVdvMUDymH4wUOnhAItN9I,29883
|
|
406
406
|
app_kit/features/taxon_profiles/migrations/0001_initial.py,sha256=aknHwoaZMBwDWMnp7dftXToVGuyN4f9xy3epQSqGkxQ,3659
|
|
407
407
|
app_kit/features/taxon_profiles/migrations/0002_taxontext_long_text.py,sha256=FN2GAdO4paIgX8FpREoLk7cihlHRRaehVY7_Ve0K97w,383
|
|
@@ -418,7 +418,7 @@ app_kit/features/taxon_profiles/migrations/0012_taxonprofile_updated_at.py,sha25
|
|
|
418
418
|
app_kit/features/taxon_profiles/migrations/0013_alter_taxonprofile_options_and_more.py,sha256=03fp39qqKjBJOiUspog7BzgxVg80lZJ8vq8dZhq8K98,596
|
|
419
419
|
app_kit/features/taxon_profiles/migrations/0014_alter_taxonprofile_unique_together_and_more.py,sha256=wPO0TfoU_I9_BBLOSe3gvzMzEeGpxP5exnwuGT_ngUU,2501
|
|
420
420
|
app_kit/features/taxon_profiles/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
421
|
-
app_kit/features/taxon_profiles/templates/taxon_profiles/manage_taxon_profile.html,sha256=
|
|
421
|
+
app_kit/features/taxon_profiles/templates/taxon_profiles/manage_taxon_profile.html,sha256=i04Bvrb5fKgxnD4oCUaqTcTf2D3RsQElmg7LHUe8HEE,11059
|
|
422
422
|
app_kit/features/taxon_profiles/templates/taxon_profiles/manage_taxon_profiles.html,sha256=NJGnmoa5da40e-hUpZAG2V-UZGqf_oxAd8bIABfuaKw,9304
|
|
423
423
|
app_kit/features/taxon_profiles/templates/taxon_profiles/manage_taxon_texts.html,sha256=q1Do_NKTwkQ8sHWY4Zx4CXaWbpfFBGxn6_8Uc3N4EVA,1353
|
|
424
424
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/backbone_taxa_taxonlist.html,sha256=6zEHqwPnU0bJJmyQqkXxWw90D0IQ1WPtm4sCCKXFJMQ,656
|
|
@@ -427,7 +427,7 @@ app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/change_navigation_
|
|
|
427
427
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/change_taxon_profile_publication_status.html,sha256=zuDHrJc77sAVLCmFmhvUMyJSYVQu8zQT_RC0PwavTiI,596
|
|
428
428
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/collected_taxon_images.html,sha256=a6HQJ6p4QMSpDqYraentxFyGmIxs-5uypFbWIyoR4q8,3654
|
|
429
429
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/collected_taxon_traits.html,sha256=PkA7sGNPBFQ_t1Pb4X1avCd_n9SVFKedN0BIsYyB0Eg,2470
|
|
430
|
-
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/create_taxon_profile.html,sha256=
|
|
430
|
+
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/create_taxon_profile.html,sha256=jbyin1419LNIbBltUmvN4S02K9jq2vgdJwGz3Dh8dSs,1056
|
|
431
431
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/delete_all_manually_added_images.html,sha256=_zOaLGeVD3AKPmIzwRTr-eHi0Lo38dOTsSzYI-Oz_rE,1022
|
|
432
432
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/delete_navigation_entry.html,sha256=kCNgH9qiAvF5Y3XP6UPA-XZeFb0Uw2CZakkYY-JjZD0,226
|
|
433
433
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/delete_navigation_entry_taxon.html,sha256=xn3CFCzn1qZS5tM76GeQn4-2_WL4zLo5OxUTAD47XiQ,410
|
|
@@ -438,19 +438,19 @@ app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/delete_taxon_text_
|
|
|
438
438
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/delete_taxon_text_type_category.html,sha256=mIgqNz2dcZyl-6U2bClztlERrSCzct5RhOnY_KB51tA,381
|
|
439
439
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_navigation_entry.html,sha256=a_Cydkty0fWKIOzcnXOa0US-eLrjKI_y8LaI4unxeC0,2497
|
|
440
440
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_navigation_image.html,sha256=9uAZLbs5Rs4Xew3ua-0BOT4MzLXjW25XjgO73vPJxP8,872
|
|
441
|
-
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_form.html,sha256=
|
|
441
|
+
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_form.html,sha256=VbfbX5xrfhzjBealfy49tbzZf4Z0wFXc7UvujzuMvnw,3089
|
|
442
442
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_image.html,sha256=TORQADZVRluI4VN3D_0cKJsKhEJu7y8JgOR-sDv6INU,1141
|
|
443
|
-
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_morphotype.html,sha256=
|
|
443
|
+
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_profile_morphotype.html,sha256=eVyORlAKHmHjB3crC1uTusXhmYOz72Fo2Hd3fwT00nA,1049
|
|
444
444
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_taxon_text_set.html,sha256=E98YJtky7fBZxPiP_gkT6LxaRHtN5BDPgc0ow3mU93I,1148
|
|
445
445
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_text_type.html,sha256=XFkHIQsxGFndUCMK5U-b0E48Fibbod2mlYw51DUcbWk,1404
|
|
446
446
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/manage_text_type_category.html,sha256=5aS1gI4kXOms7TWBiGIOp37Z56TzC4QyhHBuoJlkBCs,1391
|
|
447
447
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/move_image_to_section.html,sha256=IVpYDx7oLL16auz9D5rSXA6PMChPLhT6IsmQsuYkELg,585
|
|
448
448
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/move_navigation_entry.html,sha256=mZ-e8N8j-XhFaueIOpJSGv8knL2iX20i_FvQSeqS5uE,2158
|
|
449
|
-
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/nature_guide_taxonlist.html,sha256=
|
|
449
|
+
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/nature_guide_taxonlist.html,sha256=dXtTcymXITUEoBsGe2XoTSbifyacPLjD0NX539cVyRU,1911
|
|
450
450
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/navigation_entry_taxa.html,sha256=6UeTMqrtUCU7WEzZBK_yT9HquxxFWONRekiwoj7jh5U,2063
|
|
451
451
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/navigation_entry_taxon_profiles.html,sha256=m3IaC1yd4lvpRTV8CnSOM60pFxZukIndmCw_Yv-Yorw,910
|
|
452
452
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/navigation_entry_taxon_profiles_list.html,sha256=DrSBBxOOMSUYBZj7-XCPvmDkWB_Y8587AVlrCLPVrxE,431
|
|
453
|
-
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/non_nature_guide_taxonlist.html,sha256=
|
|
453
|
+
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/non_nature_guide_taxonlist.html,sha256=4sLthyIACNopPz7ev1A4866M3nxRpkrhZEgR3eT3Smo,582
|
|
454
454
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/set_taxon_text_set_for_taxon_profile.html,sha256=M92q0Qh2RB-Lxi717_EctdZbrp7v7kd1BMdrclkaQ8Q,611
|
|
455
455
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/taxon_profiles_navigation.html,sha256=a098AWlYiJae0V23YMwXx1JsPW0D_4DI1ASMn4E9Sx4,980
|
|
456
456
|
app_kit/features/taxon_profiles/templates/taxon_profiles/ajax/taxon_profiles_navigation_level.html,sha256=GY0KFR7BPiLsiMIVy8xRukZpbsQ6q7RBE3QiaR7506s,6204
|
|
@@ -1903,7 +1903,6 @@ app_kit/tests/TESTS_ROOT/images/app-background.jpg,sha256=bmW6cudSfmcRqGSK9P2Sc5
|
|
|
1903
1903
|
app_kit/tests/TESTS_ROOT/images/localcosmos-logo.svg,sha256=4-MHj0FjED9eTgmUHnAP-DHCQRqc557HH9akHaoQxs0,409549
|
|
1904
1904
|
app_kit/tests/TESTS_ROOT/images/test-image-2560-1440.jpg,sha256=BOP-1ZlA9wq-E1sUkOpyqUowpFCdSoF965oKgajjSq0,156278
|
|
1905
1905
|
app_kit/tests/TESTS_ROOT/ipa_for_tests/TestApp.ipa,sha256=YdGWqMepeBwvpkch3DSVMlnNkf8RuGwENWuwHtoY1Do,78900
|
|
1906
|
-
app_kit/tests/TESTS_ROOT/media_for_tests/test/imagestore/31/a6a11b61d65ee19c4c22caa0682288ff.jpg,sha256=dXT6yUqaMJ_91rwQMHT22VjDGb69KRCmm4eboxjtnxM,49349
|
|
1907
1906
|
app_kit/tests/TESTS_ROOT/templates/neobiota.html,sha256=3ag2VGCuaZ-FoAu25GMUb3s4qMsY7AyhNoDf7CSZJ_w,147
|
|
1908
1907
|
app_kit/tests/TESTS_ROOT/xlsx_for_testing/BackboneTaxonomy/invalid/Backbone taxonomy.xlsx,sha256=cMkmCtGBR1wwhpDSbjrscNSvLMGnb6YbaliQqws-l7M,8121
|
|
1909
1908
|
app_kit/tests/TESTS_ROOT/xlsx_for_testing/BackboneTaxonomy/invalid_content_type/Backbone taxonomy.xlsx,sha256=aYRrPI-UABxQUZF-bWvbrD_31ZQgEijdKCzBGOXzGRk,7996
|
|
@@ -1939,8 +1938,8 @@ app_kit/tests/__pycache__/test_models.cpython-313.pyc,sha256=Lmv3BfjLs5Fg-olJeMl
|
|
|
1939
1938
|
app_kit/tests/__pycache__/test_utils.cpython-313.pyc,sha256=GX3REqZygi2eO_A2F2_KtYi7hg54X5QPtCTCGWuxGpM,14054
|
|
1940
1939
|
app_kit/tests/__pycache__/test_views.cpython-311.pyc,sha256=NDJR40TcMm-bXXC-wV7OgH1sGR3N7psSWYiUirkkrjU,133242
|
|
1941
1940
|
app_kit/tests/__pycache__/test_views.cpython-313.pyc,sha256=q851UqIZFCCTfQb1lF4SVxV1j_Vu1hJdOlpckmrGX28,125363
|
|
1942
|
-
localcosmos_app_kit-0.
|
|
1943
|
-
localcosmos_app_kit-0.
|
|
1944
|
-
localcosmos_app_kit-0.
|
|
1945
|
-
localcosmos_app_kit-0.
|
|
1946
|
-
localcosmos_app_kit-0.
|
|
1941
|
+
localcosmos_app_kit-0.10.0.dist-info/licenses/LICENCE,sha256=VnxALPSxXoU59rlNeRdJtwS_nU79IFpVWsZZCQUM4Mw,1086
|
|
1942
|
+
localcosmos_app_kit-0.10.0.dist-info/METADATA,sha256=pVHi86lhY2n4lU4kKq5TLikiIHOxHWFiEerAaFnNzqw,1388
|
|
1943
|
+
localcosmos_app_kit-0.10.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
1944
|
+
localcosmos_app_kit-0.10.0.dist-info/top_level.txt,sha256=F6H4pEBkCvUR_iwQHIy4K1iby-jzfWg3CTym5XJKeys,8
|
|
1945
|
+
localcosmos_app_kit-0.10.0.dist-info/RECORD,,
|
app_kit/tests/TESTS_ROOT/media_for_tests/test/imagestore/31/a6a11b61d65ee19c4c22caa0682288ff.jpg
DELETED
|
Binary file
|
|
File without changes
|
{localcosmos_app_kit-0.9.18.dist-info → localcosmos_app_kit-0.10.0.dist-info}/licenses/LICENCE
RENAMED
|
File without changes
|
|
File without changes
|