diff --git a/geonode/api/api.py b/geonode/api/api.py index 3cf8eb7ecc5..6a2fde99864 100644 --- a/geonode/api/api.py +++ b/geonode/api/api.py @@ -528,7 +528,7 @@ def dehydrate(self, bundle): documents_count=bundle.data.get('documents_count', 0), maps_count=bundle.data.get('maps_count', 0), layers_count=bundle.data.get('layers_count', 0), - ) + ) return bundle def prepend_urls(self): diff --git a/geonode/api/resourcebase_api.py b/geonode/api/resourcebase_api.py index f129bd2bde0..6b6cc63f613 100644 --- a/geonode/api/resourcebase_api.py +++ b/geonode/api/resourcebase_api.py @@ -363,12 +363,11 @@ def build_haystack_filters(self, parameters): if len(subtypes) > 0: types.append("layer") - sqs = SearchQuerySet().narrow("subtype:%s" % - ','.join(map(str, subtypes))) + sqs = SearchQuerySet().narrow(f"subtype:{','.join(map(str, subtypes))}") if len(types) > 0: sqs = (SearchQuerySet() if sqs is None else sqs).narrow( - "type:%s" % ','.join(map(str, types))) + f"type:{','.join(map(str, types))}") # Filter by Query Params # haystack bug? if boosted fields aren't included in the @@ -414,7 +413,7 @@ def build_haystack_filters(self, parameters): # filter by category if category: sqs = (SearchQuerySet() if sqs is None else sqs).narrow( - 'category:%s' % ','.join(map(str, category))) + f"category:{','.join(map(str, category))}") # filter by keyword: use filter_or with keywords_exact # not using exact leads to fuzzy matching and too many results @@ -440,7 +439,7 @@ def build_haystack_filters(self, parameters): if owner: sqs = ( SearchQuerySet() if sqs is None else sqs).narrow( - "owner__username:%s" % ','.join(map(str, owner))) + f"owner__username:{','.join(map(str, owner))}") # filter by date if date_start: diff --git a/geonode/api/tests.py b/geonode/api/tests.py index faad86cc66a..87a87738544 100644 --- a/geonode/api/tests.py +++ b/geonode/api/tests.py @@ -432,7 +432,8 @@ def to_date(val): def test_extended_text_filter(self): """Test that the extended text filter works as expected""" - filter_url = f"{self.list_url}?title__icontains=layer2&abstract__icontains=layer2&purpose__icontains=layer2&f_method=or" + filter_url = (f"{self.list_url}?title__icontains=layer2&abstract__icontains=layer2" + f"&purpose__icontains=layer2&f_method=or") resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) diff --git a/geonode/api/views.py b/geonode/api/views.py index 7698e1c27b4..824c5f49d21 100644 --- a/geonode/api/views.py +++ b/geonode/api/views.py @@ -141,7 +141,7 @@ def verify_token(request): token_info, content_type="application/json" ) - response["Authorization"] = ("Bearer %s" % access_token) + response["Authorization"] = f"Bearer {access_token}" return response else: return HttpResponse( diff --git a/geonode/base/forms.py b/geonode/base/forms.py index d472157a934..63ec5a74e6c 100644 --- a/geonode/base/forms.py +++ b/geonode/base/forms.py @@ -69,7 +69,7 @@ def rectree(parent, path): children_list_of_tuples.append( tuple((path + parent.name, tuple((child.id, child.name)))) ) - childrens = rectree(child, parent.name + '/') + childrens = rectree(child, f"{parent.name}/") if childrens: children_list_of_tuples.extend(childrens) @@ -112,10 +112,10 @@ def _get_choices(self): def label_from_instance(self, obj): return '' \ - '' \ - '' \ - '
' + obj.gn_description + '
' + '' \ + '' \ + '
' + obj.gn_description + '
' # NOTE: This is commented as it needs updating to work with select2 and autocomlete light. @@ -283,7 +283,7 @@ def _region_id_from_choice(choice): class CategoryForm(forms.Form): category_choice_field = CategoryChoiceField( required=False, - label='*' + _('Category'), + label=f"*{_('Category')}", empty_label=None, queryset=TopicCategory.objects.filter( is_choice=True).extra( @@ -448,7 +448,7 @@ def clean_keywords(self): _kk = _kk.replace('%u', r'\u').encode('unicode-escape').replace( b'\\\\u', b'\\u').decode('unicode-escape') if '%u' in _kk else _kk - _hk = HierarchicalKeyword.objects.filter(name__iexact='%s' % _kk.strip()) + _hk = HierarchicalKeyword.objects.filter(name__iexact=f'{_kk.strip()}') if _hk and len(_hk) > 0: _unsescaped_kwds.append(str(_hk[0])) else: diff --git a/geonode/base/management/commands/fixoauthuri.py b/geonode/base/management/commands/fixoauthuri.py index ca3c16f4afd..93a3348c757 100644 --- a/geonode/base/management/commands/fixoauthuri.py +++ b/geonode/base/management/commands/fixoauthuri.py @@ -86,4 +86,4 @@ def handle(self, *args, **options): client_secret=client_secret, user=get_user_model().objects.filter(is_superuser=True)[0] ) - return '%s,%s' % (client_id, client_secret) + return f'{client_id},{client_secret}' diff --git a/geonode/base/management/commands/helpers.py b/geonode/base/management/commands/helpers.py index 6558e6a86bd..dc0ccc17d1d 100644 --- a/geonode/base/management/commands/helpers.py +++ b/geonode/base/management/commands/helpers.py @@ -47,9 +47,9 @@ def confirm(prompt=None, resp=False): prompt = 'Confirm' if resp: - prompt = '%s [%s]|%s: ' % (prompt, 'y', 'n') + prompt = f"{prompt} [{'y'}]|{'n'}: " else: - prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y') + prompt = f"{prompt} [{'n'}]|{'y'}: " while True: ans = six.moves.input(prompt) diff --git a/geonode/base/management/commands/load_thesaurus.py b/geonode/base/management/commands/load_thesaurus.py index b95f195cd04..b0dc5f6648a 100644 --- a/geonode/base/management/commands/load_thesaurus.py +++ b/geonode/base/management/commands/load_thesaurus.py @@ -72,8 +72,8 @@ def load_thesaurus(self, input_file, name, store): RDF_URI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' XML_URI = 'http://www.w3.org/XML/1998/namespace' - ABOUT_ATTRIB = '{' + RDF_URI + '}about' - LANG_ATTRIB = '{' + XML_URI + '}lang' + ABOUT_ATTRIB = f"{{{RDF_URI}}}about" + LANG_ATTRIB = f"{{{XML_URI}}}lang" ns = { 'rdf': RDF_URI, @@ -94,7 +94,7 @@ def load_thesaurus(self, input_file, name, store): descr = scheme.find('dc:description', ns).text if scheme.find('dc:description', ns) else title date_issued = scheme.find('dcterms:issued', ns).text - print('Thesaurus "{}" issued on {}'.format(title, date_issued)) + print(f'Thesaurus "{title}" issued on {date_issued}') thesaurus = Thesaurus() thesaurus.identifier = name @@ -110,7 +110,7 @@ def load_thesaurus(self, input_file, name, store): about = concept.attrib.get(ABOUT_ATTRIB) alt_label = concept.find('skos:altLabel', ns).text - print('Concept {} ({})'.format(alt_label, about)) + print(f'Concept {alt_label} ({about})') tk = ThesaurusKeyword() tk.thesaurus = thesaurus @@ -124,7 +124,7 @@ def load_thesaurus(self, input_file, name, store): lang = pref_label.attrib.get(LANG_ATTRIB) label = pref_label.text - print(' Label {}: {}'.format(lang, label)) + print(f' Label {lang}: {label}') tkl = ThesaurusKeywordLabel() tkl.keyword = tk @@ -138,7 +138,7 @@ def create_fake_thesaurus(self, name): thesaurus = Thesaurus() thesaurus.identifier = name - thesaurus.title = "Title: " + name + thesaurus.title = f"Title: {name}" thesaurus.description = "SAMPLE FAKE THESAURUS USED FOR TESTING" thesaurus.date = "2016-10-01" @@ -147,13 +147,13 @@ def create_fake_thesaurus(self, name): for keyword in ['aaa', 'bbb', 'ccc']: tk = ThesaurusKeyword() tk.thesaurus = thesaurus - tk.about = keyword + '_about' - tk.alt_label = keyword + '_alt' + tk.about = f"{keyword}_about" + tk.alt_label = f"{keyword}_alt" tk.save() for l in ['it', 'en', 'es']: tkl = ThesaurusKeywordLabel() tkl.keyword = tk tkl.lang = l - tkl.label = keyword + "_l_" + l + "_t_" + name + tkl.label = f"{keyword}_l_{l}_t_{name}" tkl.save() diff --git a/geonode/base/management/commands/migrate_baseurl.py b/geonode/base/management/commands/migrate_baseurl.py index 2ef3d96e117..78fc9cdfb47 100644 --- a/geonode/base/management/commands/migrate_baseurl.py +++ b/geonode/base/management/commands/migrate_baseurl.py @@ -74,8 +74,7 @@ def handle(self, **options): if not target_address or len(target_address) == 0: raise CommandError("Target Address '--target-address' is mandatory") - print("This will change all Maps, Layers, \ -Styles and Links Base URLs from [%s] to [%s]." % (source_address, target_address)) + print(f"This will change all Maps, Layers, Styles and Links Base URLs from [{source_address}] to [{target_address}].") print("The operation may take some time, depending on the amount of Layer on GeoNode.") message = 'You want to proceed?' @@ -84,7 +83,7 @@ def handle(self, **options): _cnt = Map.objects.filter(thumbnail_url__icontains=source_address).update( thumbnail_url=Func( F('thumbnail_url'),Value(source_address),Value(target_address),function='replace')) - logger.info("Updated %s Maps" % _cnt) + logger.info(f"Updated {_cnt} Maps") _cnt = MapLayer.objects.filter(ows_url__icontains=source_address).update( ows_url=Func( @@ -92,22 +91,22 @@ def handle(self, **options): MapLayer.objects.filter(layer_params__icontains=source_address).update( layer_params=Func( F('layer_params'),Value(source_address),Value(target_address),function='replace')) - logger.info("Updated %s MapLayers" % _cnt) + logger.info(f"Updated {_cnt} MapLayers") _cnt = Layer.objects.filter(thumbnail_url__icontains=source_address).update( thumbnail_url=Func( F('thumbnail_url'),Value(source_address),Value(target_address),function='replace')) - logger.info("Updated %s Layers" % _cnt) + logger.info(f"Updated {_cnt} Layers") _cnt = Style.objects.filter(sld_url__icontains=source_address).update( sld_url=Func( F('sld_url'),Value(source_address),Value(target_address),function='replace')) - logger.info("Updated %s Styles" % _cnt) + logger.info(f"Updated {_cnt} Styles") _cnt = Link.objects.filter(url__icontains=source_address).update( url=Func( F('url'),Value(source_address),Value(target_address),function='replace')) - logger.info("Updated %s Links" % _cnt) + logger.info(f"Updated {_cnt} Links") _cnt = ResourceBase.objects.filter(thumbnail_url__icontains=source_address).update( thumbnail_url=Func( @@ -118,7 +117,7 @@ def handle(self, **options): _cnt += ResourceBase.objects.filter(metadata_xml__icontains=source_address).update( metadata_xml=Func( F('metadata_xml'), Value(source_address), Value(target_address), function='replace')) - logger.info("Updated %s ResourceBases" % _cnt) + logger.info(f"Updated {_cnt} ResourceBases") site = Site.objects.get_current() if site: @@ -132,7 +131,7 @@ def handle(self, **options): _cnt = Application.objects.filter(name='GeoServer').update( redirect_uris=Func( F('redirect_uris'), Value(source_address), Value(target_address), function='replace')) - logger.info("Updated %s OAUth2 Redirect URIs" % _cnt) + logger.info(f"Updated {_cnt} OAUth2 Redirect URIs") finally: print("...done!") diff --git a/geonode/base/management/commands/set_all_layers_alternate.py b/geonode/base/management/commands/set_all_layers_alternate.py index 666b93c44de..4e20cc9e338 100644 --- a/geonode/base/management/commands/set_all_layers_alternate.py +++ b/geonode/base/management/commands/set_all_layers_alternate.py @@ -66,7 +66,7 @@ def handle(self, *args, **options): all_layers = all_layers.filter(owner__username=username) for index, layer in enumerate(all_layers): - logger.info("[%s / %s] Checking 'alternate' of Layer [%s] ..." % ((index + 1), len(all_layers), layer.name)) + logger.info(f"[{index + 1} / {len(all_layers)}] Checking 'alternate' of Layer [{layer.name}] ...") try: if not layer.alternate: layer.alternate = layer.typename @@ -75,6 +75,6 @@ def handle(self, *args, **options): # import traceback # traceback.print_exc() if ignore_errors: - logger.error("[ERROR] Layer [%s] couldn't be updated" % (layer.name)) + logger.error(f"[ERROR] Layer [{layer.name}] couldn't be updated") else: raise e diff --git a/geonode/base/management/commands/set_all_layers_metadata.py b/geonode/base/management/commands/set_all_layers_metadata.py index a2247aca807..1dee648be66 100644 --- a/geonode/base/management/commands/set_all_layers_metadata.py +++ b/geonode/base/management/commands/set_all_layers_metadata.py @@ -110,7 +110,7 @@ def handle(self, *args, **options): all_layers = all_layers.filter(owner__username=username) for index, layer in enumerate(all_layers): - print("[%s / %s] Updating Layer [%s] ..." % ((index + 1), len(all_layers), layer.name)) + print(f"[{index + 1} / {len(all_layers)}] Updating Layer [{layer.name}] ...") try: # recalculate the layer statistics set_attributes(layer, overwrite=True) @@ -128,7 +128,7 @@ def handle(self, *args, **options): import traceback traceback.print_exc() if ignore_errors: - logger.error("[ERROR] Layer [%s] couldn't be updated" % (layer.name)) + logger.error(f"[ERROR] Layer [{layer.name}] couldn't be updated") else: raise e diff --git a/geonode/base/management/commands/set_all_layers_public.py b/geonode/base/management/commands/set_all_layers_public.py index 3c8b432d086..03a5c0ee769 100644 --- a/geonode/base/management/commands/set_all_layers_public.py +++ b/geonode/base/management/commands/set_all_layers_public.py @@ -36,7 +36,7 @@ def handle(self, *args, **options): all_layers = Layer.objects.all() for index, layer in enumerate(all_layers): - print("[%s / %s] Setting public permissions to Layer [%s] ..." % ((index + 1), len(all_layers), layer.name)) + print(f"[{index + 1} / {len(all_layers)}] Setting public permissions to Layer [{layer.name}] ...") try: use_geofence = settings.OGC_SERVER['default'].get( "GEOFENCE_SECURITY_ENABLED", False) @@ -53,4 +53,4 @@ def handle(self, *args, **options): perm_spec["users"]["AnonymousUser"] = ['view_resourcebase', 'download_resourcebase'] layer.set_permissions(perm_spec) except Exception: - logger.error("[ERROR] Layer [%s] couldn't be updated" % (layer.name)) + logger.error(f"[ERROR] Layer [{layer.name}] couldn't be updated") diff --git a/geonode/base/models.py b/geonode/base/models.py index 5d68a323be7..757a69a713a 100644 --- a/geonode/base/models.py +++ b/geonode/base/models.py @@ -124,8 +124,7 @@ def clean(self): # only allow this if we are updating the same contact if self.contact != contacts.get(): raise ValidationError( - 'There can be only one %s for a given resource' % - self.role) + f'There can be only one {self.role} for a given resource') if self.contact is None: # verify that any unbound contact is only associated to one # resource @@ -182,7 +181,7 @@ class SpatialRepresentationType(models.Model): is_choice = models.BooleanField(default=True) def __str__(self): - return "{0}".format(self.gn_description) + return f"{self.gn_description}" class Meta: ordering = ("identifier",) @@ -229,7 +228,7 @@ class Region(MPTTModel): default='EPSG:4326') def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" @property def bbox(self): @@ -278,7 +277,7 @@ class RestrictionCodeType(models.Model): is_choice = models.BooleanField(default=True) def __str__(self): - return "{0}".format(self.gn_description) + return f"{self.gn_description}" class Meta: ordering = ("identifier",) @@ -294,14 +293,14 @@ class License(models.Model): license_text = models.TextField(null=True, blank=True) def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" @property def name_long(self): if self.abbreviation is None or len(self.abbreviation) == 0: return self.name else: - return self.name + " (" + self.abbreviation + ")" + return f"{self.name} ({self.abbreviation})" @property def description_bullets(self): @@ -311,7 +310,7 @@ def description_bullets(self): bullets = [] lines = self.description.split("\n") for line in lines: - bullets.append("+ " + line) + bullets.append(f"+ {line}") return bullets class Meta: @@ -417,10 +416,10 @@ class TaggedContentItem(ItemBase): def tags_for(cls, model, instance=None): if instance is not None: return cls.tag_model().objects.filter(**{ - '%s__content_object' % cls.tag_relname(): instance + f'{cls.tag_relname()}__content_object': instance }) return cls.tag_model().objects.filter(**{ - '%s__content_object__isnull' % cls.tag_relname(): False + f'{cls.tag_relname()}__content_object__isnull': False }).distinct() @@ -471,7 +470,7 @@ class Thesaurus(models.Model): slug = models.CharField(max_length=64, default='') def __str__(self): - return "{0}".format(self.identifier) + return f"{self.identifier}" class Meta: ordering = ("identifier",) @@ -492,7 +491,7 @@ class ThesaurusKeywordLabel(models.Model): keyword = models.ForeignKey('ThesaurusKeyword', related_name='keyword', on_delete=models.CASCADE) def __str__(self): - return "{0}".format(self.label) + return f"{self.label}" class Meta: ordering = ("keyword", "lang") @@ -516,7 +515,7 @@ class ThesaurusKeyword(models.Model): thesaurus = models.ForeignKey('Thesaurus', related_name='thesaurus', on_delete=models.CASCADE) def __str__(self): - return "{0}".format(self.alt_label) + return f"{self.alt_label}" @property def labels(self): @@ -894,7 +893,7 @@ def __init__(self, *args, **kwargs): super(ResourceBase, self).__init__(*args, **kwargs) def __str__(self): - return "{0}".format(self.title) + return f"{self.title}" def _remove_html_tags(self, attribute_str): _attribute_str = attribute_str @@ -933,14 +932,14 @@ def save(self, notify=False, *args, **kwargs): Send a notification when a resource is created or updated """ if not self.resource_type and self.polymorphic_ctype and \ - self.polymorphic_ctype.model: + self.polymorphic_ctype.model: self.resource_type = self.polymorphic_ctype.model.lower() if hasattr(self, 'class_name') and (self.pk is None or notify): if self.pk is None and self.title: # Resource Created - notice_type_label = '%s_created' % self.class_name.lower() + notice_type_label = f'{self.class_name.lower()}_created' recipients = get_notification_recipients(notice_type_label, resource=self) send_notification(recipients, notice_type_label, {'resource': self}) elif self.pk: @@ -954,7 +953,7 @@ def save(self, notify=False, *args, **kwargs): self.set_workflow_perms(approved=True) # Send "approved" notification - notice_type_label = '%s_approved' % self.class_name.lower() + notice_type_label = f'{self.class_name.lower()}_approved' recipients = get_notification_recipients(notice_type_label, resource=self) send_notification(recipients, notice_type_label, {'resource': self}) _notification_sent = True @@ -966,14 +965,14 @@ def save(self, notify=False, *args, **kwargs): self.set_workflow_perms(published=True) # Send "published" notification - notice_type_label = '%s_published' % self.class_name.lower() + notice_type_label = f'{self.class_name.lower()}_published' recipients = get_notification_recipients(notice_type_label, resource=self) send_notification(recipients, notice_type_label, {'resource': self}) _notification_sent = True # Updated Notifications Here if not _notification_sent: - notice_type_label = '%s_updated' % self.class_name.lower() + notice_type_label = f'{self.class_name.lower()}_updated' recipients = get_notification_recipients(notice_type_label, resource=self) send_notification(recipients, notice_type_label, {'resource': self}) @@ -986,7 +985,7 @@ def delete(self, notify=True, *args, **kwargs): Send a notification when a layer, map or document is deleted """ if hasattr(self, 'class_name') and notify: - notice_type_label = '%s_deleted' % self.class_name.lower() + notice_type_label = f'{self.class_name.lower()}_deleted' recipients = get_notification_recipients(notice_type_label, resource=self) send_notification(recipients, notice_type_label, {'resource': self}) @@ -1092,7 +1091,7 @@ def license_light(self): if self.license.name is not None and (len(self.license.name) > 0): a.append(self.license.name) if self.license.url is not None and (len(self.license.url) > 0): - a.append("(" + self.license.url + ")") + a.append(f"({self.license.url})") return " ".join(a) @property @@ -1100,12 +1099,12 @@ def license_verbose(self): a = [] if self.license.name_long is not None and ( len(self.license.name_long) > 0): - a.append(self.license.name_long + ":") + a.append(f"{self.license.name_long}:") if self.license.description is not None and ( len(self.license.description) > 0): a.append(self.license.description) if self.license.url is not None and (len(self.license.url) > 0): - a.append("(" + self.license.url + ")") + a.append(f"({self.license.url})") return " ".join(a) @property @@ -1136,7 +1135,7 @@ def metadata_completeness(self): if not field.identifier: continue filled_fields.append(field) - return '{}%'.format(len(filled_fields) * 100 / len(required_fields)) + return f'{len(filled_fields) * 100 / len(required_fields)}%' @property def instance_is_processed(self): @@ -1241,12 +1240,10 @@ def set_bounds_from_bbox(self, bbox, srid): """ if not bbox or len(bbox) < 4: raise ValidationError( - 'Bounding Box cannot be empty %s for a given resource' % - self.name) + f'Bounding Box cannot be empty {self.name} for a given resource') if not srid: raise ValidationError( - 'Projection cannot be empty %s for a given resource' % - self.name) + f'Projection cannot be empty {self.name} for a given resource') self.bbox_x0 = bbox[0] self.bbox_x1 = bbox[1] self.bbox_y0 = bbox[2] @@ -1642,7 +1639,7 @@ class Link(models.Model): objects = LinkManager() def __str__(self): - return "{0} link".format(self.link_type) + return f"{self.link_type} link" class MenuPlaceholder(models.Model): @@ -1654,7 +1651,7 @@ class MenuPlaceholder(models.Model): ) def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" class Menu(models.Model): @@ -1673,7 +1670,7 @@ class Menu(models.Model): ) def __str__(self): - return "{0}".format(self.title) + return f"{self.title}" class Meta: unique_together = ( @@ -1726,7 +1723,7 @@ def __hash__(self): return hash(self.url) def __str__(self): - return "{0}".format(self.title) + return f"{self.title}" class Meta: unique_together = ( diff --git a/geonode/base/templatetags/base_tags.py b/geonode/base/templatetags/base_tags.py index b6b35db7d93..709d16cff81 100644 --- a/geonode/base/templatetags/base_tags.py +++ b/geonode/base/templatetags/base_tags.py @@ -320,7 +320,7 @@ def get_context_resourcetype(context): resource_types = ['layers', 'maps', 'documents', 'search', 'people', 'groups/categories', 'groups'] for resource_type in resource_types: - if "/{0}/".format(resource_type) in c_path: + if f"/{resource_type}/" in c_path: return resource_type return 'error' @@ -380,7 +380,7 @@ def _has_owner_his_permissions(): _owner_set == set(['change_resourcebase_permissions', 'publish_resourcebase']) if not _has_owner_his_permissions() and \ - (user.is_superuser or resource.owner.pk == user.pk): + (user.is_superuser or resource.owner.pk == user.pk): return True return False diff --git a/geonode/base/templatetags/user_messages.py b/geonode/base/templatetags/user_messages.py index 906b42e0e30..ce965a2dbc1 100644 --- a/geonode/base/templatetags/user_messages.py +++ b/geonode/base/templatetags/user_messages.py @@ -78,6 +78,6 @@ def get_item(dictionary, key): def show_notification(notice_type_label, current_user): adms_notice_types = getattr(settings, 'ADMINS_ONLY_NOTICE_TYPES', []) if not current_user.is_superuser and adms_notice_types and \ - notice_type_label in adms_notice_types: + notice_type_label in adms_notice_types: return False return True diff --git a/geonode/base/tests.py b/geonode/base/tests.py index 43b305fdbec..a8b3d1daf55 100644 --- a/geonode/base/tests.py +++ b/geonode/base/tests.py @@ -267,52 +267,38 @@ def test_get_menu_placeholder_0(self): self.assertIn( self.menu_0_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_0_0.title - ) + f'Expected "{self.menu_0_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_0_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_0_0.title - ) + f'Expected "{self.menu_item_0_0_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_0_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_0_1.title - ) + f'Expected "{self.menu_item_0_0_1.title}" string in the rendered template' ) # second menu self.assertIn( self.menu_0_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_0_1.title - ) + f'Expected "{self.menu_0_1.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_1_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_1_0.title - ) + f'Expected "{self.menu_item_0_1_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_1_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_1_1.title - ) + f'Expected "{self.menu_item_0_1_1.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_1_2.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_1_2.title - ) + f'Expected "{self.menu_item_0_1_2.title}" string in the rendered template' ) # menu_placeholder_1 # first menu @@ -320,23 +306,17 @@ def test_get_menu_placeholder_0(self): self.assertNotIn( self.menu_1_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_1_0.title - ) + f'No "{self.menu_1_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_1_0_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_1_0_0.title - ) + f'No "{self.menu_item_1_0_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_1_0_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_1_0_1.title - ) + f'No "{self.menu_item_1_0_1.title}" string expected in the rendered template' ) def test_get_menu_placeholder_1(self): @@ -349,52 +329,38 @@ def test_get_menu_placeholder_1(self): self.assertNotIn( self.menu_0_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_0_0.title - ) + f'No "{self.menu_0_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_0_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_0_0.title - ) + f'No "{self.menu_item_0_0_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_0_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_0_1.title - ) + f'No "{self.menu_item_0_0_1.title}" string expected in the rendered template' ) # second menu self.assertNotIn( self.menu_0_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_0_1.title - ) + f'No "{self.menu_0_1.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_1_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_1_0.title - ) + f'No "{self.menu_item_0_1_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_1_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_1_1.title - ) + f'No "{self.menu_item_0_1_1.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_1_2.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_1_2.title - ) + f'No "{self.menu_item_0_1_2.title}" string expected in the rendered template' ) # menu_placeholder_1 # first menu @@ -402,23 +368,17 @@ def test_get_menu_placeholder_1(self): self.assertIn( self.menu_1_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_1_0.title - ) + f'Expected "{self.menu_1_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_1_0_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_1_0_0.title - ) + f'Expected "{self.menu_item_1_0_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_1_0_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_1_0_1.title - ) + f'Expected "{self.menu_item_1_0_1.title}" string in the rendered template' ) def test_render_nav_menu_placeholder_0(self): @@ -431,52 +391,38 @@ def test_render_nav_menu_placeholder_0(self): self.assertIn( self.menu_0_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_0_0.title - ) + f'Expected "{self.menu_0_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_0_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_0_0.title - ) + f'Expected "{self.menu_item_0_0_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_0_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_0_1.title - ) + f'Expected "{self.menu_item_0_0_1.title}" string in the rendered template' ) # second menu self.assertIn( self.menu_0_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_0_1.title - ) + f'Expected "{self.menu_0_1.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_1_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_1_0.title - ) + f'Expected "{self.menu_item_0_1_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_1_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_1_1.title - ) + f'Expected "{self.menu_item_0_1_1.title}" string in the rendered template' ) self.assertIn( self.menu_item_0_1_2.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_0_1_2.title - ) + f'Expected "{self.menu_item_0_1_2.title}" string in the rendered template' ) # menu_placeholder_1 # first menu @@ -484,23 +430,17 @@ def test_render_nav_menu_placeholder_0(self): self.assertNotIn( self.menu_1_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_1_0.title - ) + f'No "{self.menu_1_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_1_0_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_1_0_0.title - ) + f'No "{self.menu_item_1_0_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_1_0_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_1_0_1.title - ) + f'No "{self.menu_item_1_0_1.title}" string expected in the rendered template' ) def test_render_nav_menu_placeholder_1(self): @@ -513,52 +453,38 @@ def test_render_nav_menu_placeholder_1(self): self.assertNotIn( self.menu_0_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_0_0.title - ) + f'No "{self.menu_0_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_0_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_0_0.title - ) + f'No "{self.menu_item_0_0_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_0_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_0_1.title - ) + f'No "{self.menu_item_0_0_1.title}" string expected in the rendered template' ) # second menu self.assertNotIn( self.menu_0_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_0_1.title - ) + f'No "{self.menu_0_1.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_1_0.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_1_0.title - ) + f'No "{self.menu_item_0_1_0.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_1_1.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_1_1.title - ) + f'No "{self.menu_item_0_1_1.title}" string expected in the rendered template' ) self.assertNotIn( self.menu_item_0_1_2.title, rendered, - 'No "{}" string expected in the rendered template'.format( - self.menu_item_0_1_2.title - ) + f'No "{self.menu_item_0_1_2.title}" string expected in the rendered template' ) # menu_placeholder_1 # first menu @@ -566,23 +492,17 @@ def test_render_nav_menu_placeholder_1(self): self.assertIn( self.menu_1_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_1_0.title - ) + f'Expected "{self.menu_1_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_1_0_0.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_1_0_0.title - ) + f'Expected "{self.menu_item_1_0_0.title}" string in the rendered template' ) self.assertIn( self.menu_item_1_0_1.title, rendered, - 'Expected "{}" string in the rendered template'.format( - self.menu_item_1_0_1.title - ) + f'Expected "{self.menu_item_1_0_1.title}" string in the rendered template' ) diff --git a/geonode/base/utils.py b/geonode/base/utils.py index 87587927356..8d0d9abf793 100644 --- a/geonode/base/utils.py +++ b/geonode/base/utils.py @@ -78,7 +78,7 @@ def delete_orphaned_thumbs(): remove_thumb(filename) deleted.append(filename) except NotImplementedError as e: - logger.error("Failed to delete orphaned thumbnail '{}': {}".format(filename, e)) + logger.error(f"Failed to delete orphaned thumbnail '{filename}': {e}") return deleted diff --git a/geonode/base/views.py b/geonode/base/views.py index c54e464c4ad..5ae28d4a17c 100644 --- a/geonode/base/views.py +++ b/geonode/base/views.py @@ -72,7 +72,7 @@ def user_and_group_permission(request, model): ids = request.POST.get("ids") if "cancel" in request.POST or not ids: return HttpResponseRedirect( - '/admin/{}/{}/'.format(model_class._meta.app_label, model) + f'/admin/{model_class._meta.app_label}/{model}/' ) if request.method == 'POST': @@ -104,7 +104,7 @@ def user_and_group_permission(request, model): (permissions_names, resources_names, users_usernames, groups_names, delete_flag)) return HttpResponseRedirect( - '/admin/{}/{}/'.format(model_class._meta.app_label, model) + f'/admin/{model_class._meta.app_label}/{model}/' ) form = UserAndGroupPermissionsForm({ diff --git a/geonode/base/widgets.py b/geonode/base/widgets.py index 067a0937e21..f0b57415ea0 100644 --- a/geonode/base/widgets.py +++ b/geonode/base/widgets.py @@ -17,7 +17,7 @@ def value_from_datadict(self, data, files, name): try: value = super(TaggitSelect2Custom, self).value_from_datadict(data, files, name) if value and ',' not in value: - value = '%s,' % value + value = f'{value},' return value except TypeError: return "" diff --git a/geonode/br/management/commands/backup.py b/geonode/br/management/commands/backup.py index 0b56ebaacd1..30e834b04af 100644 --- a/geonode/br/management/commands/backup.py +++ b/geonode/br/management/commands/backup.py @@ -155,9 +155,9 @@ def execute_backup(self, **options): if app_name == 'br': continue - print("Dumping '"+app_name+"' into '"+dump_name+".json'.") + print(f"Dumping '{app_name}' into '{dump_name}.json'.") # Point stdout at a file for dumping data to. - output = open(os.path.join(target_folder, dump_name+'.json'), 'w') + output = open(os.path.join(target_folder, f"{dump_name}.json"), 'w') call_command('dumpdata', app_name, format='json', indent=2, stdout=output) output.close() @@ -169,7 +169,7 @@ def execute_backup(self, **options): copy_tree(media_root, media_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Saved Media Files from '"+media_root+"'.") + print(f"Saved Media Files from '{media_root}'.") # Store Static Root static_root = settings.STATIC_ROOT @@ -179,7 +179,7 @@ def execute_backup(self, **options): copy_tree(static_root, static_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Saved Static Root from '"+static_root+"'.") + print(f"Saved Static Root from '{static_root}'.") # Store Static Folders static_folders = settings.STATICFILES_DIRS @@ -202,7 +202,7 @@ def execute_backup(self, **options): copy_tree(static_files_folder, static_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Saved Static Files from '"+static_files_folder+"'.") + print(f"Saved Static Files from '{static_files_folder}'.") # Store Template Folders template_folders = [] @@ -232,7 +232,7 @@ def execute_backup(self, **options): copy_tree(template_files_folder, template_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Saved Template Files from '"+template_files_folder+"'.") + print(f"Saved Template Files from '{template_files_folder}'.") # Store Locale Folders locale_folders = settings.LOCALE_PATHS @@ -255,20 +255,20 @@ def execute_backup(self, **options): copy_tree(locale_files_folder, locale_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Saved Locale Files from '"+locale_files_folder+"'.") + print(f"Saved Locale Files from '{locale_files_folder}'.") # Create Final ZIP Archive - backup_archive = os.path.join(backup_dir, dir_time_suffix+'.zip') + backup_archive = os.path.join(backup_dir, f"{dir_time_suffix}.zip") zip_dir(target_folder, backup_archive) # Generate a md5 hash of a backup archive and save it - backup_md5_file = os.path.join(backup_dir, dir_time_suffix+'.md5') + backup_md5_file = os.path.join(backup_dir, f"{dir_time_suffix}.md5") zip_archive_md5 = utils.md5_file_hash(backup_archive) with open(backup_md5_file, 'w') as md5_file: md5_file.write(zip_archive_md5) # Generate the ini file with the current settings used by the backup command - backup_ini_file = os.path.join(backup_dir, dir_time_suffix + '.ini') + backup_ini_file = os.path.join(backup_dir, f"{dir_time_suffix}.ini") with open(backup_ini_file, 'w') as configfile: config.config_parser.write(configfile) @@ -276,11 +276,11 @@ def execute_backup(self, **options): try: shutil.rmtree(target_folder) except Exception: - print("WARNING: Could not be possible to delete the temp folder: '" + str(target_folder) + "'") + print(f"WARNING: Could not be possible to delete the temp folder: '{str(target_folder)}'") print("Backup Finished. Archive generated.") - return str(os.path.join(backup_dir, dir_time_suffix+'.zip')) + return str(os.path.join(backup_dir, f"{dir_time_suffix}.zip")) def create_geoserver_backup(self, config, settings, target_folder, ignore_errors): # Create GeoServer Backup @@ -289,25 +289,24 @@ def create_geoserver_backup(self, config, settings, target_folder, ignore_errors passwd = settings.OGC_SERVER['default']['PASSWORD'] geoserver_bk_file = os.path.join(target_folder, 'geoserver_catalog.zip') - print("Dumping 'GeoServer Catalog ["+url+"]' into '"+geoserver_bk_file+"'.") - r = requests.put(url + 'rest/reset/', + print(f"Dumping 'GeoServer Catalog [{url}]' into '{geoserver_bk_file}'.") + r = requests.put(f"{url}rest/reset/", auth=HTTPBasicAuth(user, passwd)) if r.status_code != 200: raise ValueError('Could not reset GeoServer catalog!') - r = requests.put(url + 'rest/reload/', + r = requests.put(f"{url}rest/reload/", auth=HTTPBasicAuth(user, passwd)) if r.status_code != 200: raise ValueError('Could not reload GeoServer catalog!') - error_backup = 'Could not successfully backup GeoServer ' + \ - 'catalog [{}rest/br/backup/]: {} - {}' + error_backup = f"Could not successfully backup GeoServer catalog [{{}}rest/br/backup/]: {{}} - {{}}" _options = [ 'BK_CLEANUP_TEMP=true', 'BK_SKIP_SETTINGS=false', 'BK_SKIP_SECURITY=false', - 'BK_BEST_EFFORT={}'.format('true' if ignore_errors else 'false'), - 'exclude.file.path={}'.format(config.gs_exclude_file_path) + f"BK_BEST_EFFORT={'true' if ignore_errors else 'false'}", + f'exclude.file.path={config.gs_exclude_file_path}' ] data = {'backup': {'archiveFile': geoserver_bk_file, 'overwrite': 'true', 'options': {'option': _options}}} @@ -315,12 +314,12 @@ def create_geoserver_backup(self, config, settings, target_folder, ignore_errors 'Accept': 'application/json', 'Content-type': 'application/json' } - r = requests.post(url + 'rest/br/backup/', data=json.dumps(data), + r = requests.post(f"{url}rest/br/backup/", data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(user, passwd)) if r.status_code in (200, 201, 406): try: - r = requests.get(url + 'rest/br/backup.json', + r = requests.get(f"{url}rest/br/backup.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10) @@ -341,7 +340,7 @@ def create_geoserver_backup(self, config, settings, target_folder, ignore_errors raise ValueError(error_backup.format(url, r.status_code, r.text)) gs_bk_exec_id = gs_backup['backup']['execution']['id'] - r = requests.get(url + 'rest/br/backup/' + str(gs_bk_exec_id) + '.json', + r = requests.get(f"{url}rest/br/backup/{str(gs_bk_exec_id)}.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10) @@ -352,7 +351,7 @@ def create_geoserver_backup(self, config, settings, target_folder, ignore_errors while (gs_bk_exec_status != 'COMPLETED' and gs_bk_exec_status != 'FAILED'): if (gs_bk_exec_progress != gs_bk_exec_progress_updated): gs_bk_exec_progress_updated = gs_bk_exec_progress - r = requests.get(url + 'rest/br/backup/' + str(gs_bk_exec_id) + '.json', + r = requests.get(f"{url}rest/br/backup/{str(gs_bk_exec_id)}.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10) @@ -365,7 +364,7 @@ def create_geoserver_backup(self, config, settings, target_folder, ignore_errors gs_bk_exec_status = gs_backup['backup']['execution']['status'] gs_bk_exec_progress = gs_backup['backup']['execution']['progress'] - print(str(gs_bk_exec_status) + ' - ' + gs_bk_exec_progress) + print(f"{str(gs_bk_exec_status)} - {gs_bk_exec_progress}") time.sleep(3) else: raise ValueError(error_backup.format(url, r.status_code, r.text)) @@ -376,7 +375,7 @@ def create_geoserver_backup(self, config, settings, target_folder, ignore_errors os.chmod(geoserver_bk_file, _permissions) status = os.stat(geoserver_bk_file) if oct(status.st_mode & 0o777) != str(oct(_permissions)): - raise Exception("Could not update permissions of {}".format(geoserver_bk_file)) + raise Exception(f"Could not update permissions of {geoserver_bk_file}") else: raise ValueError(error_backup.format(url, r.status_code, r.text)) @@ -387,22 +386,22 @@ def dump_geoserver_raster_data(self, config, settings, target_folder): gs_data_root = os.path.join(config.gs_data_dir, 'geonode') if not os.path.isabs(gs_data_root): gs_data_root = os.path.join(settings.PROJECT_ROOT, '..', gs_data_root) - print("Dumping GeoServer Uploaded Data from '"+gs_data_root+"'.") + print(f"Dumping GeoServer Uploaded Data from '{gs_data_root}'.") if os.path.exists(gs_data_root): gs_data_folder = os.path.join(target_folder, 'gs_data_dir', 'geonode') if not os.path.exists(gs_data_folder): os.makedirs(gs_data_folder) copy_tree(gs_data_root, gs_data_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Dumped GeoServer Uploaded Data from '"+gs_data_root+"'.") + print(f"Dumped GeoServer Uploaded Data from '{gs_data_root}'.") else: - print("Skipped GeoServer Uploaded Data '"+gs_data_root+"'.") + print(f"Skipped GeoServer Uploaded Data '{gs_data_root}'.") # Dump '$config.gs_data_dir/data/geonode' gs_data_root = os.path.join(config.gs_data_dir, 'data', 'geonode') if not os.path.isabs(gs_data_root): gs_data_root = os.path.join(settings.PROJECT_ROOT, '..', gs_data_root) - print("Dumping GeoServer Uploaded Data from '"+gs_data_root+"'.") + print(f"Dumping GeoServer Uploaded Data from '{gs_data_root}'.") if os.path.exists(gs_data_root): gs_data_folder = os.path.join(target_folder, 'gs_data_dir', 'data', 'geonode') if not os.path.exists(gs_data_folder): @@ -410,9 +409,9 @@ def dump_geoserver_raster_data(self, config, settings, target_folder): copy_tree(gs_data_root, gs_data_folder, ignore=utils.ignore_time(config.gs_data_dt_filter[0], config.gs_data_dt_filter[1])) - print("Dumped GeoServer Uploaded Data from '" + gs_data_root + "'.") + print(f"Dumped GeoServer Uploaded Data from '{gs_data_root}'.") else: - print("Skipped GeoServer Uploaded Data '"+gs_data_root+"'.") + print(f"Skipped GeoServer Uploaded Data '{gs_data_root}'.") def dump_geoserver_vector_data(self, config, settings, target_folder): if (config.gs_dump_vector_data): @@ -452,7 +451,7 @@ def copy_external_resource(abspath): if not os.path.isdir(external_path) and os.path.exists(external_path): shutil.copy2(abspath, external_path) except shutil.SameFileError: - print("WARNING: {} and {} are the same file!".format(abspath, external_path)) + print(f"WARNING: {abspath} and {external_path} are the same file!") def match_filename(key, text, regexp=re.compile("^(.+)$")): if key in ('filename', ): @@ -466,7 +465,7 @@ def match_filename(key, text, regexp=re.compile("^(.+)$")): if os.path.exists(abspath): return abspath except Exception: - print("WARNING: Error while trying to dump {}".format(text)) + print(f"WARNING: Error while trying to dump {text}") return def match_fileurl(key, text, regexp=re.compile("^file:(.+)$")): @@ -481,7 +480,7 @@ def match_fileurl(key, text, regexp=re.compile("^file:(.+)$")): if os.path.exists(abspath): return abspath except Exception: - print("WARNING: Error while trying to dump {}".format(text)) + print(f"WARNING: Error while trying to dump {text}") return def dump_external_resources_from_xml(path): diff --git a/geonode/br/management/commands/restore.py b/geonode/br/management/commands/restore.py index c18ef6fbfe8..7b9cf64d2d0 100755 --- a/geonode/br/management/commands/restore.py +++ b/geonode/br/management/commands/restore.py @@ -264,20 +264,20 @@ def execute_restore(self, **options): locale_files_folders = os.path.join(target_folder, utils.LOCALE_PATHS) try: - print(("[Sanity Check] Full Write Access to '{}' ...".format(restore_folder))) + print(f"[Sanity Check] Full Write Access to '{restore_folder}' ...") chmod_tree(restore_folder) - print(("[Sanity Check] Full Write Access to '{}' ...".format(media_root))) + print(f"[Sanity Check] Full Write Access to '{media_root}' ...") chmod_tree(media_root) - print(("[Sanity Check] Full Write Access to '{}' ...".format(static_root))) + print(f"[Sanity Check] Full Write Access to '{static_root}' ...") chmod_tree(static_root) for static_files_folder in static_folders: - print(("[Sanity Check] Full Write Access to '{}' ...".format(static_files_folder))) + print(f"[Sanity Check] Full Write Access to '{static_files_folder}' ...") chmod_tree(static_files_folder) for template_files_folder in template_folders: - print(("[Sanity Check] Full Write Access to '{}' ...".format(template_files_folder))) + print(f"[Sanity Check] Full Write Access to '{template_files_folder}' ...") chmod_tree(template_files_folder) for locale_files_folder in locale_folders: - print(("[Sanity Check] Full Write Access to '{}' ...".format(locale_files_folder))) + print(f"[Sanity Check] Full Write Access to '{locale_files_folder}' ...") chmod_tree(locale_files_folder) except Exception as exception: if notify: @@ -290,7 +290,7 @@ def execute_restore(self, **options): if not skip_geoserver: try: - print(("[Sanity Check] Full Write Access to '{}' ...".format(target_folder))) + print(f"[Sanity Check] Full Write Access to '{target_folder}' ...") chmod_tree(target_folder) self.restore_geoserver_backup(config, settings, target_folder, skip_geoserver_info, skip_geoserver_security, ignore_errors, soft_reset) @@ -351,18 +351,18 @@ def execute_restore(self, **options): # Restore Fixtures for app_name, dump_name in zip(config.app_names, config.dump_names): - fixture_file = os.path.join(target_folder, dump_name+'.json') + fixture_file = os.path.join(target_folder, f"{dump_name}.json") - print("Deserializing "+fixture_file) + print(f"Deserializing {fixture_file}") try: call_command('loaddata', fixture_file, app_label=app_name) except IntegrityError as e: traceback.print_exc() - print("WARNING: The fixture '"+dump_name+"' fails on integrity check and import is aborted after all fixtures have been checked.") + print(f"WARNING: The fixture '{dump_name}' fails on integrity check and import is aborted after all fixtures have been checked.") abortlater = True except Exception: traceback.print_exc() - print("WARNING: No valid fixture data found for '"+dump_name+"'.") + print(f"WARNING: No valid fixture data found for '{dump_name}'.") # helpers.load_fixture(app_name, fixture_file) raise try: @@ -380,7 +380,7 @@ def execute_restore(self, **options): copy_tree(media_folder, media_root) chmod_tree(media_root) - print("Media Files Restored into '"+media_root+"'.") + print(f"Media Files Restored into '{media_root}'.") # Restore Static Root if config.gs_data_dt_filter[0] is None: @@ -391,7 +391,7 @@ def execute_restore(self, **options): copy_tree(static_folder, static_root) chmod_tree(static_root) - print("Static Root Restored into '"+static_root+"'.") + print(f"Static Root Restored into '{static_root}'.") # Restore Static Folders for static_files_folder in static_folders: @@ -413,7 +413,7 @@ def execute_restore(self, **options): os.path.basename(os.path.normpath(static_files_folder))), static_files_folder) chmod_tree(static_files_folder) - print("Static Files Restored into '"+static_files_folder+"'.") + print(f"Static Files Restored into '{static_files_folder}'.") # Restore Template Folders for template_files_folder in template_folders: @@ -435,7 +435,7 @@ def execute_restore(self, **options): os.path.basename(os.path.normpath(template_files_folder))), template_files_folder) chmod_tree(template_files_folder) - print("Template Files Restored into '"+template_files_folder+"'.") + print(f"Template Files Restored into '{template_files_folder}'.") # Restore Locale Folders for locale_files_folder in locale_folders: @@ -457,7 +457,7 @@ def execute_restore(self, **options): os.path.basename(os.path.normpath(locale_files_folder))), locale_files_folder) chmod_tree(locale_files_folder) - print("Locale Files Restored into '"+locale_files_folder+"'.") + print(f"Locale Files Restored into '{locale_files_folder}'.") call_command('collectstatic', interactive=False) @@ -582,7 +582,7 @@ def validate_backup_file_hash(self, backup_file: str) -> str: backup_hash = utils.md5_file_hash(backup_file) # check md5 hash for backup archive, if the md5 file is in place - archive_md5_file = backup_file.rsplit('.', 1)[0] + '.md5' + archive_md5_file = f"{backup_file.rsplit('.', 1)[0]}.md5" if os.path.exists(archive_md5_file): with open(archive_md5_file, 'r') as md5_file: @@ -611,7 +611,7 @@ def check_backup_ini_settings(self, backup_file: str) -> str: :return: backup_ini_file_path original settings used by the backup file """ # check if the ini file is in place - backup_ini_file_path = backup_file.rsplit('.', 1)[0] + '.ini' + backup_ini_file_path = f"{backup_file.rsplit('.', 1)[0]}.ini" if os.path.exists(backup_ini_file_path): return backup_ini_file_path @@ -626,19 +626,18 @@ def restore_geoserver_backup(self, config, settings, target_folder, skip_geoserv geoserver_bk_file = os.path.join(target_folder, 'geoserver_catalog.zip') if not os.path.exists(geoserver_bk_file) or not os.access(geoserver_bk_file, os.R_OK): - raise Exception(('ERROR: geoserver restore: ' + - 'file "{}" not found.'.format(geoserver_bk_file))) + raise Exception(f"ERROR: geoserver restore: file \"{geoserver_bk_file}\" not found.") - print("Restoring 'GeoServer Catalog ["+url+"]' from '"+geoserver_bk_file+"'.") + print(f"Restoring 'GeoServer Catalog [{url}]' from '{geoserver_bk_file}'.") # Best Effort Restore: 'options': {'option': ['BK_BEST_EFFORT=true']} _options = [ - 'BK_PURGE_RESOURCES={}'.format('true' if not soft_reset else 'false'), + f"BK_PURGE_RESOURCES={'true' if not soft_reset else 'false'}", 'BK_CLEANUP_TEMP=true', - 'BK_SKIP_SETTINGS={}'.format('true' if skip_geoserver_info else 'false'), - 'BK_SKIP_SECURITY={}'.format('true' if skip_geoserver_security else 'false'), + f"BK_SKIP_SETTINGS={'true' if skip_geoserver_info else 'false'}", + f"BK_SKIP_SECURITY={'true' if skip_geoserver_security else 'false'}", 'BK_BEST_EFFORT=true', - 'exclude.file.path={}'.format(config.gs_exclude_file_path) + f'exclude.file.path={config.gs_exclude_file_path}' ] data = {'restore': {'archiveFile': geoserver_bk_file, 'options': {'option': _options}}} @@ -646,14 +645,13 @@ def restore_geoserver_backup(self, config, settings, target_folder, skip_geoserv 'Accept': 'application/json', 'Content-type': 'application/json' } - r = requests.post(url + 'rest/br/restore/', data=json.dumps(data), + r = requests.post(f"{url}rest/br/restore/", data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(user, passwd)) - error_backup = 'Could not successfully restore GeoServer ' + \ - 'catalog [{}rest/br/restore/]: {} - {}' + error_backup = f"Could not successfully restore GeoServer catalog [{{}}rest/br/restore/]: {{}} - {{}}" if r.status_code in (200, 201, 406): try: - r = requests.get(url + 'rest/br/restore.json', + r = requests.get(f"{url}rest/br/restore.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10) @@ -676,7 +674,7 @@ def restore_geoserver_backup(self, config, settings, target_folder, skip_geoserv raise ValueError(error_backup.format(url, r.status_code, r.text)) gs_bk_exec_id = gs_backup['restore']['execution']['id'] - r = requests.get(url + 'rest/br/restore/' + str(gs_bk_exec_id) + '.json', + r = requests.get(f"{url}rest/br/restore/{str(gs_bk_exec_id)}.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10) @@ -688,7 +686,7 @@ def restore_geoserver_backup(self, config, settings, target_folder, skip_geoserv while (gs_bk_exec_status != 'COMPLETED' and gs_bk_exec_status != 'FAILED'): if (gs_bk_exec_progress != gs_bk_exec_progress_updated): gs_bk_exec_progress_updated = gs_bk_exec_progress - r = requests.get(url + 'rest/br/restore/' + str(gs_bk_exec_id) + '.json', + r = requests.get(f"{url}rest/br/restore/{str(gs_bk_exec_id)}.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10) @@ -702,7 +700,7 @@ def restore_geoserver_backup(self, config, settings, target_folder, skip_geoserv gs_bk_exec_status = gs_backup['restore']['execution']['status'] gs_bk_exec_progress = gs_backup['restore']['execution']['progress'] - print(str(gs_bk_exec_status) + ' - ' + gs_bk_exec_progress) + print(f"{str(gs_bk_exec_status)} - {gs_bk_exec_progress}") time.sleep(3) else: raise ValueError(error_backup.format(url, r.status_code, r.text)) @@ -724,7 +722,7 @@ def prepare_geoserver_gwc_config(self, config, settings): gwc_layers_root = os.path.join(settings.PROJECT_ROOT, '..', gwc_layers_root) try: shutil.rmtree(gwc_layers_root) - print('Cleaned out old GeoServer GWC Layers Config: ' + gwc_layers_root) + print(f"Cleaned out old GeoServer GWC Layers Config: {gwc_layers_root}") except Exception: pass if not os.path.exists(gwc_layers_root): @@ -744,10 +742,9 @@ def restore_geoserver_raster_data(self, config, settings, target_folder): os.makedirs(gs_data_root) copy_tree(gs_data_folder, gs_data_root) - print("GeoServer Uploaded Raster Data Restored to '" + gs_data_root + "'.") + print(f"GeoServer Uploaded Raster Data Restored to '{gs_data_root}'.") else: - print(('Skipping geoserver raster data restore: ' + - 'directory "{}" not found.'.format(gs_data_folder))) + print(f"Skipping geoserver raster data restore: directory \"{gs_data_folder}\" not found.") # Restore '$config.gs_data_dir/data/geonode' gs_data_folder = os.path.join(target_folder, 'gs_data_dir', 'data', 'geonode') @@ -760,10 +757,9 @@ def restore_geoserver_raster_data(self, config, settings, target_folder): os.makedirs(gs_data_root) copy_tree(gs_data_folder, gs_data_root) - print("GeoServer Uploaded Data Restored to '" + gs_data_root + "'.") + print(f"GeoServer Uploaded Data Restored to '{gs_data_root}'.") else: - print(('Skipping geoserver raster data restore: ' + - 'directory "{}" not found.'.format(gs_data_folder))) + print(f"Skipping geoserver raster data restore: directory \"{gs_data_folder}\" not found.") def restore_geoserver_vector_data(self, config, settings, target_folder, soft_reset): """Restore Vectorial Data from DB""" @@ -771,8 +767,7 @@ def restore_geoserver_vector_data(self, config, settings, target_folder, soft_re gs_data_folder = os.path.join(target_folder, 'gs_data_dir', 'geonode') if not os.path.exists(gs_data_folder): - print(('Skipping geoserver vector data restore: ' + - 'directory "{}" not found.'.format(gs_data_folder))) + print(f"Skipping geoserver vector data restore: directory \"{gs_data_folder}\" not found.") return datastore = settings.OGC_SERVER['default']['DATASTORE'] diff --git a/geonode/br/management/commands/utils/utils.py b/geonode/br/management/commands/utils/utils.py index f316de1513f..ed92678ea63 100644 --- a/geonode/br/management/commands/utils/utils.py +++ b/geonode/br/management/commands/utils/utils.py @@ -238,8 +238,8 @@ def flush_db(db_name, db_user, db_port, db_host, db_passwd): for table in pg_tables: if table[0] == 'br_restoredbackup': continue - print("Flushing Data : " + table[0]) - curs.execute("TRUNCATE " + table[0] + " CASCADE;") + print(f"Flushing Data : {table[0]}") + curs.execute(f"TRUNCATE {table[0]} CASCADE;") conn.commit() except Exception: try: @@ -438,10 +438,10 @@ def glob2re(pat): i = i+1 if c == '*': # res = res + '.*' - res = res + '[^/]*' + res = f"{res}[^/]*" elif c == '?': # res = res + '.' - res = res + '[^/]' + res = f"{res}[^/]" elif c == '[': j = i if j < n and pat[j] == '!': @@ -451,18 +451,18 @@ def glob2re(pat): while j < n and pat[j] != ']': j = j+1 if j >= n: - res = res + '\\[' + res = f"{res}\\[" else: stuff = pat[i:j].replace('\\', '\\\\') i = j+1 if stuff[0] == '!': - stuff = '^' + stuff[1:] + stuff = f"^{stuff[1:]}" elif stuff[0] == '^': - stuff = '\\' + stuff + stuff = f"\\{stuff}" res = f'{res}[{stuff}]' else: res = res + re.escape(c) - return res + r'\Z(?ms)' + return f"{res}\\Z(?ms)" def glob_filter(names, pat): diff --git a/geonode/br/tests/test_restore.py b/geonode/br/tests/test_restore.py index 7a739ab7908..0eac15d0953 100644 --- a/geonode/br/tests/test_restore.py +++ b/geonode/br/tests/test_restore.py @@ -176,7 +176,7 @@ def test_config_files(self, mock_configuration_save, fake_confirm): with zipfile.ZipFile(tmp_file, 'w', zipfile.ZIP_DEFLATED) as archive: archive.writestr('something.txt', 'Some Content Here') - tmp_ini_file = tmp_file.name.rsplit('.', 1)[0] + '.ini' + tmp_ini_file = f"{tmp_file.name.rsplit('.', 1)[0]}.ini" from configparser import ConfigParser config = ConfigParser() config['database'] = { diff --git a/geonode/br/tests/test_restore_helpers.py b/geonode/br/tests/test_restore_helpers.py index 5324e5ab3b4..6550a6b73d1 100644 --- a/geonode/br/tests/test_restore_helpers.py +++ b/geonode/br/tests/test_restore_helpers.py @@ -203,7 +203,7 @@ def test_backup_hash_failure(self): archive.writestr('something.txt', 'Some Content Here') # create a md5 hash file for the backup temporary file - tmp_hash_file = tmp_file.name + '.md5' + tmp_hash_file = f"{tmp_file.name}.md5" with open(tmp_hash_file, 'w') as hash_file: hash_file.write('91162629d258a876ee994e9233b2ad87') @@ -230,7 +230,7 @@ def test_backup_hash_success(self): archive.writestr('something.txt', 'Some Content Here') # create a md5 hash file for the backup temporary file - tmp_hash_file = tmp_file.name + '.md5' + tmp_hash_file = f"{tmp_file.name}.md5" with open(tmp_hash_file, 'w') as hash_file: hash_file.write(md5_file_hash(tmp_file.name)) diff --git a/geonode/catalogue/__init__.py b/geonode/catalogue/__init__.py index ae1bd7f379c..8c321016bae 100644 --- a/geonode/catalogue/__init__.py +++ b/geonode/catalogue/__init__.py @@ -34,7 +34,7 @@ # If settings.CATALOGUE is defined, we expect it to be properly named if DEFAULT_CATALOGUE_ALIAS not in settings.CATALOGUE: - raise ImproperlyConfigured("You must define a '%s' CATALOGUE" % DEFAULT_CATALOGUE_ALIAS) + raise ImproperlyConfigured(f"You must define a '{DEFAULT_CATALOGUE_ALIAS}' CATALOGUE") def load_backend(backend_name): @@ -47,9 +47,8 @@ def load_backend(backend_name): # listing all possible (built-in) CSW backends. backend_dir = os.path.join(os.path.dirname(__file__), 'backends') try: - available_backends = [f for f in os.listdir(backend_dir) if os.path.isdir(os.path.join(backend_dir, f)) and - not f.startswith('.')] - available_backends.sort() + available_backends = sorted([f for f in os.listdir(backend_dir) if os.path.isdir( + os.path.join(backend_dir, f)) and not f.startswith('.')]) except EnvironmentError: available_backends = [] @@ -68,7 +67,7 @@ def load_backend(backend_name): def default_catalogue_backend(): """Get the default backend """ - msg = "There is no '%s' backend in CATALOGUE" % DEFAULT_CATALOGUE_ALIAS + msg = f"There is no '{DEFAULT_CATALOGUE_ALIAS}' backend in CATALOGUE" assert DEFAULT_CATALOGUE_ALIAS in settings.CATALOGUE, msg return settings.CATALOGUE[DEFAULT_CATALOGUE_ALIAS] diff --git a/geonode/catalogue/backends/generic.py b/geonode/catalogue/backends/generic.py index fd00b118954..085795caefe 100644 --- a/geonode/catalogue/backends/generic.py +++ b/geonode/catalogue/backends/generic.py @@ -74,7 +74,7 @@ def __init__(self, *args, **kwargs): upurl = urlparse(self.url) - self.base = '%s://%s/' % (upurl.scheme, upurl.netloc) + self.base = f'{upurl.scheme}://{upurl.netloc}/' # User and Password are optional if 'USER' in kwargs: @@ -91,7 +91,7 @@ def __exit__(self, *args, **kwargs): def login(self): if self.type == 'geonetwork': - url = "%sgeonetwork/srv/en/xml.user.login" % self.base + url = f"{self.base}geonetwork/srv/en/xml.user.login" headers = { "Content-Type": "application/x-www-form-urlencoded", "Accept": "text/plain" @@ -111,7 +111,7 @@ def login(self): def logout(self): if self.type == 'geonetwork': - url = "%sgeonetwork/srv/en/xml.user.logout" % self.base + url = f"{self.base}geonetwork/srv/en/xml.user.logout" request = Request(url) response = self.opener.open(request) # noqa self.connected = False @@ -139,14 +139,7 @@ def get_by_uuid(self, uuid): return None def url_for_uuid(self, uuid, outputschema): - return "%s?%s" % (self.url, urlencode({ - "request": "GetRecordById", - "service": "CSW", - "version": "2.0.2", - "id": uuid, - "outputschema": outputschema, - "elementsetname": "full" - })) + return f"{self.url}?{urlencode({'request': 'GetRecordById', 'service': 'CSW', 'version': '2.0.2', 'id': uuid, 'outputschema': outputschema, 'elementsetname': 'full'})}" def urls_for_uuid(self, uuid): """returns list of valid GetRecordById URLs for a given record""" @@ -281,11 +274,10 @@ def set_metadata_privs(self, uuid, privileges): if state is not True: continue op_id = self._operation_ids[op.lower()] - priv_params['_%s_%s' % (group_id, op_id)] = 'on' + priv_params[f'_{group_id}_{op_id}'] = 'on' # update all privileges - update_privs_url = "%sgeonetwork/srv/en/metadata.admin?%s" % ( - self.base, urlencode(priv_params)) + update_privs_url = f"{self.base}geonetwork/srv/en/metadata.admin?{urlencode(priv_params)}" request = Request(update_privs_url) response = self.urlopen(request) @@ -297,8 +289,7 @@ def _geonetwork_get_group_ids(self): groups. """ # get the ids of the groups. - get_groups_url = "%sgeonetwork/srv/en/xml.info?%s" % ( - self.base, urlencode({'type': 'groups'})) + get_groups_url = f"{self.base}geonetwork/srv/en/xml.info?{urlencode({'type': 'groups'})}" request = Request(get_groups_url) response = self.urlopen(request) doc = dlxml.fromstring(response.read()) @@ -313,8 +304,7 @@ def _geonetwork_get_operation_ids(self): 'operations' (privileges) """ # get the ids of the operations - get_ops_url = "%sgeonetwork/srv/en/xml.info?%s" % ( - self.base, urlencode({'type': 'operations'})) + get_ops_url = f"{self.base}geonetwork/srv/en/xml.info?{urlencode({'type': 'operations'})}" request = Request(get_ops_url) response = self.urlopen(request) doc = dlxml.fromstring(response.read()) diff --git a/geonode/catalogue/backends/pycsw_plugin.py b/geonode/catalogue/backends/pycsw_plugin.py index 32f7023f872..1bcaad6e98f 100644 --- a/geonode/catalogue/backends/pycsw_plugin.py +++ b/geonode/catalogue/backends/pycsw_plugin.py @@ -126,7 +126,7 @@ def query_domain(self, domain, typenames, Min(domain), Max(domain)).values())] else: if count: - return [(d[domain], d['%s__count' % domain]) + return [(d[domain], d[f'{domain}__count']) for d in objects.values(domain).annotate(Count(domain))] else: return objects.values_list(domain).distinct() @@ -183,7 +183,7 @@ def query(self, constraint, sortby=None, typenames=None, )[startposition:startposition + int(maxrecords)]] else: if sortby['order'] == 'DESC': - pname = '-%s' % sortby['propertyname'] + pname = f"-{sortby['propertyname']}" else: pname = sortby['propertyname'] return [str(total), diff --git a/geonode/catalogue/metadataxsl/management/commands/addmissinglinks.py b/geonode/catalogue/metadataxsl/management/commands/addmissinglinks.py index 5ad64b981bf..40155db1ef7 100644 --- a/geonode/catalogue/metadataxsl/management/commands/addmissinglinks.py +++ b/geonode/catalogue/metadataxsl/management/commands/addmissinglinks.py @@ -30,15 +30,15 @@ class Command(BaseCommand): def handle(self, *args, **options): for resource in ResourceBase.objects.all(): - print('Checking resource with id {}'.format(resource.id)) + print(f'Checking resource with id {resource.id}') # check ISO link exists isolink = Link.objects.filter(resource_id=resource.id, link_type='metadata', name='ISO') if(isolink): - print(' ISO link found for resource {} "{}"'.format(resource.id, resource.title)) + print(f' ISO link found for resource {resource.id} "{resource.title}"') created = add_xsl_link(resource) if (created): print(' XSL link created') else: - print(' ISO link NOT found for resource {} "{}"'.format(resource.id, resource.title)) + print(f' ISO link NOT found for resource {resource.id} "{resource.title}"') diff --git a/geonode/catalogue/metadataxsl/views.py b/geonode/catalogue/metadataxsl/views.py index 0c8c85d9b0d..55bbec84ebd 100644 --- a/geonode/catalogue/metadataxsl/views.py +++ b/geonode/catalogue/metadataxsl/views.py @@ -48,7 +48,7 @@ def prefix_xsl_line(req, id): logger.debug(record.xml) except Exception: logger.debug(traceback.format_exc()) - msg = 'Could not connect to catalogue to save information for layer "%s"' % str(resource) + msg = f'Could not connect to catalogue to save information for layer "{str(resource)}"' return HttpResponse( msg ) @@ -66,8 +66,8 @@ def prefix_xsl_line(req, id): "Resource Metadata not available!" ) site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL - xsl_path = '{}/static/metadataxsl/metadata.xsl'.format(site_url) - xsl_line = ''.format(xsl_path) + xsl_path = f'{site_url}/static/metadataxsl/metadata.xsl' + xsl_line = f'' return HttpResponse( xsl_line + xml, diff --git a/geonode/catalogue/models.py b/geonode/catalogue/models.py index d9019ee22c3..3e5c032f306 100644 --- a/geonode/catalogue/models.py +++ b/geonode/catalogue/models.py @@ -60,7 +60,7 @@ def catalogue_post_save(instance, sender, **kwargs): catalogue.create_record(instance) record = catalogue.get_record(instance.uuid) except EnvironmentError as err: - msg = 'Could not connect to catalogue to save information for layer "%s"' % instance.name + msg = f'Could not connect to catalogue to save information for layer "{instance.name}"' if err.reason.errno == errno.ECONNREFUSED: LOGGER.warn(msg, err) return @@ -68,12 +68,11 @@ def catalogue_post_save(instance, sender, **kwargs): raise err if not record: - msg = ('Metadata record for %s does not exist,' - ' check the catalogue signals.' % instance.title) + msg = f'Metadata record for {instance.title} does not exist, check the catalogue signals.' raise Exception(msg) if not hasattr(record, 'links'): - msg = ('Metadata record for %s should contain links.' % instance.title) + msg = f'Metadata record for {instance.title} should contain links.' raise Exception(msg) # Create the different metadata links with the available formats diff --git a/geonode/catalogue/views.py b/geonode/catalogue/views.py index 97d57c8a71c..1c4f64df463 100644 --- a/geonode/catalogue/views.py +++ b/geonode/catalogue/views.py @@ -94,15 +94,14 @@ def csw_global_dispatch(request, layer_filter=None, config_updater=None): authorized_ids = [d.id for d in layers] if len(authorized_ids) > 0: - authorized_layers = "(" + (", ".join(str(e) - for e in authorized_ids)) + ")" - authorized_layers_filter = "id IN " + authorized_layers - mdict['repository']['filter'] += " AND " + authorized_layers_filter + authorized_layers = f"({', '.join(str(e) for e in authorized_ids)})" + authorized_layers_filter = f"id IN {authorized_layers}" + mdict['repository']['filter'] += f" AND {authorized_layers_filter}" if request.user and request.user.is_authenticated: mdict['repository']['filter'] = f"({mdict['repository']['filter']}) OR ({authorized_layers_filter})" else: authorized_layers_filter = "id = -9999" - mdict['repository']['filter'] += " AND " + authorized_layers_filter + mdict['repository']['filter'] += f" AND {authorized_layers_filter}" # Filter out Documents and Maps if 'ALTERNATES_ONLY' in settings.CATALOGUE['default'] and settings.CATALOGUE['default']['ALTERNATES_ONLY']: @@ -140,12 +139,12 @@ def csw_global_dispatch(request, layer_filter=None, config_updater=None): groups_ids.append(group.id) if len(groups_ids) > 0: - groups = "(" + (", ".join(str(e) for e in groups_ids)) + ")" - groups_filter = "(group_id IS NULL OR group_id IN " + groups + ")" - mdict['repository']['filter'] += " AND " + groups_filter + groups = f"({', '.join(str(e) for e in groups_ids)})" + groups_filter = f"(group_id IS NULL OR group_id IN {groups})" + mdict['repository']['filter'] += f" AND {groups_filter}" else: groups_filter = "group_id IS NULL" - mdict['repository']['filter'] += " AND " + groups_filter + mdict['repository']['filter'] += f" AND {groups_filter}" csw = server.Csw(mdict, env, version='2.0.2') @@ -221,7 +220,7 @@ def get_keywords(resource): "SELECT a.*,b.* FROM taggit_taggeditem as a,taggit_tag" " as b WHERE a.object_id = %s AND a.tag_id=b.id", [resource.id]) for x in dictfetchall(cursor): - content += fst(x['name']) + ', ' + content += f"{fst(x['name'])}, " return content[:-2] @@ -235,63 +234,55 @@ def csw_render_extra_format_txt(request, layeruuid, resname): s = chrs['separator'] c = chrs['carriage_return'] sc = s + c - content = 'Resource metadata' + sc - content += 'uuid' + s + fst(resource.uuid) + sc - content += 'title' + s + fst(resource.title) + sc - content += 'resource owner' + s + fst(resource.owner) + sc - content += 'date' + s + fst(resource.date) + sc - content += 'date type' + s + fst(resource.date_type) + sc - content += 'abstract' + s + fst(resource.abstract) + sc - content += 'edition' + s + fst(resource.edition) + sc - content += 'purpose' + s + fst(resource.purpose) + sc - content += 'maintenance frequency' + s + fst( - resource.maintenance_frequency) + sc + content = f"Resource metadata{sc}" + content += f"uuid{s}{fst(resource.uuid)}{sc}" + content += f"title{s}{fst(resource.title)}{sc}" + content += f"resource owner{s}{fst(resource.owner)}{sc}" + content += f"date{s}{fst(resource.date)}{sc}" + content += f"date type{s}{fst(resource.date_type)}{sc}" + content += f"abstract{s}{fst(resource.abstract)}{sc}" + content += f"edition{s}{fst(resource.edition)}{sc}" + content += f"purpose{s}{fst(resource.purpose)}{sc}" + content += f"maintenance frequency{s}{fst(resource.maintenance_frequency)}{sc}" try: sprt = SpatialRepresentationType.objects.get( id=resource.spatial_representation_type_id) - content += 'identifier' + s + fst(sprt.identifier) + sc + content += f"identifier{s}{fst(sprt.identifier)}{sc}" except ObjectDoesNotExist: - content += 'ObjectDoesNotExist' + sc - - content += 'restriction code type' + s + fst( - resource.restriction_code_type) + sc - content += 'constraints other ' + s + fst( - resource.constraints_other) + sc - content += 'license' + s + fst(resource.license) + sc - content += 'language' + s + fst(resource.language) + sc - content += 'temporal extent' + sc - content += 'temporal extent start' + s + fst( - resource.temporal_extent_start) + sc - content += 'temporal extent end' + s + fst( - resource.temporal_extent_end) + sc - content += 'supplemental information' + s + fst( - resource.supplemental_information) + sc + content += f"ObjectDoesNotExist{sc}" + + content += f"restriction code type{s}{fst(resource.restriction_code_type)}{sc}" + content += f"constraints other {s}{fst(resource.constraints_other)}{sc}" + content += f"license{s}{fst(resource.license)}{sc}" + content += f"language{s}{fst(resource.language)}{sc}" + content += f"temporal extent{sc}" + content += f"temporal extent start{s}{fst(resource.temporal_extent_start)}{sc}" + content += f"temporal extent end{s}{fst(resource.temporal_extent_end)}{sc}" + content += f"supplemental information{s}{fst(resource.supplemental_information)}{sc}" """content += 'URL de distribution ' + s + fst( resource.distribution_url) + sc""" """content += 'description de la distribution' + s + fst( resource.distribution_description) + sc""" - content += 'data quality statement' + s + fst( - resource.data_quality_statement) + sc + content += f"data quality statement{s}{fst(resource.data_quality_statement)}{sc}" ext = resource.bbox_polygon.extent - content += 'extent ' + s + fst(ext[0]) + ',' + fst(ext[2]) + \ - ',' + fst(ext[1]) + ',' + fst(ext[3]) + sc - content += 'SRID ' + s + fst(resource.srid) + sc - content += 'Thumbnail url' + s + fst(resource.thumbnail_url) + sc + content += f"extent {s}{fst(ext[0])},{fst(ext[2])},{fst(ext[1])},{fst(ext[3])}{sc}" + content += f"SRID {s}{fst(resource.srid)}{sc}" + content += f"Thumbnail url{s}{fst(resource.thumbnail_url)}{sc}" - content += 'keywords;' + get_keywords(resource) + s - content += 'category' + s + fst(resource.category) + sc + content += f"keywords;{get_keywords(resource)}{s}" + content += f"category{s}{fst(resource.category)}{sc}" - content += 'regions' + s + content += f"regions{s}" for reg in resource.regions.all(): - content += fst(reg.name_en) + ',' + content += f"{fst(reg.name_en)}," content = content[:-1] content += sc if resource.detail_url.find('/layers/') > -1: layer = Layer.objects.get(resourcebase_ptr_id=resource.id) - content += 'attribute data' + sc + content += f"attribute data{sc}" content += 'attribute name;label;description\n' for attr in layer.attribute_set.all(): content += fst(attr.attribute) + s @@ -301,9 +292,9 @@ def csw_render_extra_format_txt(request, layeruuid, resname): pocr = ContactRole.objects.get( resource_id=resource.id, role='pointOfContact') pocp = get_user_model().objects.get(id=pocr.contact_id) - content += "Point of Contact" + sc - content += "name" + s + fst(pocp.last_name) + sc - content += "e-mail" + s + fst(pocp.email) + sc + content += f"Point of Contact{sc}" + content += f"name{s}{fst(pocp.last_name)}{sc}" + content += f"e-mail{s}{fst(pocp.email)}{sc}" logger = logging.getLogger(__name__) logger.error(content) diff --git a/geonode/client/conf.py b/geonode/client/conf.py index d17d9ec1a74..95bce262fa6 100644 --- a/geonode/client/conf.py +++ b/geonode/client/conf.py @@ -31,11 +31,11 @@ def load_path_attr(path): try: mod = importlib.import_module(module) except ImportError as e: - raise ImproperlyConfigured("Error importing {0}: '{1}'".format(module, e)) + raise ImproperlyConfigured(f"Error importing {module}: '{e}'") try: attr = getattr(mod, attr) except AttributeError: - raise ImproperlyConfigured("Module '{0}' does not define a '{1}'".format(module, attr)) + raise ImproperlyConfigured(f"Module '{module}' does not define a '{attr}'") return attr diff --git a/geonode/decorators.py b/geonode/decorators.py index ce3d18275e0..f3fb019a34a 100644 --- a/geonode/decorators.py +++ b/geonode/decorators.py @@ -94,7 +94,7 @@ def view_or_basicauth(view, request, test_func, realm="", *args, **kwargs): # response = HttpResponse() response.status_code = 401 - response['WWW-Authenticate'] = 'Basic realm="%s"' % realm + response['WWW-Authenticate'] = f'Basic realm="{realm}"' return response @@ -109,8 +109,7 @@ def decorator(cls): raise TypeError( "You should only decorate subclasses of View, not mixins.") if subclass: - cls = type("%sWithDecorator(%s)" % - (cls.__name__, fdec.__name__), (cls,), {}) + cls = type(f"{cls.__name__}WithDecorator({fdec.__name__})", (cls,), {}) original = cls.as_view.__func__ @wraps(original) @@ -205,7 +204,7 @@ def _inner(request, *args, **kwargs): def check_keyword_write_perms(function): def _inner(request, *args, **kwargs): keyword_readonly = settings.FREETEXT_KEYWORDS_READONLY and request.method == "POST" \ - and not auth.get_user(request).is_superuser + and not auth.get_user(request).is_superuser request.keyword_readonly = keyword_readonly if keyword_readonly and 'resource-keywords' in request.POST: return HttpResponse( @@ -316,6 +315,6 @@ def wrapper(request, *args, **kwargs): def dump_func_name(func): def echo_func(*func_args, **func_kwargs): - logger.debug('Start func: {}'.format(func.__name__)) + logger.debug(f'Start func: {func.__name__}') return func(*func_args, **func_kwargs) return echo_func diff --git a/geonode/documents/forms.py b/geonode/documents/forms.py index b2b87ff24c5..5f4f0447173 100644 --- a/geonode/documents/forms.py +++ b/geonode/documents/forms.py @@ -55,8 +55,8 @@ def generate_link_choices(self, resources=None): for obj in resources: type_id = ContentType.objects.get_for_model(obj.__class__).id choices.append([ - "type:%s-id:%s" % (type_id, obj.id), - '%s (%s)' % (obj.title, obj.polymorphic_ctype.model) + f"type:{type_id}-id:{obj.id}", + f'{obj.title} ({obj.polymorphic_ctype.model})' ]) return choices diff --git a/geonode/documents/models.py b/geonode/documents/models.py index 87757ea716a..437656ed0ac 100644 --- a/geonode/documents/models.py +++ b/geonode/documents/models.py @@ -69,7 +69,7 @@ class Document(ResourceBase): verbose_name=_('URL')) def __str__(self): - return "{0}".format(self.title) + return f"{self.title}" def get_absolute_url(self): return reverse('document_detail', args=(self.id,)) @@ -86,7 +86,7 @@ def name_long(self): if not self.title: return str(self.id) else: - return '%s (%s)' % (self.title, self.id) + return f'{self.title} ({self.id})' def find_placeholder(self): placeholder = 'documents/{0}-placeholder.png' diff --git a/geonode/documents/renderers.py b/geonode/documents/renderers.py index 8de11944773..5f75fb9ed67 100644 --- a/geonode/documents/renderers.py +++ b/geonode/documents/renderers.py @@ -67,7 +67,7 @@ def render_document(document_path, extension="png"): output_path = None if settings.UNOCONV_ENABLE: timeout = None - _, output_path = tempfile.mkstemp(suffix=".{}".format(extension)) + _, output_path = tempfile.mkstemp(suffix=f".{extension}") try: unoconv = subprocess.Popen( [settings.UNOCONV_EXECUTABLE, "-v", "-e", "PageRange=1-2", diff --git a/geonode/documents/tasks.py b/geonode/documents/tasks.py index ba41e285d83..28932cf7c1a 100644 --- a/geonode/documents/tasks.py +++ b/geonode/documents/tasks.py @@ -48,12 +48,12 @@ def create_document_thumbnail(self, object_id): """ Create thumbnail for a document. """ - logger.debug("Generating thumbnail for document #{}.".format(object_id)) + logger.debug(f"Generating thumbnail for document #{object_id}.") try: document = Document.objects.get(id=object_id) except Document.DoesNotExist: - logger.error("Document #{} does not exist.".format(object_id)) + logger.error(f"Document #{object_id} does not exist.") raise image_path = None @@ -83,23 +83,23 @@ def create_document_thumbnail(self, object_id): image_file = open(image_path, 'rb') except Exception as e: logger.debug(e) - logger.debug("Failed to render document #{}".format(object_id)) + logger.debug(f"Failed to render document #{object_id}") else: - logger.debug("Failed to render document #{}".format(object_id)) + logger.debug(f"Failed to render document #{object_id}") except ConversionError as e: - logger.debug("Could not convert document #{}: {}.".format(object_id, e)) + logger.debug(f"Could not convert document #{object_id}: {e}.") except NotImplementedError as e: - logger.debug("Failed to render document #{}: {}".format(object_id, e)) + logger.debug(f"Failed to render document #{object_id}: {e}") thumbnail_content = None try: try: thumbnail_content = generate_thumbnail_content(image_file) except Exception as e: - logger.error("Could not generate thumbnail, falling back to 'placeholder': {}".format(e)) + logger.error(f"Could not generate thumbnail, falling back to 'placeholder': {e}") thumbnail_content = generate_thumbnail_content(document.find_placeholder()) except Exception as e: - logger.error("Could not generate thumbnail: {}".format(e)) + logger.error(f"Could not generate thumbnail: {e}") return finally: if image_file is not None: @@ -109,10 +109,10 @@ def create_document_thumbnail(self, object_id): os.remove(image_path) if not thumbnail_content: - logger.warning("Thumbnail for document #{} empty.".format(object_id)) - filename = 'document-{}-thumb.png'.format(document.uuid) + logger.warning(f"Thumbnail for document #{object_id} empty.") + filename = f'document-{document.uuid}-thumb.png' document.save_thumbnail(filename, thumbnail_content) - logger.debug("Thumbnail for document #{} created.".format(object_id)) + logger.debug(f"Thumbnail for document #{object_id} created.") @app.task( diff --git a/geonode/documents/urls.py b/geonode/documents/urls.py index 8fb3da49017..1b1ae7507de 100644 --- a/geonode/documents/urls.py +++ b/geonode/documents/urls.py @@ -31,7 +31,7 @@ } documents_list = register_url_event()(TemplateView.as_view( - template_name='documents/document_list.html')) + template_name='documents/document_list.html')) urlpatterns = [ # 'geonode.documents.views', url(r'^$', diff --git a/geonode/documents/utils.py b/geonode/documents/utils.py index 3dadbfa39b4..73381897420 100644 --- a/geonode/documents/utils.py +++ b/geonode/documents/utils.py @@ -51,14 +51,14 @@ def delete_orphaned_document_files(): for filename in files: if Document.objects.filter(doc_file__contains=filename).count() == 0: - logger.debug("Deleting orphaned document " + filename) + logger.debug(f"Deleting orphaned document {filename}") try: storage.delete(os.path.join( os.path.join("documents", "document"), filename)) deleted.append(filename) except NotImplementedError as e: logger.error( - "Failed to delete orphaned document '{}': {}".format(filename, e)) + f"Failed to delete orphaned document '{filename}': {e}") return deleted diff --git a/geonode/documents/views.py b/geonode/documents/views.py index 18073206fcb..dc701089fca 100644 --- a/geonode/documents/views.py +++ b/geonode/documents/views.py @@ -367,7 +367,7 @@ def document_metadata( prefix="resource") category_form = CategoryForm(request.POST, prefix="category_choice_field", initial=int( request.POST["category_choice_field"]) if "category_choice_field" in request.POST and - request.POST["category_choice_field"] else None) + request.POST["category_choice_field"] else None) tkeywords_form = TKeywordForm(request.POST) else: document_form = DocumentForm(instance=document, prefix="resource") @@ -392,8 +392,7 @@ def document_metadata( if len(tkl) > 0: tkl_ids = ",".join( map(str, tkl.values_list('id', flat=True))) - tkeywords_list += "," + \ - tkl_ids if len( + tkeywords_list += f",{tkl_ids}" if len( tkeywords_list) > 0 else tkl_ids except Exception: tb = traceback.format_exc() diff --git a/geonode/favorite/models.py b/geonode/favorite/models.py index fd8573c75d9..88be3df5b94 100644 --- a/geonode/favorite/models.py +++ b/geonode/favorite/models.py @@ -105,7 +105,6 @@ class Meta: def __str__(self): if self.content_object: - return "Favorite: {}, {}, {}".format( - self.content_object.title, self.content_type, self.user) + return f"Favorite: {self.content_object.title}, {self.content_type}, {self.user}" else: return "Unknown" diff --git a/geonode/favorite/utils.py b/geonode/favorite/utils.py index 3d0946e827d..e09f952d778 100644 --- a/geonode/favorite/utils.py +++ b/geonode/favorite/utils.py @@ -32,7 +32,7 @@ def get_favorite_info(user, content_object): result = {} url_content_type = type(content_object).__name__.lower() - result["add_url"] = reverse("add_favorite_{}".format(url_content_type), args=[content_object.pk]) + result["add_url"] = reverse(f"add_favorite_{url_content_type}", args=[content_object.pk]) existing_favorite = models.Favorite.objects.favorite_for_user_and_content_object(user, content_object) diff --git a/geonode/geoserver/__init__.py b/geonode/geoserver/__init__.py index 8a8c4d0bc24..a5a4b3a59da 100644 --- a/geonode/geoserver/__init__.py +++ b/geonode/geoserver/__init__.py @@ -59,14 +59,14 @@ def set_resource_links(*args, **kwargs): _all_layers = Layer.objects.all() for index, layer in enumerate(_all_layers, start=1): _lyr_name = layer.name - message = "[%s / %s] Updating Layer [%s] ..." % (index, len(_all_layers), _lyr_name) + message = f"[{index} / {len(_all_layers)}] Updating Layer [{_lyr_name}] ..." logger.debug(message) try: set_resource_default_links(layer, layer) catalogue_post_save(instance=layer, sender=layer.__class__) except Exception: logger.exception( - "[ERROR] Layer [%s] couldn't be updated" % _lyr_name + f"[ERROR] Layer [{_lyr_name}] couldn't be updated" ) diff --git a/geonode/geoserver/createlayer/tests.py b/geonode/geoserver/createlayer/tests.py index e1b4781bcb6..af322fe5fa1 100644 --- a/geonode/geoserver/createlayer/tests.py +++ b/geonode/geoserver/createlayer/tests.py @@ -123,7 +123,7 @@ def test_layer_creation(self): self.assertEqual(resource.projection, layer.srid) # check if layer detail page is accessible with client - response = self.client.get(reverse('layer_detail', args=('geonode:%s' % layer_name,))) + response = self.client.get(reverse('layer_detail', args=(f'geonode:{layer_name}',))) self.assertEqual(response.status_code, 200) def test_layer_creation_with_wrong_geometry_type(self): diff --git a/geonode/geoserver/createlayer/utils.py b/geonode/geoserver/createlayer/utils.py index e0cc701ada6..d5079957dca 100644 --- a/geonode/geoserver/createlayer/utils.py +++ b/geonode/geoserver/createlayer/utils.py @@ -69,7 +69,7 @@ def create_gn_layer(workspace, datastore, name, title, owner_name): workspace=workspace.name, store=datastore.name, storeType='dataStore', - alternate='%s:%s' % (workspace.name, name), + alternate=f'{workspace.name}:{name}', title=title, owner=owner, uuid=str(uuid.uuid4()), @@ -118,7 +118,7 @@ def get_attributes(geometry_type, json_attrs=None): lattrs = [] gattr = [] gattr.append('the_geom') - gattr.append('com.vividsolutions.jts.geom.%s' % geometry_type) + gattr.append(f'com.vividsolutions.jts.geom.{geometry_type}') gattr.append({'nillable': False}) lattrs.append(gattr) if json_attrs: @@ -128,17 +128,17 @@ def get_attributes(geometry_type, json_attrs=None): attr_name = slugify(jattr[0]) attr_type = jattr[1].lower() if len(attr_name) == 0: - msg = 'You must provide an attribute name for attribute of type %s' % (attr_type) + msg = f'You must provide an attribute name for attribute of type {attr_type}' logger.error(msg) raise GeoNodeException(msg) if attr_type not in ('float', 'date', 'string', 'integer'): - msg = '%s is not a valid type for attribute %s' % (attr_type, attr_name) + msg = f'{attr_type} is not a valid type for attribute {attr_name}' logger.error(msg) raise GeoNodeException(msg) if attr_type == 'date': - attr_type = 'java.util.%s' % attr_type[:1].upper() + attr_type[1:] + attr_type = f"java.util.{attr_type[:1].upper()}{attr_type[1:]}" else: - attr_type = 'java.lang.%s' % attr_type[:1].upper() + attr_type[1:] + attr_type = f"java.lang.{attr_type[:1].upper()}{attr_type[1:]}" lattr.append(attr_name) lattr.append(attr_type) lattr.append({'nillable': True}) @@ -180,7 +180,7 @@ def create_gs_layer(name, title, geometry_type, attributes=None): resources = datastore.get_resources() for resource in resources: if resource.name == name: - msg = "There is already a layer named %s in %s" % (name, workspace) + msg = f"There is already a layer named {name} in {workspace}" logger.error(msg) raise GeoNodeException(msg) @@ -211,14 +211,13 @@ def create_gs_layer(name, title, geometry_type, attributes=None): minx=BBOX[0], maxx=BBOX[1], miny=BBOX[2], maxy=BBOX[3], attributes=attributes_block) - url = ('%s/workspaces/%s/datastores/%s/featuretypes' - % (ogc_server_settings.rest, workspace.name, datastore.name)) + url = f'{ogc_server_settings.rest}/workspaces/{workspace.name}/datastores/{datastore.name}/featuretypes' headers = {'Content-Type': 'application/xml'} _user, _password = ogc_server_settings.credentials req = requests.post(url, data=xml, headers=headers, auth=(_user, _password)) if req.status_code != 201: - logger.error('Request status code was: %s' % req.status_code) - logger.error('Response was: %s' % req.text) - raise Exception("Layer could not be created in GeoServer {}".format(req.text)) + logger.error(f'Request status code was: {req.status_code}') + logger.error(f'Response was: {req.text}') + raise Exception(f"Layer could not be created in GeoServer {req.text}") return workspace, datastore diff --git a/geonode/geoserver/createlayer/views.py b/geonode/geoserver/createlayer/views.py index b806bf0450e..622ebbdeee6 100644 --- a/geonode/geoserver/createlayer/views.py +++ b/geonode/geoserver/createlayer/views.py @@ -49,7 +49,7 @@ def layer_create(request, template='createlayer/layer_create.html'): layer.set_permissions(json.loads(permissions), created=True) return redirect(layer) except Exception as e: - error = '%s (%s)' % (e, type(e)) + error = f'{e} ({type(e)})' else: form = NewLayerForm() diff --git a/geonode/geoserver/helpers.py b/geonode/geoserver/helpers.py index d1e1af82cc9..2b806b1faea 100755 --- a/geonode/geoserver/helpers.py +++ b/geonode/geoserver/helpers.py @@ -84,10 +84,9 @@ def check_geoserver_is_up(): """Verifies all geoserver is running, this is needed to be able to upload. """ - url = "%s" % ogc_server_settings.LOCATION + url = f"{ogc_server_settings.LOCATION}" req, content = http_client.get(url, user=_user) - msg = ('Cannot connect to the GeoServer at %s\nPlease make sure you ' - 'have started it.' % url) + msg = f'Cannot connect to the GeoServer at {url}\nPlease make sure you have started it.' logger.debug(req) assert req.status_code == 200, msg @@ -180,7 +179,7 @@ def _add_sld_boilerplate(symbolizer): def _style_name(resource): - return _punc.sub("_", resource.store.workspace.name + ":" + resource.name) + return _punc.sub("_", f"{resource.store.workspace.name}:{resource.name}") def extract_name_from_sld(gs_catalog, sld, sld_file=None): @@ -470,7 +469,7 @@ def cascading_delete(layer_name=None, catalog=None): for s in styles: if s is not None and s.name not in _default_style_names: try: - logger.debug("Trying to delete Style [%s]" % s.name) + logger.debug(f"Trying to delete Style [{s.name}]") cat.delete(s, purge='true') except Exception as e: # Trying to delete a shared style will fail @@ -492,7 +491,7 @@ def cascading_delete(layer_name=None, catalog=None): else: if store.resource_type == 'coverageStore': try: - logger.debug(" - Going to purge the " + store.resource_type + " : " + store.href) + logger.debug(f" - Going to purge the {store.resource_type} : {store.href}") cat.reset() # this resets the coverage readers and unlocks the files cat.delete(store, purge='all', recurse=True) # cat.reload() # this preservers the integrity of geoserver @@ -528,7 +527,7 @@ def delete_from_postgis(layer_name, store): try: conn = psycopg2.connect(dbname=db_name, user=user, host=host, port=port, password=password) cur = conn.cursor() - cur.execute("SELECT DropGeometryTable ('%s')" % layer_name) + cur.execute(f"SELECT DropGeometryTable ('{layer_name}')") conn.commit() except Exception as e: logger.error( @@ -638,7 +637,7 @@ def gs_slurp( if skip_geonode_registered: try: resources = [k for k in resources - if not '%s:%s' % (k.workspace.name, k.name) in layer_names] + if f'{k.workspace.name}:{k.name}' not in layer_names] except Exception: if ignore_errors: pass @@ -677,7 +676,7 @@ def gs_slurp( workspace=workspace.name, store=the_store.name, storeType=the_store.resource_type, - alternate="%s:%s" % (workspace.name, resource.name), + alternate=f"{workspace.name}:{resource.name}", title=resource.title or 'No title provided', abstract=resource.abstract or "{}".format(_('No abstract provided')), owner=owner, @@ -722,7 +721,7 @@ def gs_slurp( msg = "Stopping process because --ignore-errors was not set and an error was found." print(msg, file=sys.stderr) - raise Exception("Failed to process {}".format(resource.name)) from e + raise Exception(f"Failed to process {resource.name}") from e else: if created: @@ -977,7 +976,7 @@ def set_attributes_from_geoserver(layer, overwrite=False): "version": "1.0.0", "request": "DescribeFeatureType", "typename": typename, - }) + }) try: # The code below will fail if http_client cannot be imported or WFS not supported req, body = http_client.get(dft_url, user=_user) @@ -1210,19 +1209,17 @@ def get_attribute_statistics(layer_name, field): def get_wcs_record(instance, retry=True): - wcs = WebCoverageService(ogc_server_settings.LOCATION + 'wcs', '1.0.0') - key = instance.workspace + ':' + instance.name + wcs = WebCoverageService(f"{ogc_server_settings.LOCATION}wcs", '1.0.0') + key = f"{instance.workspace}:{instance.name}" logger.debug(wcs.contents) if key in wcs.contents: return wcs.contents[key] else: - msg = ("Layer '%s' was not found in WCS service at %s." % - (key, ogc_server_settings.public_url) + msg = (f"Layer '{key}' was not found in WCS service at {ogc_server_settings.public_url}." ) if retry: logger.debug( - msg + - ' Waiting a couple of seconds before trying again.') + f"{msg} Waiting a couple of seconds before trying again.") time.sleep(2) return get_wcs_record(instance, retry=False) else: @@ -1258,8 +1255,7 @@ def cleanup(name, uuid): except Layer.DoesNotExist: pass else: - msg = ('Not doing any cleanup because the layer %s exists in the ' - 'Django db.' % name) + msg = f'Not doing any cleanup because the layer {name} exists in the Django db.' raise GeoNodeException(msg) cat = gs_catalog @@ -1328,7 +1324,7 @@ def create_geoserver_db_featurestore( ds_exists = True except FailedRequestError: logger.debug( - 'Creating target datastore %s' % dsname) + f'Creating target datastore {dsname}') ds = cat.create_datastore(dsname, workspace=workspace) db = ogc_server_settings.datastore_db db_engine = 'postgis' if \ @@ -1412,12 +1408,12 @@ def _create_db_featurestore(name, data, overwrite=False, charset="UTF-8", worksp return ds, resource except Exception: msg = _("An exception occurred loading data to PostGIS") - msg += "- %s" % (sys.exc_info()[1]) + msg += f"- {sys.exc_info()[1]}" try: delete_from_postgis(name, ds) except Exception: msg += _(" Additionally an error occured during database cleanup") - msg += "- %s" % (sys.exc_info()[1]) + msg += f"- {sys.exc_info()[1]}" raise GeoNodeException(msg) @@ -1432,15 +1428,15 @@ def get_store(cat, name, workspace=None): if workspace: try: - store = cat.get_xml('%s/%s.xml' % (workspace.datastore_url[:-4], name)) + store = cat.get_xml(f'{workspace.datastore_url[:-4]}/{name}.xml') except FailedRequestError: try: - store = cat.get_xml('%s/%s.xml' % (workspace.coveragestore_url[:-4], name)) + store = cat.get_xml(f'{workspace.coveragestore_url[:-4]}/{name}.xml') except FailedRequestError: try: - store = cat.get_xml('%s/%s.xml' % (workspace.wmsstore_url[:-4], name)) + store = cat.get_xml(f'{workspace.wmsstore_url[:-4]}/{name}.xml') except FailedRequestError: - raise FailedRequestError("No store found named: " + name) + raise FailedRequestError(f"No store found named: {name}") if store: if store.tag == 'dataStore': store = datastore_from_index(cat, workspace, store) @@ -1450,9 +1446,9 @@ def get_store(cat, name, workspace=None): store = wmsstore_from_index(cat, workspace, store) return store else: - raise FailedRequestError("No store found named: " + name) + raise FailedRequestError(f"No store found named: {name}") else: - raise FailedRequestError("No store found named: " + name) + raise FailedRequestError(f"No store found named: {name}") class ServerDoesNotExist(Exception): @@ -1530,7 +1526,7 @@ def netloc(self): return urlsplit(self.LOCATION).netloc def __str__(self): - return "{0}".format(self.alias) + return f"{self.alias}" class OGC_Servers_Handler(object): @@ -1552,7 +1548,7 @@ def ensure_valid_configuration(self, alias): try: server = self.servers[alias] except KeyError: - raise ServerDoesNotExist("The server %s doesn't exist" % alias) + raise ServerDoesNotExist(f"The server {alias} doesn't exist") if 'PRINTNG_ENABLED' in server: raise ImproperlyConfigured("The PRINTNG_ENABLED setting has been removed, use 'PRINT_NG_ENABLED' instead.") @@ -1564,7 +1560,7 @@ def ensure_defaults(self, alias): try: server = self.servers[alias] except KeyError: - raise ServerDoesNotExist("The server %s doesn't exist" % alias) + raise ServerDoesNotExist(f"The server {alias} doesn't exist") server.setdefault('BACKEND', 'geonode.geoserver') server.setdefault('LOCATION', 'http://localhost:8080/geoserver/') @@ -1627,12 +1623,12 @@ def fetch_gs_resource(instance, values, tries): values = {} values.update(dict(store=gs_resource.store.name, storeType=gs_resource.store.resource_type, - alternate=gs_resource.store.workspace.name + ':' + gs_resource.name, + alternate=f"{gs_resource.store.workspace.name}:{gs_resource.name}", title=gs_resource.title or gs_resource.store.name, abstract=gs_resource.abstract or '', owner=instance.owner)) else: - msg = "There isn't a geoserver resource for this layer: %s" % instance.name + msg = f"There isn't a geoserver resource for this layer: {instance.name}" logger.exception(msg) if tries >= _max_tries: # raise GeoNodeException(msg) @@ -1643,8 +1639,7 @@ def fetch_gs_resource(instance, values, tries): def get_wms(): - wms_url = ogc_server_settings.internal_ows + \ - "?service=WMS&request=GetCapabilities&version=1.1.0" + wms_url = f"{ogc_server_settings.internal_ows}?service=WMS&request=GetCapabilities&version=1.1.0" req, body = http_client.get(wms_url, user=_user) _wms = WebMapService(wms_url, xml=body) return _wms @@ -1706,7 +1701,7 @@ def _stylefilterparams_geowebcache_layer(layer_name): headers = { "Content-Type": "text/xml" } - url = '%sgwc/rest/layers/%s.xml' % (ogc_server_settings.LOCATION, layer_name) + url = f'{ogc_server_settings.LOCATION}gwc/rest/layers/{layer_name}.xml' # read GWC configuration req, content = http_client.get( @@ -1714,9 +1709,7 @@ def _stylefilterparams_geowebcache_layer(layer_name): headers=headers, user=_user) if req.status_code != 200: - line = "Error {0} reading Style Filter Params GeoWebCache at {1}".format( - req.status_code, url - ) + line = f"Error {req.status_code} reading Style Filter Params GeoWebCache at {url}" logger.error(line) return @@ -1738,9 +1731,7 @@ def _stylefilterparams_geowebcache_layer(layer_name): headers=headers, user=_user) if req.status_code != 200: - line = "Error {0} writing Style Filter Params GeoWebCache at {1}".format( - req.status_code, url - ) + line = f"Error {req.status_code} writing Style Filter Params GeoWebCache at {url}" logger.error(line) @@ -1753,7 +1744,7 @@ def _invalidate_geowebcache_layer(layer_name, url=None): {0} """.strip().format(layer_name) if not url: - url = '%sgwc/rest/masstruncate' % ogc_server_settings.LOCATION + url = f'{ogc_server_settings.LOCATION}gwc/rest/masstruncate' req, content = http_client.post( url, data=body, @@ -1761,9 +1752,7 @@ def _invalidate_geowebcache_layer(layer_name, url=None): user=_user) if req.status_code != 200: - line = "Error {0} invalidating GeoWebCache at {1}".format( - req.status_code, url - ) + line = f"Error {req.status_code} invalidating GeoWebCache at {url}" logger.debug(line) @@ -1809,7 +1798,7 @@ def style_update(request, url): elm_user_style_title = elm_user_style_name.text layer_name = elm_namedlayer_name.text style_name = elm_user_style_name.text - sld_body = '%s' % request.body + sld_body = f'{request.body}' except Exception: logger.warn("Could not recognize Style and Layer name from Request!") # add style in GN and associate it to layer @@ -1875,7 +1864,7 @@ def set_time_info(layer, attribute, end_attribute, presentation, ''' layer = gs_catalog.get_layer(layer.name) if layer is None: - raise ValueError('no such layer: %s' % layer.name) + raise ValueError(f'no such layer: {layer.name}') resource = layer.resource if layer else None if not resource: resources = gs_catalog.get_resources(stores=[layer.name]) @@ -1884,7 +1873,7 @@ def set_time_info(layer, attribute, end_attribute, presentation, resolution = None if precision_value and precision_step: - resolution = '%s %s' % (precision_value, precision_step) + resolution = f'{precision_value} {precision_step}' info = DimensionInfo("time", enabled, presentation, resolution, "ISO8601", None, attribute=attribute, end_attribute=end_attribute) if resource and resource.metadata: @@ -1908,7 +1897,7 @@ def get_time_info(layer): ''' layer = gs_catalog.get_layer(layer.name) if layer is None: - raise ValueError('no such layer: %s' % layer.name) + raise ValueError(f'no such layer: {layer.name}') resource = layer.resource if layer else None if not resource: resources = gs_catalog.get_resources(stores=[layer.name]) @@ -2007,8 +1996,8 @@ def _dump_image_spec(request_body, image_spec): def _fixup_ows_url(thumb_spec): # @HACK - for whatever reason, a map's maplayers ows_url contains only /geoserver/wms # so rendering of thumbnails fails - replace those uri's with full geoserver URL - gspath = '"' + ogc_server_settings.public_url # this should be in img src attributes - repl = '"' + ogc_server_settings.LOCATION + gspath = f"\"{ogc_server_settings.public_url}" # this should be in img src attributes + repl = f"\"{ogc_server_settings.LOCATION}" return re.sub(gspath, repl, thumb_spec) @@ -2019,7 +2008,7 @@ def mosaic_delete_first_granule(cat, layer): store = cat.get_store(layer) coverages = cat.mosaic_coverages(store) - granule_id = layer + ".1" + granule_id = f"{layer}.1" cat.mosaic_delete_granule(coverages['coverages']['coverage'][0]['name'], store, granule_id) @@ -2050,8 +2039,8 @@ def set_time_dimension(cat, name, workspace, time_presentation, time_presentatio resource = resources[0] if not resource: - logger.exception("No resource could be found on GeoServer with name %s" % name) - raise Exception("No resource could be found on GeoServer with name %s" % name) + logger.exception(f"No resource could be found on GeoServer with name {name}") + raise Exception(f"No resource could be found on GeoServer with name {name}") resource.metadata = {'time': timeInfo} cat.save(resource) diff --git a/geonode/geoserver/management/commands/find_geoserver_broken_layers.py b/geonode/geoserver/management/commands/find_geoserver_broken_layers.py index 3341ff1e92c..3d25ac89de2 100644 --- a/geonode/geoserver/management/commands/find_geoserver_broken_layers.py +++ b/geonode/geoserver/management/commands/find_geoserver_broken_layers.py @@ -77,14 +77,9 @@ def handle(self, **options): for layer in layers: count += 1 try: - print("Checking layer {}/{}: {} owned by {}".format( - count, - layers_count, - layer.alternate, - layer.owner.username - )) + print(f"Checking layer {count}/{layers_count}: {layer.alternate} owned by {layer.owner.username}") if not is_gs_resource_valid(layer): - print("Layer {} is broken!".format(layer.alternate)) + print(f"Layer {layer.alternate} is broken!") layer_errors.append(layer) if options['remove']: print("Removing this layer...") @@ -97,4 +92,4 @@ def handle(self, **options): layers_count )) for layer_error in layer_errors: - print("{} by {}".format(layer_error.alternate, layer_error.owner.username)) + print(f"{layer_error.alternate} by {layer_error.owner.username}") diff --git a/geonode/geoserver/management/commands/sync_geonode_layers.py b/geonode/geoserver/management/commands/sync_geonode_layers.py index 00f40ef814a..b1cff1204f3 100644 --- a/geonode/geoserver/management/commands/sync_geonode_layers.py +++ b/geonode/geoserver/management/commands/sync_geonode_layers.py @@ -51,7 +51,7 @@ def sync_geonode_layers(ignore_errors, for layer in layers: try: count += 1 - print("Syncing layer {}/{}: {}".format(count, layers_count, layer.name)) + print(f"Syncing layer {count}/{layers_count}: {layer.name}") if updatepermissions: print("Syncing permissions...") # sync permissions in GeoFence diff --git a/geonode/geoserver/management/commands/sync_geonode_maps.py b/geonode/geoserver/management/commands/sync_geonode_maps.py index deb71d67278..9360a8f6bfd 100644 --- a/geonode/geoserver/management/commands/sync_geonode_maps.py +++ b/geonode/geoserver/management/commands/sync_geonode_maps.py @@ -45,7 +45,7 @@ def sync_geonode_maps(ignore_errors, for map in maps: try: count += 1 - print("Syncing map %s/%s: %s" % (count, maps_count, map.title)) + print(f"Syncing map {count}/{maps_count}: {map.title}") if updatethumbnails: print("Regenerating thumbnails...") create_gs_thumbnail(map, overwrite=True, check_bbox=False) diff --git a/geonode/geoserver/management/commands/updatelayers.py b/geonode/geoserver/management/commands/updatelayers.py index e1584197b7d..ae720730574 100644 --- a/geonode/geoserver/management/commands/updatelayers.py +++ b/geonode/geoserver/management/commands/updatelayers.py @@ -142,15 +142,15 @@ def handle(self, **options): if verbosity > 0: print("\n\nFinished processing {} layers in {} seconds.\n".format( len(output['layers']), round(output['stats']['duration_sec'], 2))) - print("{} Created layers".format(output['stats']['created'])) - print("{} Updated layers".format(output['stats']['updated'])) - print("{} Failed layers".format(output['stats']['failed'])) + print(f"{output['stats']['created']} Created layers") + print(f"{output['stats']['updated']} Updated layers") + print(f"{output['stats']['failed']} Failed layers") try: duration_layer = round( output['stats']['duration_sec'] * 1.0 / len(output['layers']), 2) except ZeroDivisionError: duration_layer = 0 if len(output) > 0: - print("{} seconds per layer".format(duration_layer)) + print(f"{duration_layer} seconds per layer") if remove_deleted: - print("\n{} Deleted layers".format(output['stats']['deleted'])) + print(f"\n{output['stats']['deleted']} Deleted layers") diff --git a/geonode/geoserver/signals.py b/geonode/geoserver/signals.py index c6ac1b0917b..1a2f981b3f5 100644 --- a/geonode/geoserver/signals.py +++ b/geonode/geoserver/signals.py @@ -119,7 +119,7 @@ def geoserver_pre_save_maplayer(instance, sender, **kwargs): GsLayer) except EnvironmentError as e: if e.errno == errno.ECONNREFUSED: - msg = 'Could not connect to catalog to verify if layer %s was local' % instance.name + msg = f'Could not connect to catalog to verify if layer {instance.name} was local' logger.warn(msg) else: raise e @@ -130,8 +130,8 @@ def geoserver_post_save_map(instance, sender, created, **kwargs): instance.set_missing_info() if not created: if not instance.thumbnail_url or \ - instance.thumbnail_url == staticfiles.static(settings.MISSING_THUMBNAIL): - logger.debug("... Creating Thumbnail for Map [%s]" % (instance.title)) + instance.thumbnail_url == staticfiles.static(settings.MISSING_THUMBNAIL): + logger.debug(f"... Creating Thumbnail for Map [{instance.title}]") # create_gs_thumbnail(instance, overwrite=False, check_bbox=True) geoserver_create_thumbnail.apply_async(((instance.id, False, True, ))) @@ -146,11 +146,11 @@ def geoserver_post_save_thumbnail(sender, instance, **kwargs): logger.debug(f"... Creating Thumbnail for Layer {instance.title}") _recreate_thumbnail = False if 'update_fields' in kwargs and kwargs['update_fields'] is not None and \ - 'thumbnail_url' in kwargs['update_fields']: + 'thumbnail_url' in kwargs['update_fields']: _recreate_thumbnail = True if not instance.thumbnail_url or \ - instance.thumbnail_url == staticfiles.static(settings.MISSING_THUMBNAIL) or \ - is_monochromatic_image(instance.thumbnail_url): + instance.thumbnail_url == staticfiles.static(settings.MISSING_THUMBNAIL) or \ + is_monochromatic_image(instance.thumbnail_url): _recreate_thumbnail = True if _recreate_thumbnail: geoserver_create_thumbnail.apply_async(((instance.id, False, True, ))) diff --git a/geonode/geoserver/tasks.py b/geonode/geoserver/tasks.py index fdf832df0ec..c8a26b72ed5 100644 --- a/geonode/geoserver/tasks.py +++ b/geonode/geoserver/tasks.py @@ -196,14 +196,13 @@ def geoserver_create_style( except geoserver.catalog.ConflictingDataError: try: gs_catalog.create_style( - name + '_layer', + f"{name}_layer", sld, raw=True, workspace=settings.DEFAULT_WORKSPACE) gs_catalog.reset() except geoserver.catalog.ConflictingDataError as e: - msg = 'There was already a style named %s in GeoServer, cannot overwrite: "%s"' % ( - name, str(e)) + msg = f'There was already a style named {name} in GeoServer, cannot overwrite: "{str(e)}"' logger.error(msg) e.args = (msg,) @@ -214,8 +213,8 @@ def geoserver_create_style( except Exception: logger.warn('Could not retreive the Layer default Style name') try: - style = gs_catalog.get_style(name + '_layer', workspace=settings.DEFAULT_WORKSPACE) or \ - gs_catalog.get_style(name + '_layer') + style = gs_catalog.get_style(f"{name}_layer", workspace=settings.DEFAULT_WORKSPACE) or \ + gs_catalog.get_style(f"{name}_layer") logger.warn( 'No style could be created for the layer, falling back to POINT default one') except Exception as e: @@ -320,7 +319,7 @@ def geoserver_finalize_upload( owner=instance.owner, store=gs_resource.store.name, storeType=gs_resource.store.resource_type, - alternate=gs_resource.store.workspace.name + ':' + gs_resource.name, + alternate=f"{gs_resource.store.workspace.name}:{gs_resource.name}", title=gs_resource.title or gs_resource.store.name, abstract=gs_resource.abstract or '')) @@ -394,7 +393,7 @@ def geoserver_finalize_upload( else: geoserver_create_style(instance.id, instance.name, sld_file, tempdir) - logger.debug('Finalizing (permissions and notifications) Layer {0}'.format(instance)) + logger.debug(f'Finalizing (permissions and notifications) Layer {instance}') instance.handle_moderated_uploads() if permissions is not None and not spec_perms_is_empty(permissions): @@ -507,7 +506,7 @@ def geoserver_post_save_layers( metadata_links.append((link.mime, link.name, link.url)) if gs_resource: - logger.debug("Found geoserver resource for this layer: %s" % instance.name) + logger.debug(f"Found geoserver resource for this layer: {instance.name}") gs_resource.metadata_links = metadata_links instance.gs_resource = gs_resource @@ -579,8 +578,7 @@ def geoserver_post_save_layers( if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) except Exception as e: - msg = ('Error while trying to save resource named %s in GeoServer, ' - 'try to use: "%s"' % (gs_resource, str(e))) + msg = f'Error while trying to save resource named {gs_resource} in GeoServer, try to use: "{str(e)}"' e.args = (msg,) logger.exception(e) diff --git a/geonode/geoserver/tests/integration.py b/geonode/geoserver/tests/integration.py index d0f1efc7677..59d70db93f1 100644 --- a/geonode/geoserver/tests/integration.py +++ b/geonode/geoserver/tests/integration.py @@ -82,8 +82,8 @@ def test_set_attributes_from_geoserver(self): try: # set attributes for resource for attribute in layer.attribute_set.all(): - attribute.attribute_label = '%s_label' % attribute.attribute - attribute.description = '%s_description' % attribute.attribute + attribute.attribute_label = f'{attribute.attribute}_label' + attribute.description = f'{attribute.attribute}_description' attribute.save() # sync the attributes with GeoServer @@ -93,11 +93,11 @@ def test_set_attributes_from_geoserver(self): for attribute in layer.attribute_set.all(): self.assertEqual( attribute.attribute_label, - '%s_label' % attribute.attribute + f'{attribute.attribute}_label' ) self.assertEqual( attribute.description, - '%s_description' % attribute.attribute + f'{attribute.attribute}_description' ) links = Link.objects.filter(resource=layer.resourcebase_ptr) diff --git a/geonode/geoserver/tests/test_helpers.py b/geonode/geoserver/tests/test_helpers.py index af48e5df239..5d8f0ae0884 100644 --- a/geonode/geoserver/tests/test_helpers.py +++ b/geonode/geoserver/tests/test_helpers.py @@ -180,17 +180,17 @@ def test_replace_callback(self): """ kwargs = { - 'content': content, - 'status': 200, - 'content_type': 'application/xml' + 'content': content, + 'status': 200, + 'content_type': 'application/xml' } _content = _response_callback(**kwargs).content self.assertTrue(re.findall(f'{urljoin(settings.SITEURL, "/gs/")}ows', str(_content))) kwargs = { - 'content': content, - 'status': 200, - 'content_type': 'text/xml; charset=UTF-8' + 'content': content, + 'status': 200, + 'content_type': 'text/xml; charset=UTF-8' } _content = _response_callback(**kwargs).content self.assertTrue(re.findall(f'{urljoin(settings.SITEURL, "/gs/")}ows', str(_content))) diff --git a/geonode/geoserver/tests/test_server.py b/geonode/geoserver/tests/test_server.py index 2c89e235776..e460169cfd6 100644 --- a/geonode/geoserver/tests/test_server.py +++ b/geonode/geoserver/tests/test_server.py @@ -814,13 +814,11 @@ def test_layer_acls(self): invalid_uname_pw = b"n0t:v@l1d" valid_auth_headers = { - 'HTTP_AUTHORIZATION': 'basic ' + - base64.b64encode(valid_uname_pw).decode(), + 'HTTP_AUTHORIZATION': f"basic {base64.b64encode(valid_uname_pw).decode()}", } invalid_auth_headers = { - 'HTTP_AUTHORIZATION': 'basic ' + - base64.b64encode(invalid_uname_pw).decode(), + 'HTTP_AUTHORIZATION': f"basic {base64.b64encode(invalid_uname_pw).decode()}", } bob = get_user_model().objects.get(username='bobby') @@ -882,13 +880,11 @@ def test_resolve_user(self): invalid_uname_pw = b"n0t:v@l1d" valid_auth_headers = { - 'HTTP_AUTHORIZATION': 'basic ' + - base64.b64encode(valid_uname_pw).decode(), + 'HTTP_AUTHORIZATION': f"basic {base64.b64encode(valid_uname_pw).decode()}", } invalid_auth_headers = { - 'HTTP_AUTHORIZATION': 'basic ' + - base64.b64encode(invalid_uname_pw).decode(), + 'HTTP_AUTHORIZATION': f"basic {base64.b64encode(invalid_uname_pw).decode()}", } response = self.client.get( @@ -1004,8 +1000,8 @@ def test_ogc_server_defaults(self): defaults = self.OGC_DEFAULT_SETTINGS.get('default') ogc_settings = OGC_Servers_Handler(OGC_SERVER)['default'] self.assertEqual(ogc_settings.server, defaults) - self.assertEqual(ogc_settings.rest, defaults['LOCATION'] + 'rest') - self.assertEqual(ogc_settings.ows, defaults['LOCATION'] + 'ows') + self.assertEqual(ogc_settings.rest, f"{defaults['LOCATION']}rest") + self.assertEqual(ogc_settings.ows, f"{defaults['LOCATION']}ows") # Make sure we get None vs a KeyError when the key does not exist self.assertIsNone(ogc_settings.SFDSDFDSF) @@ -1105,7 +1101,7 @@ def test_ogc_server_defaults(self): self.assertIsNotNone(instance.default_style.name) # WMS Links - wms_links = wms_links(ogc_settings.public_url + 'wms?', + wms_links = wms_links(f"{ogc_settings.public_url}wms?", instance.alternate, bbox, srid, @@ -1116,13 +1112,13 @@ def test_ogc_server_defaults(self): wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wms') identifier = urlencode({'layers': instance.alternate}) for _link in wms_links: - logger.debug('%s --> %s' % (wms_url, _link[3])) + logger.debug(f'{wms_url} --> {_link[3]}') self.assertTrue(wms_url in _link[3]) - logger.debug('%s --> %s' % (identifier, _link[3])) + logger.debug(f'{identifier} --> {_link[3]}') self.assertTrue(identifier in _link[3]) # WFS Links - wfs_links = wfs_links(ogc_settings.public_url + 'wfs?', + wfs_links = wfs_links(f"{ogc_settings.public_url}wfs?", instance.alternate, bbox, srid) @@ -1131,13 +1127,13 @@ def test_ogc_server_defaults(self): wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wfs') identifier = urlencode({'typename': instance.alternate}) for _link in wfs_links: - logger.debug('%s --> %s' % (wfs_url, _link[3])) + logger.debug(f'{wfs_url} --> {_link[3]}') self.assertTrue(wfs_url in _link[3]) - logger.debug('%s --> %s' % (identifier, _link[3])) + logger.debug(f'{identifier} --> {_link[3]}') self.assertTrue(identifier in _link[3]) # WCS Links - wcs_links = wcs_links(ogc_settings.public_url + 'wcs?', + wcs_links = wcs_links(f"{ogc_settings.public_url}wcs?", instance.alternate, bbox, srid) @@ -1146,9 +1142,9 @@ def test_ogc_server_defaults(self): wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wcs') identifier = urlencode({'coverageid': instance.alternate.replace(':', '__', 1)}) for _link in wcs_links: - logger.debug('%s --> %s' % (wcs_url, _link[3])) + logger.debug(f'{wcs_url} --> {_link[3]}') self.assertTrue(wcs_url in _link[3]) - logger.debug('%s --> %s' % (identifier, _link[3])) + logger.debug(f'{identifier} --> {_link[3]}') self.assertTrue(identifier in _link[3]) @on_ogc_backend(geoserver.BACKEND_PACKAGE) @@ -1252,28 +1248,20 @@ def test_set_resources_links(self): ) self.assertTrue( _post_migrate_links_orig.count() > 0, - "No 'original' links has been found for the layer '{}'".format( - _lyr.alternate - ) + f"No 'original' links has been found for the layer '{_lyr.alternate}'" ) for _link_orig in _post_migrate_links_orig: self.assertIn( _link_orig.url, _lyr.csw_anytext, - "The link URL {0} is not present in the 'csw_anytext' attribute of the layer '{1}'".format( - _link_orig.url, - _lyr.alternate - ) - ) + f"The link URL {_link_orig.url} is not present in the 'csw_anytext' attribute of the layer '{_lyr.alternate}'") # Check catalogue catalogue = get_catalogue() record = catalogue.get_record(_lyr.uuid) self.assertIsNotNone(record) self.assertTrue( hasattr(record, 'links'), - "No records have been found in the catalogue for the resource '{}'".format( - _lyr.alternate - ) + f"No records have been found in the catalogue for the resource '{_lyr.alternate}'" ) # Check 'metadata' links for each record for mime, name, metadata_url in record.links['metadata']: @@ -1290,8 +1278,5 @@ def test_set_resources_links(self): _post_migrate_link_meta = None self.assertIsNotNone( _post_migrate_link_meta, - "No '{}' links have been found in the catalogue for the resource '{}'".format( - name, - _lyr.alternate - ) + f"No '{name}' links have been found in the catalogue for the resource '{_lyr.alternate}'" ) diff --git a/geonode/geoserver/upload.py b/geonode/geoserver/upload.py index a379c701629..59bd37e87cb 100644 --- a/geonode/geoserver/upload.py +++ b/geonode/geoserver/upload.py @@ -88,10 +88,7 @@ def geoserver_upload( assert overwrite, msg existing_type = resource.resource_type if existing_type != the_layer_type: - msg = ('Type of uploaded file %s (%s) ' - 'does not match type of existing ' - 'resource type ' - '%s' % (name, the_layer_type, existing_type)) + msg = f'Type of uploaded file {name} ({the_layer_type}) does not match type of existing resource type {existing_type}' logger.debug(msg) raise GeoNodeException(msg) @@ -109,11 +106,7 @@ def geoserver_upload( logger.debug("Uploading raster layer: [%s]", base_file) create_store_and_resource = _create_coveragestore else: - msg = ('The layer type for name %s is %s. It should be ' - '%s or %s,' % (name, - the_layer_type, - FeatureType.resource_type, - Coverage.resource_type)) + msg = f'The layer type for name {name} is {the_layer_type}. It should be {FeatureType.resource_type} or {Coverage.resource_type},' logger.warn(msg) raise GeoNodeException(msg) @@ -133,8 +126,7 @@ def geoserver_upload( overwrite=overwrite, workspace=workspace) except UploadError as e: - msg = ('Could not save the layer %s, there was an upload ' - 'error: %s' % (name, str(e))) + msg = f'Could not save the layer {name}, there was an upload error: {str(e)}' logger.warn(msg) e.args = (msg,) raise @@ -163,16 +155,14 @@ def geoserver_upload( workspace=workspace) if not gs_resource: - msg = ('GeoNode encountered problems when creating layer %s.' - 'It cannot find the Layer that matches this Workspace.' - 'try renaming your files.' % name) + msg = f'GeoNode encountered problems when creating layer {name}.It cannot find the Layer that matches this Workspace.try renaming your files.' logger.warn(msg) raise GeoNodeException(msg) assert gs_resource.name == name # Step 6. Make sure our data always has a valid projection - logger.debug('>>> Step 6. Making sure [%s] has a valid projection' % name) + logger.debug(f'>>> Step 6. Making sure [{name}] has a valid projection') _native_bbox = None try: _native_bbox = gs_resource.native_bbox @@ -183,7 +173,7 @@ def geoserver_upload( box = _native_bbox[:4] minx, maxx, miny, maxy = [float(a) for a in box] if -180 <= round(minx, 5) <= 180 and -180 <= round(maxx, 5) <= 180 and \ - -90 <= round(miny, 5) <= 90 and -90 <= round(maxy, 5) <= 90: + -90 <= round(miny, 5) <= 90 and -90 <= round(maxy, 5) <= 90: gs_resource.latlon_bbox = _native_bbox gs_resource.projection = "EPSG:4326" else: @@ -195,7 +185,7 @@ def geoserver_upload( logger.debug('BBOX coordinates forced to [-180, -90, 180, 90] for layer [%s].', name) # Step 7. Create the style and assign it to the created resource - logger.debug('>>> Step 7. Creating style for [%s]' % name) + logger.debug(f'>>> Step 7. Creating style for [{name}]') cat.save(gs_resource) publishing = cat.get_layer(name) or gs_resource sld = None @@ -220,13 +210,11 @@ def geoserver_upload( cat.create_style(name, sld, overwrite=overwrite, raw=True, workspace=workspace) cat.reset() except geoserver.catalog.ConflictingDataError as e: - msg = ('There was already a style named %s in GeoServer, ' - 'try to use: "%s"' % (name + "_layer", str(e))) + msg = f'There was already a style named {name}_layer in GeoServer, try to use: "{str(e)}"' logger.warn(msg) e.args = (msg,) except geoserver.catalog.UploadError as e: - msg = ('Error while trying to upload style named %s in GeoServer, ' - 'try to use: "%s"' % (name + "_layer", str(e))) + msg = f'Error while trying to upload style named {name}_layer in GeoServer, try to use: "{str(e)}"' e.args = (msg,) logger.exception(e) @@ -235,8 +223,7 @@ def geoserver_upload( style = cat.get_style(name, workspace=workspace) or cat.get_style(name) except Exception as e: style = cat.get_style('point') - msg = ('Could not find any suitable style in GeoServer ' - 'for Layer: "%s"' % (name)) + msg = f'Could not find any suitable style in GeoServer for Layer: "{name}"' e.args = (msg,) logger.exception(e) @@ -246,14 +233,13 @@ def geoserver_upload( try: cat.save(publishing) except geoserver.catalog.FailedRequestError as e: - msg = ('Error while trying to save resource named %s in GeoServer, ' - 'try to use: "%s"' % (publishing, str(e))) + msg = f'Error while trying to save resource named {publishing} in GeoServer, try to use: "{str(e)}"' e.args = (msg,) logger.exception(e) # Step 8. Create the Django record for the layer logger.debug('>>> Step 8. Creating Django record for [%s]', name) - alternate = workspace.name + ':' + gs_resource.name + alternate = f"{workspace.name}:{gs_resource.name}" layer_uuid = str(uuid.uuid1()) defaults = dict(store=gs_resource.store.name, diff --git a/geonode/geoserver/urls.py b/geonode/geoserver/urls.py index 30aa59400bf..45a52342cbf 100644 --- a/geonode/geoserver/urls.py +++ b/geonode/geoserver/urls.py @@ -55,16 +55,16 @@ downstream_path='pdf'), name='pdf_endpoint'), url(r'^(?P[^/]*)/(?P[^/]*)/ows', views.geoserver_proxy, - dict(proxy_path='/gs/%s' % settings.DEFAULT_WORKSPACE, downstream_path='ows')), + dict(proxy_path=f'/gs/{settings.DEFAULT_WORKSPACE}', downstream_path='ows')), url(r'^(?P[^/]*)/(?P[^/]*)/wms', views.geoserver_proxy, - dict(proxy_path='/gs/%s' % settings.DEFAULT_WORKSPACE, downstream_path='wms')), + dict(proxy_path=f'/gs/{settings.DEFAULT_WORKSPACE}', downstream_path='wms')), url(r'^(?P[^/]*)/(?P[^/]*)/wfs', views.geoserver_proxy, - dict(proxy_path='/gs/%s' % settings.DEFAULT_WORKSPACE, downstream_path='wfs')), + dict(proxy_path=f'/gs/{settings.DEFAULT_WORKSPACE}', downstream_path='wfs')), url(r'^(?P[^/]*)/(?P[^/]*)/wcs', views.geoserver_proxy, - dict(proxy_path='/gs/%s' % settings.DEFAULT_WORKSPACE, downstream_path='wcs')), + dict(proxy_path=f'/gs/{settings.DEFAULT_WORKSPACE}', downstream_path='wcs')), url(r'^updatelayers/$', views.updatelayers, name="updatelayers"), diff --git a/geonode/geoserver/views.py b/geonode/geoserver/views.py index 76d57a8b2b3..e53c39cd5a2 100644 --- a/geonode/geoserver/views.py +++ b/geonode/geoserver/views.py @@ -128,8 +128,7 @@ def layer_style(request, layername): old_default = layer.default_style if old_default.name == style_name: return HttpResponse( - "Default style for %s remains %s" % - (layer.name, style_name), status=200) + f"Default style for {layer.name} remains {style_name}", status=200) # This code assumes without checking # that the new default style name is included @@ -151,8 +150,7 @@ def layer_style(request, layername): pass return HttpResponse( - "Default style for %s changed to %s" % - (layer.name, style_name), status=200) + f"Default style for {layer.name} changed to {style_name}", status=200) @login_required @@ -189,7 +187,7 @@ def respond(*args, **kw): sld_name = extract_name_from_sld( gs_catalog, sld, sld_file=request.FILES['sld']) except Exception as e: - respond(errors="The uploaded SLD file is not valid XML: {}".format(e)) + respond(errors=f"The uploaded SLD file is not valid XML: {e}") name = data.get('name') or sld_name @@ -267,10 +265,8 @@ def layer_style_manage(request, layername): except (FailedRequestError, EnvironmentError): tb = traceback.format_exc() logger.debug(tb) - msg = ('Could not connect to geoserver at "%s"' - 'to manage style information for layer "%s"' % ( - ogc_server_settings.LOCATION, layer.name) - ) + msg = ( + f'Could not connect to geoserver at "{ogc_server_settings.LOCATION}"to manage style information for layer "{layer.name}"') logger.debug(msg) # If geoserver is not online, return an error return render( @@ -335,7 +331,7 @@ def layer_style_manage(request, layername): except (FailedRequestError, EnvironmentError, MultiValueDictKeyError): tb = traceback.format_exc() logger.debug(tb) - msg = ('Error Saving Styles for Layer "%s"' % (layer.name) + msg = (f'Error Saving Styles for Layer "{layer.name}"' ) logger.warn(msg) return render( @@ -420,7 +416,7 @@ def style_change_check(request, path): except Exception: authorized = (request.method == 'POST') # The user is probably trying to create a new style logger.warn( - 'There is not a style with such a name: %s.' % style_name) + f'There is not a style with such a name: {style_name}.') return authorized @@ -469,8 +465,7 @@ def strip_prefix(path, prefix): assert _prefix in path prefix_idx = path.index(_prefix) _prefix = path[:prefix_idx] + _prefix - full_prefix = "%s/%s/%s" % ( - _prefix, layername, downstream_path) if layername else _prefix + full_prefix = f"{_prefix}/{layername}/{downstream_path}" if layername else _prefix return path[len(full_prefix):] path = strip_prefix(request.get_full_path(), proxy_path) @@ -487,7 +482,7 @@ def strip_prefix(path, prefix): except Exception: pass - if proxy_path == '/gs/%s' % settings.DEFAULT_WORKSPACE and layername: + if proxy_path == f'/gs/{settings.DEFAULT_WORKSPACE}' and layername: import posixpath raw_url = urljoin(ogc_server_settings.LOCATION, posixpath.join(workspace, layername, downstream_path, path)) @@ -514,9 +509,9 @@ def strip_prefix(path, prefix): url = urlsplit(raw_url) affected_layers = None - if '%s/layers' % ws in path: + if f'{ws}/layers' in path: downstream_path = 'rest/layers' - elif '%s/styles' % ws in path: + elif f'{ws}/styles' in path: downstream_path = 'rest/styles' if request.method in ("POST", "PUT", "DELETE"): @@ -530,8 +525,7 @@ def strip_prefix(path, prefix): status=401) elif downstream_path == 'rest/styles': logger.debug( - "[geoserver_proxy] Updating Style ---> url %s" % - url.geturl()) + f"[geoserver_proxy] Updating Style ---> url {url.geturl()}") _style_name, _style_ext = os.path.splitext(os.path.basename(urlsplit(url.geturl()).path)) _parsed_get_args = dict(parse_qsl(urlsplit(url.geturl()).query)) if _style_name == 'styles.json' and request.method == "PUT": @@ -540,18 +534,17 @@ def strip_prefix(path, prefix): else: _style_name, _style_ext = os.path.splitext(_style_name) if _style_name != 'style-check' and (_style_ext == '.json' or _parsed_get_args.get('raw')) and \ - not re.match(temp_style_name_regex, _style_name): + not re.match(temp_style_name_regex, _style_name): affected_layers = style_update(request, raw_url) elif downstream_path == 'rest/layers': logger.debug( - "[geoserver_proxy] Updating Layer ---> url %s" % - url.geturl()) + f"[geoserver_proxy] Updating Layer ---> url {url.geturl()}") try: _layer_name = os.path.splitext(os.path.basename(request.path))[0] _layer = Layer.objects.get(name=_layer_name) affected_layers = [_layer] except Exception: - logger.warn("Could not find any Layer %s on DB" % os.path.basename(request.path)) + logger.warn(f"Could not find any Layer {os.path.basename(request.path)} on DB") kwargs = {'affected_layers': affected_layers} raw_url = unquote(raw_url) @@ -585,7 +578,7 @@ def _response_callback(**kwargs): _content = content.decode('UTF-8') else: _content = content - if re.findall(r"(?=(\b" + '|'.join(content_type_list) + r"\b))", content_type): + if re.findall(f"(?=(\\b{'|'.join(content_type_list)}\\b))", content_type): _gn_proxy_url = urljoin(settings.SITEURL, '/gs/') content = _content\ .replace(ogc_server_settings.LOCATION, _gn_proxy_url)\ @@ -720,13 +713,11 @@ def get_layer_capabilities(layer, version='1.3.0', access_token=None, tolerant=F """ workspace, layername = layer.alternate.split(":") if ":" in layer.alternate else (None, layer.alternate) if not layer.remote_service: - wms_url = '%s%s/%s/wms?service=wms&version=%s&request=GetCapabilities'\ - % (ogc_server_settings.LOCATION, workspace, layername, version) + wms_url = f'{ogc_server_settings.LOCATION}{workspace}/{layername}/wms?service=wms&version={version}&request=GetCapabilities' if access_token: - wms_url += ('&access_token=%s' % access_token) + wms_url += f'&access_token={access_token}' else: - wms_url = '%s?service=wms&version=%s&request=GetCapabilities'\ - % (layer.remote_service.service_url, version) + wms_url = f'{layer.remote_service.service_url}?service=wms&version={version}&request=GetCapabilities' _user, _password = ogc_server_settings.credentials req, content = http_client.get(wms_url, user=_user) @@ -735,10 +726,9 @@ def get_layer_capabilities(layer, version='1.3.0', access_token=None, tolerant=F if tolerant and ('ServiceException' in getcap or req.status_code == 404): # WARNING Please make sure to have enabled DJANGO CACHE as per # https://docs.djangoproject.com/en/2.0/topics/cache/#filesystem-caching - wms_url = '%s%s/ows?service=wms&version=%s&request=GetCapabilities&layers=%s'\ - % (ogc_server_settings.public_url, workspace, version, layer) + wms_url = f'{ogc_server_settings.public_url}{workspace}/ows?service=wms&version={version}&request=GetCapabilities&layers={layer}' if access_token: - wms_url += ('&access_token=%s' % access_token) + wms_url += f'&access_token={access_token}' req, content = http_client.get(wms_url, user=_user) getcap = ensure_string(content) @@ -757,14 +747,14 @@ def format_online_resource(workspace, layer, element, namespaces): if layerName is None: return - layerName.text = workspace + ":" + layer if workspace else layer + layerName.text = f"{workspace}:{layer}" if workspace else layer layerresources = element.findall('.//wms:OnlineResource', namespaces) if layerresources is None: return for resource in layerresources: wtf = resource.attrib['{http://www.w3.org/1999/xlink}href'] - replace_string = "/" + workspace + "/" + layer if workspace else "/" + layer + replace_string = f"/{workspace}/{layer}" if workspace else f"/{layer}" resource.attrib['{http://www.w3.org/1999/xlink}href'] = wtf.replace( replace_string, "") @@ -827,8 +817,7 @@ def get_capabilities(request, layerid=None, user=None, import traceback traceback.print_exc() logger.error( - "Error occurred creating GetCapabilities for %s: %s" % - (layer.typename, str(e))) + f"Error occurred creating GetCapabilities for {layer.typename}: {str(e)}") rootdoc = None if layercap is None or not len(layercap) or rootdoc is None or not len(rootdoc): # Get the required info from layer model @@ -847,8 +836,7 @@ def get_capabilities(request, layerid=None, user=None, import traceback traceback.print_exc() logger.error( - "Error occurred creating GetCapabilities for %s:%s" % - (layer.typename, str(e))) + f"Error occurred creating GetCapabilities for {layer.typename}:{str(e)}") rootdoc = None if rootdoc is not None: capabilities = etree.tostring( diff --git a/geonode/groups/__init__.py b/geonode/groups/__init__.py index ad24e55f272..649c895c057 100644 --- a/geonode/groups/__init__.py +++ b/geonode/groups/__init__.py @@ -31,7 +31,7 @@ def init_registered_members_groupprofile(): group_name = settings.REGISTERED_MEMBERS_GROUP_NAME group_title = settings.REGISTERED_MEMBERS_GROUP_TITLE - logger.debug("Creating %s default Group Profile" % group_name) + logger.debug(f"Creating {group_name} default Group Profile") groupprofile, created = GroupProfile.objects.get_or_create( slug=group_name) if created: @@ -43,5 +43,5 @@ def init_registered_members_groupprofile(): User = get_user_model() for _u in User.objects.filter(is_active=True): if not _u.is_anonymous and _u != User.get_anonymous() and \ - not groupprofile.user_is_member(_u): + not groupprofile.user_is_member(_u): groupprofile.join(_u) diff --git a/geonode/groups/models.py b/geonode/groups/models.py index 0d7545e26f6..ff64111de90 100644 --- a/geonode/groups/models.py +++ b/geonode/groups/models.py @@ -54,7 +54,7 @@ class Meta: verbose_name_plural = _('Group Categories') def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" def get_absolute_url(self): return reverse('group_category_detail', args=(self.slug,)) @@ -130,7 +130,7 @@ def groups_for_user(cls, user): return [] def __str__(self): - return "{0}".format(self.title) + return f"{self.title}" def keyword_list(self): """ @@ -201,7 +201,7 @@ def join(self, user, **kwargs): raise ValueError("The invited user cannot be anonymous") member, created = GroupMember.objects.get_or_create(group=self, user=user, defaults=kwargs) if not created: - logger.warning("The invited user \"{0}\" is already a member".format(user.username)) + logger.warning(f"The invited user \"{user.username}\" is already a member") def leave(self, user, **kwargs): if not user or user.is_anonymous or user == user.get_anonymous(): @@ -212,7 +212,7 @@ def leave(self, user, **kwargs): user.groups.remove(self.group) member.delete() else: - logger.warning("The invited user \"{0}\" is not a member".format(user.username)) + logger.warning(f"The invited user \"{user.username}\" is not a member") def get_absolute_url(self): return reverse('group_detail', args=[self.slug, ]) diff --git a/geonode/groups/search_indexes.py b/geonode/groups/search_indexes.py index a4ea2638660..1cca7db7f49 100644 --- a/geonode/groups/search_indexes.py +++ b/geonode/groups/search_indexes.py @@ -56,7 +56,7 @@ def prepare_json(self, obj): "title": obj.title, "description": obj.description, "keywords": [keyword.name for keyword in obj.keywords.all()] if obj.keywords else [], - "thumb": settings.STATIC_URL + "static/img/contact.png", + "thumb": f"{settings.STATIC_URL}static/img/contact.png", "detail": None, } diff --git a/geonode/groups/templatetags/groups_tags.py b/geonode/groups/templatetags/groups_tags.py index f36ea13957b..bb07fb4681e 100644 --- a/geonode/groups/templatetags/groups_tags.py +++ b/geonode/groups/templatetags/groups_tags.py @@ -34,7 +34,7 @@ def group_profile_image(group_profile, css_classes="", size=None): """ if isinstance(css_classes, string_types): - class_attr = 'class="{}" '.format(css_classes) + class_attr = f'class="{css_classes}" ' else: try: class_attr = 'class="{}" '.format( @@ -51,10 +51,5 @@ def group_profile_image(group_profile, css_classes="", size=None): url = group_profile.logo_url else: url = staticfiles_storage.url("geonode/img/default-avatar.jpg") - img_tag = '{alt}'.format( - css=class_attr, - style=style_attr, - url=url, - alt=group_profile.title, - ) + img_tag = f'{group_profile.title}' return img_tag diff --git a/geonode/groups/tests.py b/geonode/groups/tests.py index 4116e15cb08..5dd47937c86 100644 --- a/geonode/groups/tests.py +++ b/geonode/groups/tests.py @@ -927,7 +927,7 @@ def test_group_logo_is_present_on_list_view(self): slug="test", description="test", access="public", - logo=SimpleUploadedFile("dummy-file.jpg", "dummy contents".encode("UTF-8")) + logo=SimpleUploadedFile("dummy-file.jpg", "dummy contents".encode("UTF-8")) ) test_profile.save() response = self.client.get( diff --git a/geonode/groups/views.py b/geonode/groups/views.py index d352d1c0293..784e25831d5 100644 --- a/geonode/groups/views.py +++ b/geonode/groups/views.py @@ -147,7 +147,7 @@ def get(self, request, *args, **kwargs): self.group = get_object_or_404( models.GroupProfile, slug=kwargs.get('slug')) if self.group.access == 'private' and \ - not self.group.user_is_member(request.user): + not self.group.user_is_member(request.user): raise Http404 return super(GroupDetailView, self).get(request, *args, **kwargs) diff --git a/geonode/invitations/forms.py b/geonode/invitations/forms.py index 54e2bc9b705..80c2eb81d66 100644 --- a/geonode/invitations/forms.py +++ b/geonode/invitations/forms.py @@ -50,12 +50,9 @@ def clean_email(self): email = get_invitations_adapter().clean_email(em.strip()) errors = { - "already_invited": _("The e-mail address '%(email)s' has already been" - " invited." % {"email": email}), - "already_accepted": _("The e-mail address '%(email)s' has already" - " accepted an invite." % {"email": email}), - "email_in_use": _("An active user is already using the" - " e-mail address '%(email)s'" % {"email": email}), + "already_invited": _(f"The e-mail address '{email}' has already been invited."), + "already_accepted": _(f"The e-mail address '{email}' has already accepted an invite."), + "email_in_use": _(f"An active user is already using the e-mail address '{email}'"), } try: self.validate_invitation(email) diff --git a/geonode/layers/forms.py b/geonode/layers/forms.py index af2df6c81d2..8f64a804a24 100644 --- a/geonode/layers/forms.py +++ b/geonode/layers/forms.py @@ -153,16 +153,13 @@ def clean(self): if not cleaned["metadata_upload_form"] and not cleaned["style_upload_form"] and base_ext.lower() not in ( ".shp", ".tif", ".tiff", ".geotif", ".geotiff", ".asc", ".sld", ".kml", ".kmz"): raise forms.ValidationError( - "Only Shapefiles, GeoTiffs, and ASCIIs are supported. You " - "uploaded a %s file" % base_ext) + f"Only Shapefiles, GeoTiffs, and ASCIIs are supported. You uploaded a {base_ext} file") elif cleaned["metadata_upload_form"] and base_ext.lower() not in (".xml"): raise forms.ValidationError( - "Only XML files are supported. You uploaded a %s file" % - base_ext) + f"Only XML files are supported. You uploaded a {base_ext} file") elif cleaned["style_upload_form"] and base_ext.lower() not in (".sld"): raise forms.ValidationError( - "Only SLD files are supported. You uploaded a %s file" % - base_ext) + f"Only SLD files are supported. You uploaded a {base_ext} file") if base_ext.lower() == ".shp": if dbf_file is None or shx_file is None: @@ -187,14 +184,14 @@ def clean(self): # force rename of file so that file.shp.xml doesn't # overwrite as file.shp if cleaned.get("xml_file"): - cleaned["xml_file"].name = '%s.xml' % base_name + cleaned["xml_file"].name = f'{base_name}.xml' if sld_file is not None: if os.path.splitext(sld_file)[0] != base_name: if sld_file.find('.shp') != -1: # force rename of file so that file.shp.xml doesn't # overwrite as file.shp if cleaned.get("sld_file"): - cleaned["sld_file"].name = '%s.sld' % base_name + cleaned["sld_file"].name = f'{base_name}.sld' return cleaned def write_files(self): diff --git a/geonode/layers/management/commands/importlayers.py b/geonode/layers/management/commands/importlayers.py index 8965b237030..774b9c2f87d 100644 --- a/geonode/layers/management/commands/importlayers.py +++ b/geonode/layers/management/commands/importlayers.py @@ -244,4 +244,4 @@ def handle(self, *args, **options): print("{} Failed layers".format(len(failed))) if len(output) > 0: - print("{} seconds per layer".format(duration * 1.0 / len(output))) + print(f"{duration * 1.0 / len(output)} seconds per layer") diff --git a/geonode/layers/metadata.py b/geonode/layers/metadata.py index 411f0316e3e..f017da29161 100644 --- a/geonode/layers/metadata.py +++ b/geonode/layers/metadata.py @@ -45,7 +45,7 @@ def set_metadata(xml): exml = dlxml.fromstring(xml.encode()) except Exception as err: raise GeoNodeException( - 'Uploaded XML document is not XML: %s' % str(err)) + f'Uploaded XML document is not XML: {str(err)}') # check if document is an accepted XML metadata format tagname = get_tagname(exml) diff --git a/geonode/layers/models.py b/geonode/layers/models.py index 7bae89e2c1d..05841e138ee 100644 --- a/geonode/layers/models.py +++ b/geonode/layers/models.py @@ -87,7 +87,7 @@ class Style(models.Model, PermissionLevelMixin): workspace = models.CharField(max_length=255, null=True, blank=True) def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" def absolute_url(self): if self.sld_url: @@ -102,8 +102,7 @@ def absolute_url(self): return self.sld_url else: logger.error( - "SLD URL is empty for Style %s" % - self.name) + f"SLD URL is empty for Style {self.name}") return None def get_self_resource(self): @@ -139,15 +138,15 @@ def successful(self): return self.processed and self.errors is None def __str__(self): - _s = "[Upload session-id: {}]".format(self.id) + _s = f"[Upload session-id: {self.id}]" try: - _s += " - {}".format(self.resource.title) + _s += f" - {self.resource.title}" except Exception: pass - return "{0}".format(_s) + return f"{_s}" def __unicode__(self): - return "{0}".format(self.__str__()) + return f"{self.__str__()}" class Layer(ResourceBase): @@ -251,9 +250,7 @@ def ows_url(self): if self.remote_service is not None and self.remote_service.method == INDEXED: result = self.remote_service.service_url else: - result = "{base}ows".format( - base=settings.OGC_SERVER['default']['PUBLIC_LOCATION'], - ) + result = f"{settings.OGC_SERVER['default']['PUBLIC_LOCATION']}ows" return result @property @@ -263,7 +260,7 @@ def ptype(self): @property def service_typename(self): if self.remote_service is not None: - return "%s:%s" % (self.remote_service.name, self.alternate) + return f"{self.remote_service.name}:{self.alternate}" else: return self.alternate @@ -309,7 +306,7 @@ def get_base_file(self): if base_files_count == 0: return None, None - msg = 'There should only be one main file (.shp or .geotiff or .asc), found %s' % base_files_count + msg = f'There should only be one main file (.shp or .geotiff or .asc), found {base_files_count}' assert base_files_count == 1, msg # we need to check, for shapefile, if column names are valid @@ -318,7 +315,7 @@ def get_base_file(self): valid_shp, wrong_column_name, list_col = check_shp_columnnames( self) if wrong_column_name: - msg = 'Shapefile has an invalid column name: %s' % wrong_column_name + msg = f'Shapefile has an invalid column name: {wrong_column_name}' else: msg = _('File cannot be opened, maybe check the encoding') # AF: Removing assertion since if the original file does not exists anymore @@ -331,7 +328,7 @@ def get_base_file(self): def get_absolute_url(self): return reverse( 'layer_detail', - args=("%s:%s" % (self.store, self.alternate),) + args=(f"{self.store}:{self.alternate}",) ) def attribute_config(self): @@ -351,7 +348,7 @@ def attribute_config(self): return cfg def __str__(self): - return "{0}".format(self.alternate) + return f"{self.alternate}" class Meta: # custom permissions, @@ -573,8 +570,7 @@ class Attribute(models.Model): objects = AttributeManager() def __str__(self): - return "{0}".format( - self.attribute_label if self.attribute_label else self.attribute) + return f"{self.attribute_label if self.attribute_label else self.attribute}" def unique_values_as_list(self): return self.unique_values.split(',') @@ -625,7 +621,7 @@ def pre_save_layer(instance, sender, **kwargs): logger.debug("In pre_save_layer") if instance.alternate is None: instance.alternate = _get_alternate_name(instance) - logger.debug("instance.alternate is: {}".format(instance.alternate)) + logger.debug(f"instance.alternate is: {instance.alternate}") base_file, info = instance.get_base_file() @@ -633,7 +629,7 @@ def pre_save_layer(instance, sender, **kwargs): instance.info = info if base_file is not None: - extension = '.%s' % base_file.name + extension = f'.{base_file.name}' if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: @@ -662,7 +658,7 @@ def pre_save_layer(instance, sender, **kwargs): # Send a notification when a layer is created if instance.pk is None and instance.title: # Resource Created - notice_type_label = '%s_created' % instance.class_name.lower() + notice_type_label = f'{instance.class_name.lower()}_created' recipients = get_notification_recipients(notice_type_label, resource=instance) send_notification(recipients, notice_type_label, {'resource': instance}) diff --git a/geonode/layers/populate_layers_data.py b/geonode/layers/populate_layers_data.py index 71ee88dcd30..1aa2b551162 100644 --- a/geonode/layers/populate_layers_data.py +++ b/geonode/layers/populate_layers_data.py @@ -24,7 +24,7 @@ styles = [{"name": "test_style_1", - "sld_url": "{ogc_location}rest/styles/test_style.sld".format(ogc_location=ogc_location), + "sld_url": f"{ogc_location}rest/styles/test_style.sld", "sld_body": "", }, {"name": "test_style_2", - "sld_url": "{ogc_location}rest/styles/test_style.sld".format(ogc_location=ogc_location), + "sld_url": f"{ogc_location}rest/styles/test_style.sld", "sld_body": "", }, {"name": "test_style_3", - "sld_url": "{ogc_location}rest/styles/test_style.sld".format(ogc_location=ogc_location), + "sld_url": f"{ogc_location}rest/styles/test_style.sld", "sld_body": "", }, {"name": "Evaluación", - "sld_url": "{ogc_location}rest/styles/test_style.sld".format(ogc_location=ogc_location), + "sld_url": f"{ogc_location}rest/styles/test_style.sld", "sld_body": "\ diff --git a/geonode/layers/tasks.py b/geonode/layers/tasks.py index 318caaa2fb4..b0d561c0c68 100644 --- a/geonode/layers/tasks.py +++ b/geonode/layers/tasks.py @@ -48,7 +48,7 @@ def delete_layer(self, layer_id): except Layer.DoesNotExist: logger.warning(f"Layers {layer_id} does not exist!") return - logger.debug('Deleting Layer {0}'.format(layer)) + logger.debug(f'Deleting Layer {layer}') try: with transaction.atomic(): layer.delete() diff --git a/geonode/layers/tests.py b/geonode/layers/tests.py index a7a20d1b2e2..2e61b11bafb 100644 --- a/geonode/layers/tests.py +++ b/geonode/layers/tests.py @@ -318,7 +318,7 @@ def test_layer_save(self): response = self.client.get(reverse('layer_detail', args=(lyr.alternate,))) self.assertEqual(response.status_code, 200) - response = self.client.get(reverse('layer_detail', args=(":%s" % lyr.alternate,))) + response = self.client.get(reverse('layer_detail', args=(f":{lyr.alternate}",))) self.assertEqual(response.status_code, 200) response = self.client.get(reverse('layer_metadata', args=(lyr.alternate,))) @@ -388,19 +388,17 @@ def test_get_valid_user(self): # Verify it accepts an admin user adminuser = get_user_model().objects.get(is_superuser=True) valid_user = get_valid_user(adminuser) - msg = ('Passed in a valid admin user "%s" but got "%s" in return' - % (adminuser, valid_user)) + msg = f'Passed in a valid admin user "{adminuser}" but got "{valid_user}" in return' assert valid_user.id == adminuser.id, msg # Verify it returns a valid user after receiving None valid_user = get_valid_user(None) - msg = ('Expected valid user after passing None, got "%s"' % valid_user) + msg = f'Expected valid user after passing None, got "{valid_user}"' assert isinstance(valid_user, get_user_model()), msg newuser = get_user_model().objects.create(username='arieluser') valid_user = get_valid_user(newuser) - msg = ('Passed in a valid user "%s" but got "%s" in return' - % (newuser, valid_user)) + msg = f'Passed in a valid user "{newuser}" but got "{valid_user}" in return' assert valid_user.id == newuser.id, msg valid_user = get_valid_user('arieluser') @@ -566,7 +564,7 @@ def generate_files(*extensions): expected_files = None try: d = tempfile.mkdtemp() - fnames = ["foo." + ext for ext in extensions] + fnames = [f"foo.{ext}" for ext in extensions] expected_files = {ext.lower(): fname for ext, fname in zip(extensions, fnames)} for f in fnames: path = os.path.join(d, f) @@ -1121,7 +1119,7 @@ def _get_input_paths(self): base_name = 'single_point' suffixes = 'shp shx dbf prj'.split(' ') base_path = gisdata.GOOD_DATA - paths = [os.path.join(base_path, 'vector', '{}.{}'.format(base_name, suffix)) for suffix in suffixes] + paths = [os.path.join(base_path, 'vector', f'{base_name}.{suffix}') for suffix in suffixes] return paths, suffixes, @on_ogc_backend(geoserver.BACKEND_PACKAGE) @@ -1143,7 +1141,7 @@ def test_moderated_upload(self, thumbnail_mock): with contextlib.ExitStack() as stack: input_files = [ stack.enter_context(_fp) for _fp in input_files] - files = dict(zip(['{}_file'.format(s) for s in suffixes], input_files)) + files = dict(zip([f'{s}_file' for s in suffixes], input_files)) files['base_file'] = files.pop('shp_file') files['permissions'] = '{}' files['charset'] = 'utf-8' @@ -1175,7 +1173,7 @@ def test_moderated_upload(self, thumbnail_mock): with contextlib.ExitStack() as stack: input_files = [ stack.enter_context(_fp) for _fp in input_files] - files = dict(zip(['{}_file'.format(s) for s in suffixes], input_files)) + files = dict(zip([f'{s}_file' for s in suffixes], input_files)) files['base_file'] = files.pop('shp_file') files['permissions'] = '{}' files['charset'] = 'utf-8' @@ -1367,11 +1365,11 @@ def test_geonode_upload_kml_and_import_isocategory(self): for fnsuffix in filename_suffix_list: files = dict( base_file=SimpleUploadedFile( - thelayer_basename + '_' + fnsuffix + '.kml', - open(thelayer_path + thelayer_basename + '_' + fnsuffix + '.kml', mode='rb').read()), + f"{thelayer_basename}_{fnsuffix}.kml", + open(f"{thelayer_path + thelayer_basename}_{fnsuffix}.kml", mode='rb').read()), xml_file=SimpleUploadedFile( - thelayer_basename + '_' + fnsuffix + '.xml', - open(thelayer_path + thelayer_basename + '_' + fnsuffix + '.xml', mode='rb').read()) + f"{thelayer_basename}_{fnsuffix}.xml", + open(f"{thelayer_path + thelayer_basename}_{fnsuffix}.xml", mode='rb').read()) ) files['permissions'] = '{}' files['charset'] = 'utf-8' @@ -1414,28 +1412,28 @@ def test_geonode_rest_layer_uploader(self): thelayer_name = 'ming_female_1' thelayer_path = os.path.join( PROJECT_ROOT, - '../tests/data/%s' % thelayer_name) + f'../tests/data/{thelayer_name}') files = dict( base_file=SimpleUploadedFile( - '%s.shp' % thelayer_name, + f'{thelayer_name}.shp', open(os.path.join(thelayer_path, - '%s.shp' % thelayer_name), mode='rb').read()), + f'{thelayer_name}.shp'), mode='rb').read()), shx_file=SimpleUploadedFile( - '%s.shx' % thelayer_name, + f'{thelayer_name}.shx', open(os.path.join(thelayer_path, - '%s.shx' % thelayer_name), mode='rb').read()), + f'{thelayer_name}.shx'), mode='rb').read()), dbf_file=SimpleUploadedFile( - '%s.dbf' % thelayer_name, + f'{thelayer_name}.dbf', open(os.path.join(thelayer_path, - '%s.dbf' % thelayer_name), mode='rb').read()), + f'{thelayer_name}.dbf'), mode='rb').read()), prj_file=SimpleUploadedFile( - '%s.prj' % thelayer_name, + f'{thelayer_name}.prj', open(os.path.join(thelayer_path, - '%s.prj' % thelayer_name), mode='rb').read()) + f'{thelayer_name}.prj'), mode='rb').read()) ) files['permissions'] = '{}' files['charset'] = 'windows-1258' - files['layer_title'] = 'test layer_{}'.format('windows-1258') + files['layer_title'] = "test layer_windows-1258" resp = self.client.post(layer_upload_url, data=files) # Check response status code if resp.status_code == 200: @@ -1484,34 +1482,34 @@ def test_geonode_same_UUID_error(self, thumbnail_mock): thelayer_name = 'hydrodata' thelayer_path = os.path.join( PROJECT_ROOT, - '../tests/data/%s' % thelayer_name) + f'../tests/data/{thelayer_name}') # Uploading the first one should be OK same_uuid_root_file = 'same_uuid_a' files = dict( base_file=SimpleUploadedFile( - '%s.shp' % same_uuid_root_file, + f'{same_uuid_root_file}.shp', open(os.path.join(thelayer_path, - '%s.shp' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.shp'), mode='rb').read()), shx_file=SimpleUploadedFile( - '%s.shx' % same_uuid_root_file, + f'{same_uuid_root_file}.shx', open(os.path.join(thelayer_path, - '%s.shx' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.shx'), mode='rb').read()), dbf_file=SimpleUploadedFile( - '%s.dbf' % same_uuid_root_file, + f'{same_uuid_root_file}.dbf', open(os.path.join(thelayer_path, - '%s.dbf' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.dbf'), mode='rb').read()), prj_file=SimpleUploadedFile( - '%s.prj' % same_uuid_root_file, + f'{same_uuid_root_file}.prj', open(os.path.join(thelayer_path, - '%s.prj' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.prj'), mode='rb').read()), xml_file=SimpleUploadedFile( - '%s.xml' % same_uuid_root_file, + f'{same_uuid_root_file}.xml', open(os.path.join(thelayer_path, - '%s.xml' % same_uuid_root_file), mode='rb').read()) + f'{same_uuid_root_file}.xml'), mode='rb').read()) ) files['permissions'] = '{}' files['charset'] = 'utf-8' - files['layer_title'] = 'test layer_{}'.format(same_uuid_root_file) + files['layer_title'] = f'test layer_{same_uuid_root_file}' resp = self.client.post(layer_upload_url, data=files) # Check response status code self.assertEqual(resp.status_code, 200) @@ -1520,29 +1518,29 @@ def test_geonode_same_UUID_error(self, thumbnail_mock): same_uuid_root_file = 'same_uuid_b' files = dict( base_file=SimpleUploadedFile( - '%s.shp' % same_uuid_root_file, + f'{same_uuid_root_file}.shp', open(os.path.join(thelayer_path, - '%s.shp' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.shp'), mode='rb').read()), shx_file=SimpleUploadedFile( - '%s.shx' % same_uuid_root_file, + f'{same_uuid_root_file}.shx', open(os.path.join(thelayer_path, - '%s.shx' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.shx'), mode='rb').read()), dbf_file=SimpleUploadedFile( - '%s.dbf' % same_uuid_root_file, + f'{same_uuid_root_file}.dbf', open(os.path.join(thelayer_path, - '%s.dbf' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.dbf'), mode='rb').read()), prj_file=SimpleUploadedFile( - '%s.prj' % same_uuid_root_file, + f'{same_uuid_root_file}.prj', open(os.path.join(thelayer_path, - '%s.prj' % same_uuid_root_file), mode='rb').read()), + f'{same_uuid_root_file}.prj'), mode='rb').read()), xml_file=SimpleUploadedFile( - '%s.xml' % same_uuid_root_file, + f'{same_uuid_root_file}.xml', open(os.path.join(thelayer_path, - '%s.xml' % same_uuid_root_file), mode='rb').read()) + f'{same_uuid_root_file}.xml'), mode='rb').read()) ) files['permissions'] = '{}' files['charset'] = 'utf-8' - files['layer_title'] = 'test layer_{}'.format(same_uuid_root_file) + files['layer_title'] = f'test layer_{same_uuid_root_file}' resp = self.client.post(layer_upload_url, data=files) # Check response status code self.assertEqual(resp.status_code, 400) diff --git a/geonode/layers/utils.py b/geonode/layers/utils.py index f5188e56ea8..9a40a5087d7 100644 --- a/geonode/layers/utils.py +++ b/geonode/layers/utils.py @@ -82,7 +82,7 @@ logger = logging.getLogger('geonode.layers.utils') -_separator = '\n' + ('-' * 100) + '\n' +_separator = f"\n{'-' * 100}\n" def _clean_string( @@ -126,8 +126,7 @@ def get_files(filename): try: filename.encode('ascii') except UnicodeEncodeError: - msg = "Please use only characters from the english alphabet for the filename. '%s' is not yet supported." \ - % os.path.basename(filename).encode('UTF-8', 'strict') + msg = f"Please use only characters from the english alphabet for the filename. '{os.path.basename(filename).encode('UTF-8', 'strict')}' is not yet supported." raise GeoNodeException(msg) # Let's unzip the filname in case it is a ZIP file @@ -153,8 +152,7 @@ def get_files(filename): # Make sure the file exists. if not os.path.exists(filename): - msg = ('Could not open %s. Make sure you are using a ' - 'valid file' % filename) + msg = f'Could not open {filename}. Make sure you are using a valid file' logger.debug(msg) raise GeoNodeException(msg) @@ -170,7 +168,7 @@ def get_files(filename): if len(matches) == 0: msg = ('Expected helper file %s does not exist; a Shapefile ' 'requires helper files with the following extensions: ' - '%s') % (base_name + "." + ext, + '%s') % (f"{base_name}.{ext}", list(required_extensions.keys())) raise GeoNodeException(msg) elif len(matches) > 1: @@ -180,7 +178,7 @@ def get_files(filename): else: files[ext] = matches[0] - matches = glob.glob(glob_name + ".[pP][rR][jJ]") + matches = glob.glob(f"{glob_name}.[pP][rR][jJ]") if len(matches) == 1: files['prj'] = matches[0] elif len(matches) > 1: @@ -193,11 +191,11 @@ def get_files(filename): # Only for GeoServer if check_ogc_backend(geoserver.BACKEND_PACKAGE): - matches = glob.glob(os.path.dirname(glob_name) + ".[sS][lL][dD]") + matches = glob.glob(f"{os.path.dirname(glob_name)}.[sS][lL][dD]") if len(matches) == 1: files['sld'] = matches[0] else: - matches = glob.glob(glob_name + ".[sS][lL][dD]") + matches = glob.glob(f"{glob_name}.[sS][lL][dD]") if len(matches) == 1: files['sld'] = matches[0] elif len(matches) > 1: @@ -205,12 +203,12 @@ def get_files(filename): 'distinct by spelling and not just case.') % filename raise GeoNodeException(msg) - matches = glob.glob(glob_name + ".[xX][mM][lL]") + matches = glob.glob(f"{glob_name}.[xX][mM][lL]") # shapefile XML metadata is sometimes named base_name.shp.xml # try looking for filename.xml if base_name.xml does not exist if len(matches) == 0: - matches = glob.glob(filename + ".[xX][mM][lL]") + matches = glob.glob(f"{filename}.[xX][mM][lL]") if len(matches) == 1: files['xml'] = matches[0] @@ -252,7 +250,7 @@ def layer_type(filename): elif extension.lower() in cov_exts: return 'raster' else: - msg = ('Saving of extension [%s] is not implemented' % extension) + msg = f'Saving of extension [{extension}] is not implemented' raise GeoNodeException(msg) @@ -265,7 +263,7 @@ def get_valid_name(layer_name): while Layer.objects.filter(name=proposed_name).exists(): possible_chars = string.ascii_lowercase + string.digits suffix = "".join([choice(possible_chars) for i in range(4)]) - proposed_name = '%s_%s' % (name, suffix) + proposed_name = f'{name}_{suffix}' logger.debug('Requested name already used; adjusting name ' '[%s] => [%s]', layer_name, proposed_name) @@ -327,7 +325,7 @@ def get_resolution(filename): gtif = gdal.Open(filename) gt = gtif.GetGeoTransform() __, resx, __, __, __, resy = gt - resolution = '%s %s' % (resx, resy) + resolution = f'{resx} {resy}' return resolution except Exception: return None @@ -402,7 +400,7 @@ def get_bbox(filename): except Exception: pass - return [bbox_x0, bbox_x1, bbox_y0, bbox_y1, "EPSG:%s" % str(srid)] + return [bbox_x0, bbox_x1, bbox_y0, bbox_y1, f"EPSG:{str(srid)}"] @transaction.atomic @@ -478,7 +476,7 @@ def file_upload(filename, absolute_base_file = None if not absolute_base_file or \ - os.path.splitext(absolute_base_file)[1].lower() != '.shp': + os.path.splitext(absolute_base_file)[1].lower() != '.shp': raise Exception( _("You are attempting to replace a vector layer with an unknown format.")) else: @@ -505,7 +503,7 @@ def file_upload(filename, that is consistent with the file you are trying to replace.")) except Exception as e: raise Exception( - _("Some error occurred while trying to access the uploaded schema: %s" % str(e))) + _(f"Some error occurred while trying to access the uploaded schema: {str(e)}")) # Set a default title that looks nice ... if title is None: @@ -550,8 +548,7 @@ def file_upload(filename, with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File( - f, name='%s.%s' % - (assigned_name or valid_name, type_name))) + f, name=f'{assigned_name or valid_name}.{type_name}')) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name @@ -795,8 +792,7 @@ def upload(incoming, user=None, overwrite=False, potential_files.append((basename, filename)) elif not os.path.isdir(incoming): - msg = ('Please pass a filename or a directory name as the "incoming" ' - 'parameter, instead of %s: %s' % (incoming, type(incoming))) + msg = f'Please pass a filename or a directory name as the "incoming" parameter, instead of {incoming}: {type(incoming)}' logger.exception(msg) raise GeoNodeException(msg) else: @@ -914,13 +910,13 @@ def delete_orphaned_layers(): for filename in files: if LayerFile.objects.filter(file__icontains=filename).count() == 0: - logger.debug("Deleting orphaned layer file " + filename) + logger.debug(f"Deleting orphaned layer file {filename}") try: storage.delete(os.path.join("layers", filename)) deleted.append(filename) except NotImplementedError as e: logger.error( - "Failed to delete orphaned layer file '{}': {}".format(filename, e)) + f"Failed to delete orphaned layer file '{filename}': {e}") return deleted @@ -946,9 +942,7 @@ def set_layers_permissions(permissions_name, resources_names=None, resources = Layer.objects.filter(Q(title__in=resources_names) | Q(name__in=resources_names)) except Layer.DoesNotExist: logger.warning( - 'No resources have been found with these names: %s.' % ( - ", ".join(resources_names) - ) + f"No resources have been found with these names: {', '.join(resources_names)}." ) if not resources: logger.warning("No resources have been found. No update operations have been executed.") @@ -963,7 +957,7 @@ def set_layers_permissions(permissions_name, resources_names=None, permissions = READ_PERMISSIONS else: permissions = READ_PERMISSIONS + WRITE_PERMISSIONS \ - + DOWNLOAD_PERMISSIONS + OWNER_PERMISSIONS + + DOWNLOAD_PERMISSIONS + OWNER_PERMISSIONS elif permissions_name.lower() in ('write', 'w'): if not delete_flag: permissions = READ_PERMISSIONS + WRITE_PERMISSIONS @@ -977,7 +971,7 @@ def set_layers_permissions(permissions_name, resources_names=None, elif permissions_name.lower() in ('owner', 'o'): if not delete_flag: permissions = READ_PERMISSIONS + WRITE_PERMISSIONS \ - + DOWNLOAD_PERMISSIONS + OWNER_PERMISSIONS + + DOWNLOAD_PERMISSIONS + OWNER_PERMISSIONS else: permissions = OWNER_PERMISSIONS if not permissions: @@ -1000,8 +994,7 @@ def set_layers_permissions(permissions_name, resources_names=None, users.append(user) except User.DoesNotExist: logger.warning( - 'The user {} does not exists. ' - 'It has been skipped.'.format(username) + f'The user {username} does not exists. It has been skipped.' ) # GROUPS groups = [] @@ -1012,8 +1005,7 @@ def set_layers_permissions(permissions_name, resources_names=None, groups.append(group) except Group.DoesNotExist: logger.warning( - 'The group {} does not exists. ' - 'It has been skipped.'.format(group_name) + f'The group {group_name} does not exists. It has been skipped.' ) if not users and not groups: logger.error( @@ -1065,15 +1057,11 @@ def set_layers_permissions(permissions_name, resources_names=None, perm_spec["users"][_user] = list(u_perms_set) else: logger.warning( - "The user %s does not have " - "any permission on the layer %s. " - "It has been skipped." % (_user.username, resource.title) + f"The user {_user.username} does not have any permission on the layer {resource.title}. It has been skipped." ) else: logger.warning( - "Warning! - The user %s is the layer %s owner, " - "so its permissions can't be changed. " - "It has been skipped." % (_user.username, resource.title) + f"Warning! - The user {_user.username} is the layer {resource.title} owner, so its permissions can't be changed. It has been skipped." ) for g in groups: _group = g @@ -1106,8 +1094,7 @@ def set_layers_permissions(permissions_name, resources_names=None, perm_spec["groups"][g] = list(g_perms_set) else: logger.warning( - "The group %s does not have any permission on the layer %s. " - "It has been skipped." % (g.name, resource.title) + f"The group {g.name} does not have any permission on the layer {resource.title}. It has been skipped." ) # Set final permissions resource.set_permissions(perm_spec) diff --git a/geonode/layers/views.py b/geonode/layers/views.py index 2f10a256f53..611670bd9ab 100644 --- a/geonode/layers/views.py +++ b/geonode/layers/views.py @@ -140,7 +140,7 @@ def log_snippet(log_file): if not log_file or not os.path.isfile(log_file): - return "No log file at %s" % log_file + return f"No log file at {log_file}" with open(log_file, "r") as f: f.seek(0, 2) # Seek @ EOF @@ -442,9 +442,7 @@ def sld_definition(style): "legend": { "height": "40", "width": "22", - "href": layer.ows_url + - "?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=" + - quote(layer.service_typename, safe=''), + "href": f"{layer.ows_url}?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer={quote(layer.service_typename, safe='')}", "format": "image/png" }, "name": style.name @@ -467,12 +465,11 @@ def sld_definition(style): ] # Add required parameters for GXP lazy-loading - attribution = "%s %s" % (layer.owner.first_name, - layer.owner.last_name) if layer.owner.first_name or layer.owner.last_name else str( + attribution = f"{layer.owner.first_name} {layer.owner.last_name}" if layer.owner.first_name or layer.owner.last_name else str( layer.owner) srs = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') srs_srid = int(srs.split(":")[1]) if srs != "EPSG:900913" else 3857 - config["attribution"] = "%s" % attribution + config["attribution"] = f"{attribution}" config["format"] = getattr( settings, 'DEFAULT_LAYER_FORMAT', 'image/png') config["title"] = layer.title @@ -560,7 +557,7 @@ def sld_definition(style): e = dlxml.fromstring(wms_capabilities) for atype in e.findall( - "./[wms:Name='%s']/wms:Dimension[@name='time']" % (layer.alternate), namespaces): + f"./[wms:Name='{layer.alternate}']/wms:Dimension[@name='time']", namespaces): dim_name = atype.get('name') if dim_name: dim_name = str(dim_name).lower() @@ -634,7 +631,7 @@ def sld_definition(style): "remote": True, "url": service.service_url, "name": service.name, - "title": "[R] %s" % service.title} + "title": f"[R] {service.title}"} maplayer = GXPLayer( name=layer.alternate, ows_url=layer.ows_url, @@ -928,7 +925,7 @@ def layer_metadata( "remote": True, "url": service.service_url, "name": service.name, - "title": "[R] %s" % service.title} + "title": f"[R] {service.title}"} maplayer = GXPLayer( name=layer.alternate, ows_url=layer.ows_url, @@ -1050,9 +1047,8 @@ def layer_metadata( if len(tkl) > 0: tkl_ids = ",".join( map(str, tkl.values_list('id', flat=True))) - tkeywords_list += "," + \ - tkl_ids if len( - tkeywords_list) > 0 else tkl_ids + tkeywords_list += f",{tkl_ids}" if len( + tkeywords_list) > 0 else tkl_ids except Exception: tb = traceback.format_exc() logger.error(tb) @@ -1100,7 +1096,7 @@ def layer_metadata( new_category = None if category_form and 'category_choice_field' in category_form.cleaned_data and\ - category_form.cleaned_data['category_choice_field']: + category_form.cleaned_data['category_choice_field']: new_category = TopicCategory.objects.get( id=int(category_form.cleaned_data['category_choice_field'])) @@ -1384,7 +1380,7 @@ def layer_remove(request, layername, template='layers/layer_remove.html'): }) if (request.method == 'POST'): try: - logger.debug('Deleting Layer {0}'.format(layer)) + logger.debug(f'Deleting Layer {layer}') with transaction.atomic(): Layer.objects.filter(id=layer.id).delete() except IntegrityError: @@ -1669,12 +1665,12 @@ def batch_permissions(request, model): users_usernames = [_data['user'].username, ] if _data['user'] else None groups_names = [_data['group'].name, ] if _data['group'] else None if users_usernames and 'AnonymousUser' in users_usernames and \ - (not groups_names or 'anonymous' not in groups_names): + (not groups_names or 'anonymous' not in groups_names): if not groups_names: groups_names = [] groups_names.append('anonymous') if groups_names and 'anonymous' in groups_names and \ - (not users_usernames or 'AnonymousUser' not in users_usernames): + (not users_usernames or 'AnonymousUser' not in users_usernames): if not users_usernames: users_usernames = [] users_usernames.append('AnonymousUser') diff --git a/geonode/maps/management/commands/remove_broken_layers.py b/geonode/maps/management/commands/remove_broken_layers.py index 272ef0ab10d..381273022c5 100644 --- a/geonode/maps/management/commands/remove_broken_layers.py +++ b/geonode/maps/management/commands/remove_broken_layers.py @@ -31,5 +31,5 @@ def handle(self, *args, **options): map_layers = MapLayer.objects.filter(local=True) for maplayer in map_layers: if not Layer.objects.filter(alternate=maplayer.name).exists(): - print('Removing broken map layer {}'.format(maplayer.name)) + print(f'Removing broken map layer {maplayer.name}') maplayer.delete() diff --git a/geonode/maps/management/commands/updatemaplayerip.py b/geonode/maps/management/commands/updatemaplayerip.py index 00f581c12b9..2714918db35 100644 --- a/geonode/maps/management/commands/updatemaplayerip.py +++ b/geonode/maps/management/commands/updatemaplayerip.py @@ -30,5 +30,5 @@ def handle(self, *args, **options): site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL map_layers = MapLayer.objects.filter(local=True) for maplayer in map_layers: - maplayer.ows_url = site_url + "/geoserver/wms" + maplayer.ows_url = f"{site_url}/geoserver/wms" maplayer.save() diff --git a/geonode/maps/models.py b/geonode/maps/models.py index fbc3ce56fbe..d3f42ab050f 100644 --- a/geonode/maps/models.py +++ b/geonode/maps/models.py @@ -131,17 +131,15 @@ def json(self, layer_filter): # the readme text will appear in a README file in the zip readme = ( - "Title: %s\n" + - "Author: %s\n" + - "Abstract: %s\n" + "Title: %s\nAuthor: %s\nAbstract: %s\n" ) % (self.title, self.poc, self.abstract) if self.license: - readme += "License: %s" % self.license + readme += f"License: {self.license}" if self.license.url: - readme += " (%s)" % self.license.url + readme += f" ({self.license.url})" readme += "\n" if self.constraints_other: - readme += "Additional constraints: %s\n" % self.constraints_other + readme += f"Additional constraints: {self.constraints_other}\n" def layer_json(lyr): return { @@ -290,16 +288,14 @@ def create_from_layer_list(self, user, layers, title, abstract): layer = Layer.objects.get(alternate=layer) except ObjectDoesNotExist: raise Exception( - 'Could not find layer with name %s' % - layer) + f'Could not find layer with name {layer}') if not user.has_perm( 'base.view_resourcebase', obj=layer.resourcebase_ptr): # invisible layer, skip inclusion or raise Exception? logger.error( - 'User %s tried to create a map with layer %s without having premissions' % - (user, layer)) + f'User {user} tried to create a map with layer {layer} without having premissions') else: _layers.append(layer) @@ -499,10 +495,7 @@ class MapLayer(models.Model, GXPLayerBase): def layer_config(self, user=None): # Try to use existing user-specific cache of layer config if self.id: - cfg = cache.get("layer_config" + - str(self.id) + - "_" + - str(0 if user is None else user.id)) + cfg = cache.get(f"layer_config{str(self.id)}_{str(0 if user is None else user.id)}") if cfg is not None: return cfg @@ -537,10 +530,7 @@ def layer_config(self, user=None): # Create temporary cache of maplayer config, should not last too long in case # local layer permissions or configuration values change (default # is 5 minutes) - cache.set("layer_config" + - str(self.id) + - "_" + - str(0 if user is None else user.id), cfg) + cache.set(f"layer_config{str(self.id)}_{str(0 if user is None else user.id)}", cfg) return cfg @property @@ -569,12 +559,11 @@ def local_link(self): store=self.store, alternate=self.name) else: layer = Layer.objects.get(alternate=self.name) - link = "%s" % ( - layer.get_absolute_url(), layer.title) + link = f"{layer.title}" except Exception: link = None if link is None: - link = "%s " % self.name + link = f"{self.name} " return link @property @@ -604,7 +593,7 @@ class Meta: ordering = ["stack_order"] def __str__(self): - return '%s?layers=%s' % (self.ows_url, self.name) + return f'{self.ows_url}?layers={self.name}' def pre_delete_map(instance, sender, **kwrargs): diff --git a/geonode/maps/qgis_server_views.py b/geonode/maps/qgis_server_views.py index 40ce83eb076..69eaf97d49b 100644 --- a/geonode/maps/qgis_server_views.py +++ b/geonode/maps/qgis_server_views.py @@ -155,7 +155,7 @@ def get_context_data(self, **kwargs): if access_token and ogc_server_url == service_url and \ 'access_token' not in service.base_url: - url = '%s?access_token=%s' % (service.base_url, access_token) + url = f'{service.base_url}?access_token={access_token}' else: url = service.base_url map_layers = MapLayer(map=map_obj, @@ -168,7 +168,7 @@ def get_context_data(self, **kwargs): "remote": True, "url": url, "name": service.name, - "title": "[R] %s" % service.title})) + "title": f"[R] {service.title}"})) else: ogc_server_url = urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc @@ -176,8 +176,7 @@ def get_context_data(self, **kwargs): if access_token and ogc_server_url == layer_url and \ 'access_token' not in layer.ows_url: - url = layer.ows_url + '?access_token=' + \ - access_token + url = f"{layer.ows_url}?access_token={access_token}" else: url = layer.ows_url map_layers = MapLayer( @@ -500,15 +499,13 @@ def perm_filter(layer): }) json_layers = json.dumps(map_layers) - url_server = settings.QGIS_SERVER_URL \ - + '?SERVICE=LAYERDEFINITIONS&LAYERS=' + json_layers + url_server = f"{settings.QGIS_SERVER_URL}?SERVICE=LAYERDEFINITIONS&LAYERS={json_layers}" fwd_request = requests.get(url_server) response = HttpResponse( fwd_request.content, content_type="application/x-qgis-layer-definition", status=fwd_request.status_code) - response['Content-Disposition'] = 'attachment; filename=%s.qlr' \ - % map_obj.title + response['Content-Disposition'] = f'attachment; filename={map_obj.title}.qlr' return response @@ -548,8 +545,7 @@ def map_download_leaflet(request, mapid, response = HttpResponse( the_page.content, content_type="html", status=the_page.status_code) - response['Content-Disposition'] = 'attachment; filename=%s.html' \ - % (map_obj.title,) + response['Content-Disposition'] = f'attachment; filename={map_obj.title}.html' return response @@ -575,7 +571,7 @@ def set_thumbnail_map(request, mapid): _l = Layer.objects.get(typename=layer.name) layers[_l.name] = _l except Layer.DoesNotExist: - msg = 'No Layer found for typename: {0}'.format(layer.name) + msg = f'No Layer found for typename: {layer.name}' logger.debug(msg) if not layers: diff --git a/geonode/maps/tests.py b/geonode/maps/tests.py index b6ad0f5bf01..ed6a81dd3a8 100644 --- a/geonode/maps/tests.py +++ b/geonode/maps/tests.py @@ -328,16 +328,16 @@ def test_new_map_without_layers(self): def test_new_map_with_layer(self): layer = Layer.objects.all().first() - self.client.get(reverse('new_map') + '?layer=' + layer.alternate) + self.client.get(f"{reverse('new_map')}?layer={layer.alternate}") def test_new_map_with_empty_bbox_layer(self): layer = Layer.objects.all().first() - self.client.get(reverse('new_map') + '?layer=' + layer.alternate) + self.client.get(f"{reverse('new_map')}?layer={layer.alternate}") def test_add_layer_to_existing_map(self): layer = Layer.objects.all().first() map_obj = Map.objects.all().first() - self.client.get(reverse('add_layer') + '?layer_name=%s&map_id=%s' % (layer.alternate, map_obj.id)) + self.client.get(f"{reverse('add_layer')}?layer_name={layer.alternate}&map_id={map_obj.id}") map_obj = Map.objects.get(id=map_obj.id) for map_layer in map_obj.layers: diff --git a/geonode/maps/utils.py b/geonode/maps/utils.py index 9b7858391e3..cfc8a80dc26 100644 --- a/geonode/maps/utils.py +++ b/geonode/maps/utils.py @@ -86,7 +86,7 @@ def fix_baselayers(map_id): return if not Map.objects.filter(pk=id).exists(): - logger.error('There is not a map with id %s' % id) + logger.error(f'There is not a map with id {id}') return map = Map.objects.get(pk=id) diff --git a/geonode/maps/views.py b/geonode/maps/views.py index 14423449ddc..ea85379f319 100644 --- a/geonode/maps/views.py +++ b/geonode/maps/views.py @@ -265,9 +265,8 @@ def map_metadata( if len(tkl) > 0: tkl_ids = ",".join( map(str, tkl.values_list('id', flat=True))) - tkeywords_list += "," + \ - tkl_ids if len( - tkeywords_list) > 0 else tkl_ids + tkeywords_list += f",{tkl_ids}" if len( + tkeywords_list) > 0 else tkl_ids except Exception: tb = traceback.format_exc() logger.error(tb) @@ -623,7 +622,7 @@ def map_json_handle_put(request, mapid): map_obj.viewer_json(request))) except ValueError as e: return HttpResponse( - "The server could not understand the request." + str(e), + f"The server could not understand the request.{str(e)}", content_type="text/plain", status=400 ) @@ -854,13 +853,9 @@ def sld_definition(style): "legend": { "height": "40", "width": "22", - "href": layer.ows_url + - "?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=" + - quote(layer.service_typename, safe=''), - "format": "image/png" - }, - "name": style.name - } + "href": f"{layer.ows_url}?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer={quote(layer.service_typename, safe='')}", + "format": "image/png"}, + "name": style.name} return _sld config = layer.attribute_config() @@ -870,12 +865,11 @@ def sld_definition(style): 'properties': layer.srid } # Add required parameters for GXP lazy-loading - attribution = "%s %s" % (layer.owner.first_name, - layer.owner.last_name) if layer.owner.first_name or layer.owner.last_name else str( + attribution = f"{layer.owner.first_name} {layer.owner.last_name}" if layer.owner.first_name or layer.owner.last_name else str( layer.owner) srs = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') srs_srid = int(srs.split(":")[1]) if srs != "EPSG:900913" else 3857 - config["attribution"] = "%s" % attribution + config["attribution"] = f"{attribution}" config["format"] = getattr( settings, 'DEFAULT_LAYER_FORMAT', 'image/png') config["title"] = layer.title @@ -960,7 +954,7 @@ def sld_definition(style): 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} e = dlxml.fromstring(wms_capabilities) for atype in e.findall( - "./[wms:Name='%s']/wms:Dimension[@name='time']" % (layer.alternate), namespaces): + f"./[wms:Name='{layer.alternate}']/wms:Dimension[@name='time']", namespaces): dim_name = atype.get('name') if dim_name: dim_name = str(dim_name).lower() @@ -992,7 +986,7 @@ def sld_definition(style): "remote": True, "url": service.service_url, "name": service.name, - "title": "[R] %s" % service.title} + "title": f"[R] {service.title}"} maplayer = MapLayer(map=map_obj, name=layer.alternate, ows_url=layer.ows_url, @@ -1007,7 +1001,7 @@ def sld_definition(style): access_token = request.session['access_token'] if request and 'access_token' in request.session else None if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url: - url = '%s?access_token=%s' % (layer.ows_url, access_token) + url = f'{layer.ows_url}?access_token={access_token}' else: url = layer.ows_url maplayer = MapLayer( @@ -1124,8 +1118,7 @@ def perm_filter(layer): request.session["map_status"] = map_status else: raise Exception( - 'Could not start the download of %s. Error was: %s' % - (map_obj.title, content)) + f'Could not start the download of {map_obj.title}. Error was: {content}') locked_layers = [] remote_layers = [] diff --git a/geonode/messaging/consumer.py b/geonode/messaging/consumer.py index b750b0f79d5..0a67bd1c7fe 100644 --- a/geonode/messaging/consumer.py +++ b/geonode/messaging/consumer.py @@ -84,12 +84,12 @@ def on_consume_end(self, connection, channel): logger.debug("finished.") def on_message(self, body, message): - logger.debug("broadcast: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"broadcast: RECEIVED MSG - body: {body!r}") message.ack() self._check_message_limit() def on_email_messages(self, body, message): - logger.debug("on_email_messages: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_email_messages: RECEIVED MSG - body: {body!r}") layer_uuid = body.get("layer_uuid") user_id = body.get("user_id") send_email_consumer(layer_uuid, user_id) @@ -99,7 +99,7 @@ def on_email_messages(self, body, message): self._check_message_limit() def on_geoserver_messages(self, body, message): - logger.debug("on_geoserver_messages: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_geoserver_messages: RECEIVED MSG - body: {body!r}") layer_id = body.get("id") try: layer = _wait_for_layer(layer_id) @@ -115,7 +115,7 @@ def on_geoserver_messages(self, body, message): self._check_message_limit() def on_notifications_messages(self, body, message): - logger.debug("on_notifications_message: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_notifications_message: RECEIVED MSG - body: {body!r}") body.get("id") body.get("app_label") body.get("model") @@ -126,30 +126,30 @@ def on_notifications_messages(self, body, message): self._check_message_limit() def on_geoserver_all(self, body, message): - logger.debug("on_geoserver_all: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_geoserver_all: RECEIVED MSG - body: {body!r}") message.ack() logger.debug("on_geoserver_all: finished") # TODO:Adding consurmer's producers. self._check_message_limit() def on_geoserver_catalog(self, body, message): - logger.debug("on_geoserver_catalog: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_geoserver_catalog: RECEIVED MSG - body: {body!r}") try: _update_layer_data(body, self.last_message) self.last_message = json.loads(body) except Exception: - logger.debug("Could not encode message {!r}".format(body)) + logger.debug(f"Could not encode message {body!r}") message.ack() logger.debug("on_geoserver_catalog: finished") self._check_message_limit() def on_geoserver_data(self, body, message): - logger.debug("on_geoserver_data: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_geoserver_data: RECEIVED MSG - body: {body!r}") try: _update_layer_data(body, self.last_message) self.last_message = json.loads(body) except Exception: - logger.debug("Could not encode message {!r}".format(body)) + logger.debug(f"Could not encode message {body!r}") message.ack() logger.debug("on_geoserver_data: finished") self._check_message_limit() @@ -159,12 +159,12 @@ def on_consume_ready(self, connection, channel, consumers, **kwargs): logger.debug(connection) logger.debug("{} consumers:".format(len(consumers))) for i, consumer in enumerate(consumers, start=1): - logger.debug("{0} {1}".format(i, consumer)) + logger.debug(f"{i} {consumer}") super(Consumer, self).on_consume_ready(connection, channel, consumers, **kwargs) def on_layer_viewer(self, body, message): - logger.debug("on_layer_viewer: RECEIVED MSG - body: %r" % (body,)) + logger.debug(f"on_layer_viewer: RECEIVED MSG - body: {body!r}") viewer = body.get("viewer") # owner_layer = body.get("owner_layer") layer_id = body.get("layer_id") @@ -217,15 +217,12 @@ def _wait_for_layer(layer_id, num_attempts=5, wait_seconds=1): for current in range(1, num_attempts + 1): try: instance = Layer.objects.get(id=layer_id) - logger.debug("Attempt {}/{} - Found layer in the " - "database".format(current, num_attempts)) + logger.debug(f"Attempt {current}/{num_attempts} - Found layer in the database") break except Layer.DoesNotExist: time.sleep(wait_seconds) - logger.debug("Attempt {}/{} - Could not find layer " - "instance".format(current, num_attempts)) + logger.debug(f"Attempt {current}/{num_attempts} - Could not find layer instance") else: - logger.debug("Reached maximum attempts and layer {!r} is still not " - "saved. Exiting...".format(layer_id)) + logger.debug(f"Reached maximum attempts and layer {layer_id!r} is still not saved. Exiting...") raise Layer.DoesNotExist return instance diff --git a/geonode/messaging/producer.py b/geonode/messaging/producer.py index 3014b2c2131..cc6ad654f9f 100644 --- a/geonode/messaging/producer.py +++ b/geonode/messaging/producer.py @@ -73,11 +73,11 @@ def sync_if_local_memory(func, *args, **kwargs): worker.run(timeout=broker_socket_timeout) except Exception: tb = traceback.format_exc() - msg = "Exception while publishing message: {}".format(tb) + msg = f"Exception while publishing message: {tb}" logger.error(msg) raise Exception(msg) elif not getattr(connection.connection, 'driver_name', None): - msg = "Exception while getting connection to {}".format(url) + msg = f"Exception while getting connection to {url}" logger.error(msg) raise Exception(msg) diff --git a/geonode/monitoring/__init__.py b/geonode/monitoring/__init__.py index 472d6d87bbf..f88e38bbd63 100644 --- a/geonode/monitoring/__init__.py +++ b/geonode/monitoring/__init__.py @@ -98,7 +98,7 @@ def register_event(request, event_type, resource): resource_name = getattr(resource, 'alternate', None) or resource.title resource_id = resource.id else: - raise ValueError("Invalid resource: {}".format(resource)) + raise ValueError(f"Invalid resource: {resource}") if request and hasattr(request, 'register_event'): request.register_event(event_type, resource_type, resource_name, resource_id) diff --git a/geonode/monitoring/aggregation.py b/geonode/monitoring/aggregation.py index d62e9084419..73dfe6d4560 100644 --- a/geonode/monitoring/aggregation.py +++ b/geonode/monitoring/aggregation.py @@ -37,7 +37,6 @@ def get_metric_names(): - """ Returns list of tuples: (service type, list of metrics) """ @@ -64,7 +63,7 @@ def get_metric_names(): def get_labels_for_metric(metric_name, resource=None): mt = ServiceTypeMetric.objects.filter(metric__name=metric_name) if not mt: - raise ValueError("No metric for {}".format(metric_name)) + raise ValueError(f"No metric for {metric_name}") qparams = {'metric_values__service_metric__in': mt} if resource: @@ -76,7 +75,7 @@ def get_labels_for_metric(metric_name, resource=None): def get_resources_for_metric(metric_name): mt = ServiceTypeMetric.objects.filter(metric__name=metric_name) if not mt: - raise ValueError("No metric for {}".format(metric_name)) + raise ValueError(f"No metric for {metric_name}") return list(MonitoredResource.objects.filter(metric_values__service_metric__in=mt) .exclude(name='', type='') .distinct() @@ -104,8 +103,8 @@ def extract_event_type(requests): def extract_event_types(requests): event_types = requests.exclude(event_type__isnull=True)\ - .distinct('event_type')\ - .values_list('event_type', flat=True) + .distinct('event_type')\ + .values_list('event_type', flat=True) return [EventType.objects.get(id=evt_id) for evt_id in event_types] @@ -163,7 +162,7 @@ def calculate_rate(metric_name, metric_label, def calculate_percent( - metric_name, metric_label, current_value, valid_to): + metric_name, metric_label, current_value, valid_to): """ Find previous network metric value and caclulate percent """ @@ -225,7 +224,7 @@ def aggregate_past_periods(metric_data_q=None, periods=None, cleanup=True, now=N # and extract service, resource, event type and label combinations # then, for each distinctive set, calculate per-metric aggregate values for period_start, period_end in periods: - log.debug('period %s - %s (%s s)', period_start, period_end, period_end-period_start) + log.debug('period %s - %s (%s s)', period_start, period_end, period_end - period_start) ret = aggregate_period(period_start, period_end, metric_data_q, cleanup) counter += ret previous_cutoff = until @@ -237,9 +236,9 @@ def aggregate_period(period_start, period_end, metric_data_q, cleanup=True): to_remove_data = {'remove_at': period_start.strftime("%Y%m%d%H%M%S")} source_metric_data = metric_data_q.filter(valid_from__gte=period_start, valid_to__lte=period_end)\ - .exclude(valid_from=period_start, - valid_to=period_end, - data={}) + .exclude(valid_from=period_start, + valid_to=period_end, + data={}) r = source_metric_data.values_list('service_id', 'service_metric_id', 'resource_id', 'event_type_id', 'label_id',)\ .distinct('service_id', 'service_metric_id', 'resource_id', 'event_type_id', 'label_id') source_metric_data.update(data=to_remove_data) @@ -290,11 +289,11 @@ def aggregate_period(period_start, period_end, metric_data_q, cleanup=True): valid_from=period_start, valid_to=period_end, label_id=label_id)\ - .update(value=value, - value_num=value, - value_raw=value, - data=None, - samples_count=samples_count) + .update(value=value, + value_num=value, + value_raw=value, + data=None, + samples_count=samples_count) counter += 1 if cleanup: diff --git a/geonode/monitoring/collector.py b/geonode/monitoring/collector.py index cf275fab174..9b6b40b6250 100644 --- a/geonode/monitoring/collector.py +++ b/geonode/monitoring/collector.py @@ -107,7 +107,7 @@ def get_network_rate(row, value, metric_defaults, 'value_raw': rate, 'value_num': rate, 'label': iface_label, - 'metric': '{}.rate'.format(metric_name)} + 'metric': f'{metric_name}.rate'} mdata.update(metric_defaults) log.debug(MetricValue.add(**mdata)) @@ -208,13 +208,13 @@ def process_host_geonode(self, service, data, valid_from, valid_to): 'value_raw': tx_value, 'value_num': tx_value, 'label': ifname, - 'metric': 'network.{}'.format(tx_label)} + 'metric': f'network.{tx_label}'} mdata.update(mdefaults) rate = self._calculate_rate( mdata['metric'], ifname, tx_value, valid_to) log.debug(MetricValue.add(**mdata)) if rate: - mdata['metric'] = '{}.rate'.format(mdata['metric']) + mdata['metric'] = f"{mdata['metric']}.rate" mdata['value'] = rate mdata['value_num'] = rate mdata['value_raw'] = rate @@ -233,7 +233,7 @@ def process_host_geonode(self, service, data, valid_from, valid_to): mdata = {'value': mdata, 'value_raw': mdata, 'value_num': mdata, - 'metric': 'mem.{}'.format(mkey), + 'metric': f'mem.{mkey}', 'label': 'B', } mdata.update(mdefaults) @@ -276,7 +276,7 @@ def process_host_geonode(self, service, data, valid_from, valid_to): mdata = {'value': l, 'value_raw': l, 'value_num': l, - 'metric': 'load.{}m'.format(llabel[lidx]), + 'metric': f'load.{llabel[lidx]}m', 'label': 'Value', } @@ -330,7 +330,7 @@ def process_host_geonode(self, service, data, valid_from, valid_to): mdata['valid_to']) if rate: rate_data = mdata.copy() - rate_data['metric'] = '{}.rate'.format(mdata['metric']) + rate_data['metric'] = f"{mdata['metric']}.rate" rate_data['value'] = rate rate_data['value_num'] = rate rate_data['value_raw'] = rate @@ -343,7 +343,7 @@ def process_host_geonode(self, service, data, valid_from, valid_to): mdata['valid_to']) if percent: percent_data = mdata.copy() - percent_data['metric'] = '{}.percent'.format(mdata['metric']) + percent_data['metric'] = f"{mdata['metric']}.percent" percent_data['value'] = percent percent_data['value_num'] = percent percent_data['value_raw'] = percent @@ -441,7 +441,7 @@ def _key(v): row['label'] = Metric.TYPE_VALUE_NUMERIC q.append(row) else: - raise ValueError("Unsupported metric type: {}".format(metric.type)) + raise ValueError(f"Unsupported metric type: {metric.type}") rows = q[:100] metric_values.update({'metric': metric_name, 'service': service}) for row in rows: @@ -661,7 +661,7 @@ def get_aggregate_function(self, column_name, metric_name, service=None): """ metric = Metric.get_for(metric_name, service=service) if not metric: - raise ValueError("Invalid metric {}".format(metric_name)) + raise ValueError(f"Invalid metric {metric_name}") f = metric.get_aggregate_name() return f or column_name @@ -877,11 +877,11 @@ def get_metrics_data(self, metric_name, group_by_cfg = group_by_map[group_by] g_sel = group_by_cfg.get('select') if g_sel: - q_select.append(', {}'.format(', '.join(g_sel))) + q_select.append(f", {', '.join(g_sel)}") g_sel = group_by_cfg.get('select_only') if g_sel: - q_select = ['select {}'.format(', '.join(g_sel))] + q_select = [f"select {', '.join(g_sel)}"] q_from.extend(group_by_cfg['from']) q_where.extend(group_by_cfg['where']) @@ -917,7 +917,7 @@ def get_metrics_data(self, metric_name, if q_group: q_group = [' group by ', ','.join(q_group)] if q_order_by: - q_order_by = 'order by {}'.format(','.join(q_order_by)) + q_order_by = f"order by {','.join(q_order_by)}" q = ' '.join(chain(q_select, q_from, q_where, q_group, [q_order_by])) @@ -968,8 +968,8 @@ def clear_old_data(self): utc = pytz.utc threshold = settings.MONITORING_DATA_TTL if not isinstance(threshold, timedelta): - raise TypeError("MONITORING_DATA_TTL should be an instance of " - "datatime.timedelta, not {}".format(threshold.__class__)) + raise TypeError( + f"MONITORING_DATA_TTL should be an instance of datatime.timedelta, not {threshold.__class__}") cutoff = datetime.utcnow().replace(tzinfo=utc) - threshold ExceptionEvent.objects.filter(created__lte=cutoff).delete() RequestEvent.objects.filter(created__lte=cutoff).delete() diff --git a/geonode/monitoring/management/commands/render_metrics.py b/geonode/monitoring/management/commands/render_metrics.py index 5f65f1d2874..db2de7ef3d3 100644 --- a/geonode/monitoring/management/commands/render_metrics.py +++ b/geonode/monitoring/management/commands/render_metrics.py @@ -100,26 +100,26 @@ def handle(self, *args, **options): @timeout_decorator.timeout(LOCAL_TIMEOUT) def list_labels(self, metric, resource=None): labels = self.collector.get_labels_for_metric(metric, resource=resource) - print('Labels for metric {}'.format(metric)) + print(f'Labels for metric {metric}') for label in labels: print(' ', *label) @timeout_decorator.timeout(LOCAL_TIMEOUT) def list_resources(self, metric): resources = self.collector.get_resources_for_metric(metric) - print('Resources for metric {}'.format(metric)) + print(f'Resources for metric {metric}') for res in resources: print(' ', '='.join(res)) @timeout_decorator.timeout(LOCAL_TIMEOUT) def show_metrics(self, metric, since, until, interval, resource=None, label=None, service=None): - print('Monitoring Metric values for {}'.format(metric)) + print(f'Monitoring Metric values for {metric}') if service: - print(' for service: {} '.format(service)) + print(f' for service: {service} ') if resource: - print(' for resource: {}={} '.format(resource.type, resource.name)) + print(f' for resource: {resource.type}={resource.name} ') if label: - print(' for label: {} label'.format(label.name)) + print(f' for label: {label.name} label') utc = pytz.utc since = since.replace(tzinfo=utc) if since else None @@ -148,4 +148,4 @@ def list_metrics(self): for stype, metrics in _metrics: print('service type', stype.name) for m in metrics: - print(' {}[{}]'.format(m.name, m.type)) + print(f' {m.name}[{m.type}]') diff --git a/geonode/monitoring/management/commands/updategeoip.py b/geonode/monitoring/management/commands/updategeoip.py index c0cc5dc742f..f2026b4df6c 100644 --- a/geonode/monitoring/management/commands/updategeoip.py +++ b/geonode/monitoring/management/commands/updategeoip.py @@ -41,7 +41,7 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('-f', '--file', dest='file', default=settings.GEOIP_PATH, - help=_("Write result to file, default GEOIP_PATH: {}".format(settings.GEOIP_PATH))) + help=_(f"Write result to file, default GEOIP_PATH: {settings.GEOIP_PATH}")) parser.add_argument('-u', '--url', dest='url', default=URL, help=_("Fetch database from specific url. If nothing provided, default {} will be used")) parser.add_argument('-o', '--overwrite', dest='overwrite', action='store_true', default=False, @@ -119,6 +119,6 @@ def handle_old_format(self, f, fname): try: os.remove(fname) except OSError: - logger.debug('Could not delete file %s' % fname) + logger.debug(f'Could not delete file {fname}') except Exception as err: logger.error("Cannot process %s: %s", f, err, exc_info=err) diff --git a/geonode/monitoring/middleware.py b/geonode/monitoring/middleware.py index 5f24f61276d..f1661ee28f5 100644 --- a/geonode/monitoring/middleware.py +++ b/geonode/monitoring/middleware.py @@ -48,7 +48,7 @@ def __init__(self, get_response): self.setup_logging() def setup_logging(self): - self.log = logging.getLogger('{}.catcher'.format(__name__)) + self.log = logging.getLogger(f'{__name__}.catcher') self.log.propagate = False self.log.setLevel(logging.DEBUG) self.log.handlers = [] diff --git a/geonode/monitoring/models.py b/geonode/monitoring/models.py index 144190e3e05..d417993716e 100644 --- a/geonode/monitoring/models.py +++ b/geonode/monitoring/models.py @@ -84,7 +84,7 @@ class Host(models.Model): active = models.BooleanField(null=False, blank=False, default=True) def __str__(self): - return 'Host: {} ({})'.format(self.name, self.ip) + return f'Host: {self.name} ({self.ip})' class ServiceType(models.Model): @@ -110,7 +110,7 @@ class ServiceType(models.Model): choices=TYPES) def __str__(self): - return 'Service Type: {}'.format(self.name) + return f'Service Type: {self.name}' @property def is_system_monitor(self): @@ -137,7 +137,7 @@ class Service(models.Model): url = models.URLField(null=True, blank=True, default='') def __str__(self): - return 'Service: {}@{}'.format(self.name, self.host.name) + return f'Service: {self.name}@{self.host.name}' def get_metrics(self): return [m.metric for m in self.service_type.metric.all()] @@ -192,7 +192,7 @@ class Meta: unique_together = (('name', 'type',),) def __str__(self): - return 'Monitored Resource: {} {}'.format(self.name, self.type) + return f'Monitored Resource: {self.name} {self.type}' @classmethod def get(cls, resource_type, resource_name, or_create=False): @@ -283,7 +283,7 @@ def get_aggregate_name(self): return self.AGGREGATE_MAP[self.type] def __unicode__(self): - return "Metric: {}".format(self.name) + return f"Metric: {self.name}" @property def is_rate(self): @@ -321,7 +321,7 @@ class ServiceTypeMetric(models.Model): metric = models.ForeignKey(Metric, related_name='service_type', on_delete=models.CASCADE) def __str__(self): - return '{} - {}'.format(self.service_type, self.metric) + return f'{self.service_type} - {self.metric}' class EventType(models.Model): @@ -347,7 +347,7 @@ class EventType(models.Model): EVENT_OTHER = 'other' # non-ows event EVENT_ALL = 'all' # all events - baseline: ows + non-ows - EVENT_TYPES = list(zip(['OWS:{}'.format(ows) for ows in _ows_types], _ows_types)) + \ + EVENT_TYPES = list(zip([f'OWS:{ows}' for ows in _ows_types], _ows_types)) + \ [(EVENT_OTHER, _("Not OWS"))] +\ [(EVENT_OWS, _("Any OWS"))] +\ [(EVENT_ALL, _("All"))] +\ @@ -368,7 +368,7 @@ class EventType(models.Model): blank=False) def __str__(self): - return 'Event Type: {}'.format(self.name) + return f'Event Type: {self.name}' @classmethod def get(cls, service_name=None): @@ -767,7 +767,7 @@ def from_geoserver(cls, service, request_data, received=None): rl = rd['responseLength'] event_type_name = rd.get('service') if event_type_name: - event_type = EventType.get('OWS:{}'.format(event_type_name.upper())) + event_type = EventType.get(f'OWS:{event_type_name.upper()}') else: event_type = EventType.get(EventType.EVENT_GEOSERVER) @@ -777,7 +777,7 @@ def from_geoserver(cls, service, request_data, received=None): 'event_type': event_type, 'service': service, 'request_path': - '{}?{}'.format(rd['path'], rd['queryString']) if rd.get( + f"{rd['path']}?{rd['queryString']}" if rd.get( 'queryString') else rd['path'], 'request_method': rd['httpMethod'], 'response_status': rd['responseStatus'], @@ -830,7 +830,7 @@ def add_error(cls, from_service, error_type, stack_trace, received = datetime.utcnow().replace(tzinfo=pytz.utc) if not isinstance(error_type, string_types): _cls = error_type.__class__ - error_type = '{}.{}'.format(_cls.__module__, _cls.__name__) + error_type = f'{_cls.__module__}.{_cls.__name__}' if not message: message = str(error_type) if isinstance(stack_trace, (list, tuple)): @@ -897,7 +897,7 @@ class MetricLabel(models.Model): blank=True) def __unicode__(self): - return 'Metric Label: {}'.format(self.name.encode('ascii', 'ignore')) + return f"Metric Label: {self.name.encode('ascii', 'ignore')}" class MetricValue(models.Model): @@ -945,13 +945,10 @@ def __str__(self): metric = self.service_metric.metric.name if self.label: _l = self.label.name - metric = '{} [{}]'.format(metric, _l) + metric = f'{metric} [{_l}]' if self.resource and self.resource.type: - metric = '{} for {}'.format( - metric, '{}={}'.format( - self.resource.type, self.resource.name)) - return 'Metric Value: {}: [{}] (since {} until {})'.format( - metric, self.value, self.valid_from, self.valid_to) + metric = f'{metric} for {self.resource.type}={self.resource.name}' + return f'Metric Value: {metric}: [{self.value}] (since {self.valid_from} until {self.valid_to})' @classmethod def add(cls, metric, valid_from, valid_to, service, label, @@ -1120,7 +1117,7 @@ class NotificationCheck(models.Model): help_text=_("Is it active")) def __str__(self): - return "Notification Check #{}: {}".format(self.id, self.name) + return f"Notification Check #{self.id}: {self.name}" @property def notification_subject(self): @@ -1456,9 +1453,7 @@ def current_value(self): val_ = val return { 'class': - '{}.{}'.format( - val.__class__.__module__, - val.__class__.__name__), + f'{val.__class__.__module__}.{val.__class__.__name__}', 'value': val_} except MetricNotificationCheck.DoesNotExist: return @@ -1487,7 +1482,7 @@ def get_fields(self): @property def field_name(self): - return '{}.{}'.format(self.metric.name, self.field_option) + return f'{self.metric.name}.{self.field_option}' def populate_min_max(self): notification = self.notification_check @@ -1503,7 +1498,7 @@ def populate_min_max(self): .filter( notification_check=self.notification_check, metric=self.metric, - **{'{}__isnull'.format(self.field_option): False})\ + **{f'{self.field_option}__isnull': False})\ .get() if mcheck: self.metric_check = mcheck @@ -1553,16 +1548,14 @@ class MetricNotificationCheck(models.Model): def __str__(self): indicator = [] if self.min_value is not None: - indicator.append("value above {}".format(self.min_value)) + indicator.append(f"value above {self.min_value}") if self.max_value is not None: - indicator.append("value below {}".format(self.max_value)) + indicator.append(f"value below {self.max_value}") if self.max_timeout is not None: indicator.append( - "value must be collected within {}".format( - self.max_timeout)) + f"value must be collected within {self.max_timeout}") indicator = ' and '.join(indicator) - return "MetricCheck({}@{}: {})".format( - self.metric.name, self.service.name if self.service else '', indicator) + return f"MetricCheck({self.metric.name}@{self.service.name if self.service else ''}: {indicator})" @property def field_option(self): @@ -1597,10 +1590,7 @@ def __init__(self, metric, check, message, self.valid_to = metric.valid_to if hasattr(metric, 'valid_to') else None def __str__(self): - return "MetricValueError({}: metric {} misses {} check: {})".format(self.severity, - self.metric, - self.check, - self.message) + return f"MetricValueError({self.severity}: metric {self.metric} misses {self.check} check: {self.message})" def check_value(self, metric, valid_on): """ @@ -1609,7 +1599,7 @@ def check_value(self, metric, valid_on): v = metric.value_num m = metric.service_metric.metric metric_name = m.description or m.name - unit_name = ' {}'.format(m.unit) if not m.is_count else '' + unit_name = f' {m.unit}' if not m.is_count else '' had_check = False if self.definition: @@ -1618,16 +1608,14 @@ def check_value(self, metric, valid_on): if self.event_type: os = self.event_type if os.is_all or os.is_other: - msg_prefix.append("for {} OWS".format(os.name)) + msg_prefix.append(f"for {os.name} OWS") else: - msg_prefix.append("for {} OWS".format(os.name)) + msg_prefix.append(f"for {os.name} OWS") if self.service: - msg_prefix.append("for {} service".format(self.service.name)) + msg_prefix.append(f"for {self.service.name} service") if self.resource: msg_prefix.append( - "for {}[{}] resource".format( - self.resource.name, - self.resource.type)) + f"for {self.resource.name}[{self.resource.type}] resource") msg_prefix = ' '.join(msg_prefix) description_tmpl = ("{} {} should be {{}} " @@ -1668,9 +1656,8 @@ def check_value(self, metric, valid_on): actual_seconds = (valid_on - metric.valid_to).total_seconds() msg = "{} {} seconds".format(def_msg, int(total_seconds)) description = description_tmpl.format('recored at most ', - '{} seconds ago'.format( - total_seconds), - '{} seconds'.format(actual_seconds)) + f'{total_seconds} seconds ago', + f'{actual_seconds} seconds') raise self.MetricValueError(metric, self, msg, @@ -1684,7 +1671,7 @@ def check_value(self, metric, valid_on): "", None, None, - "Metric check {} is not checking anything".format(self)) + f"Metric check {self} is not checking anything") def check_metric(self, for_timestamp=None): """ @@ -1711,7 +1698,7 @@ def check_metric(self, for_timestamp=None): "", None, None, - "Cannot find metric values for {} on {}".format(self.metric, for_timestamp)) + f"Cannot find metric values for {self.metric} on {for_timestamp}") for m in metrics: self.check_value(m, for_timestamp) return True @@ -1849,14 +1836,13 @@ def do_autoconfigure(): _host_by_name = '127.0.0.1' hosts = [(wsite.hostname, _host_by_name,)] # default geonode - geonode_name = settings.MONITORING_SERVICE_NAME or '{}-geonode'.format( - wsite.hostname) + geonode_name = settings.MONITORING_SERVICE_NAME or f'{wsite.hostname}-geonode' geonodes = [(geonode_name, settings.SITEURL, hosts[0])] geoservers = [] for k, val in settings.OGC_SERVER.items(): if val.get('BACKEND') == 'geonode.geoserver': - gname = '{}-geoserver'.format(k) + gname = f'{k}-geoserver' gsite = urlparse(val['LOCATION']) try: _host_by_name = gethostbyname(gsite.hostname) @@ -1900,7 +1886,7 @@ def do_autoconfigure(): service_type=geonode_type) service.save() - shost_name = '{}-hostgeonode'.format(host.name) + shost_name = f'{host.name}-hostgeonode' try: service = Service.objects.get(name=shost_name) except Service.DoesNotExist: @@ -1928,7 +1914,7 @@ def do_autoconfigure(): service_type=geoserver_type) service.save() - shost_name = '{}-hostgeoserver'.format(host.name) + shost_name = f'{host.name}-hostgeoserver' try: service = Service.objects.get(name=shost_name) except Service.DoesNotExist: diff --git a/geonode/monitoring/service_handlers.py b/geonode/monitoring/service_handlers.py index 099e7e33bd1..2e3c83cd7c5 100644 --- a/geonode/monitoring/service_handlers.py +++ b/geonode/monitoring/service_handlers.py @@ -171,7 +171,7 @@ def __init__(self, service, force_check=False): def setup(self): if not self.service.url: - raise ValueError("Monitoring is not configured to fetch from %s" % self.service.name) + raise ValueError(f"Monitoring is not configured to fetch from {self.service.name}") self.gs_monitor = GeoServerMonitorClient(self.service.url) def _collect(self, since, until, format=None, **kwargs): @@ -197,11 +197,11 @@ def __init__(self, service, force_check=False): def _collect(self, *args, **kwargs): base_url = self.service.url if not base_url: - raise ValueError("Service {} should have url provided".format(self.service.name)) - url = '{}{}'.format(base_url.rstrip('/'), self.PATH) + raise ValueError(f"Service {self.service.name} should have url provided") + url = f"{base_url.rstrip('/')}{self.PATH}" rdata = requests.get(url, timeout=10, verify=False) if rdata.status_code != 200: - raise ValueError("Error response from api: ({}) {}".format(url, rdata)) + raise ValueError(f"Error response from api: ({url}) {rdata}") data = rdata.json()['metrics']['metric'] return data @@ -217,11 +217,11 @@ def __init__(self, service, force_check=False): def _collect(self, since, until, *args, **kwargs): base_url = self.service.url if not base_url: - raise ValueError("Service {} should have url provided".format(self.service.name)) - url = '{}/monitoring/api/beacon/{}/'.format(base_url.rstrip('/'), self.service.service_type.name) + raise ValueError(f"Service {self.service.name} should have url provided") + url = f"{base_url.rstrip('/')}/monitoring/api/beacon/{self.service.service_type.name}/" rdata = requests.get(url, timeout=10, verify=False) if rdata.status_code != 200: - raise ValueError("Error response from api: ({}) {}".format(url, rdata)) + raise ValueError(f"Error response from api: ({url}) {rdata}") data = rdata.json() return data diff --git a/geonode/monitoring/tests/integration.py b/geonode/monitoring/tests/integration.py index 08277d29958..f66e65d426a 100644 --- a/geonode/monitoring/tests/integration.py +++ b/geonode/monitoring/tests/integration.py @@ -78,13 +78,7 @@ DB_NAME = settings.DATABASES['default']['NAME'] DB_USER = settings.DATABASES['default']['USER'] DB_PASSWORD = settings.DATABASES['default']['PASSWORD'] -DATASTORE_URL = 'postgis://{}:{}@{}:{}/{}'.format( - DB_USER, - DB_PASSWORD, - DB_HOST, - DB_PORT, - DB_NAME -) +DATASTORE_URL = f'postgis://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}' postgis_db = dj_database_url.parse(DATASTORE_URL, conn_max_age=0) logging.getLogger('south').setLevel(logging.WARNING) @@ -123,7 +117,7 @@ def _base_environ(self, **request): # See https://www.python.org/dev/peps/pep-3333/#environ-variables environ = { 'HTTP_COOKIE': '; '.join(sorted( - '%s=%s' % (morsel.key, morsel.coded_value) + f'{morsel.key}={morsel.coded_value}' for morsel in self.cookies.values() )), 'PATH_INFO': str('/'), @@ -161,7 +155,7 @@ def login_user(self, user): """ if 'django.contrib.sessions' not in settings.INSTALLED_APPS: raise AssertionError("Unable to login without django.contrib.sessions in INSTALLED_APPS") - user.backend = "%s.%s" % ("django.contrib.auth.backends", "ModelBackend") + user.backend = f"{'django.contrib.auth.backends'}.{'ModelBackend'}" # Login self.force_login(user, backend=user.backend) @@ -194,7 +188,7 @@ def setUp(self): pass self.catalog = Catalog( - GEOSERVER_URL + 'rest', + f"{GEOSERVER_URL}rest", GEOSERVER_USER, GEOSERVER_PASSWD, retries=ogc_server_settings.MAX_RETRIES, @@ -1923,10 +1917,7 @@ def test_ows_service_enpoints(self): {'name': 'OWS:ALL', 'type_label': 'Any OWS'} ] # url - url = "%s?%s" % ( - reverse('monitoring:api_event_types'), - 'ows_service=true' - ) + url = f"{reverse('monitoring:api_event_types')}?{'ows_service=true'}" # Unauthorized response = self.client.get(url) out = json.loads(ensure_string(response.content)) @@ -1964,10 +1955,7 @@ def test_non_ows_events_enpoints(self): {'name': 'geoserver', 'type_label': 'Geoserver event'} ] # url - url = "%s?%s" % ( - reverse('monitoring:api_event_types'), - 'ows_service=false' - ) + url = f"{reverse('monitoring:api_event_types')}?{'ows_service=false'}" # Unauthorized response = self.client.get(url) out = json.loads(ensure_string(response.content)) @@ -2181,11 +2169,7 @@ def test_unique_visitors_count_endpoints(self): } ] # url - url = "%s?%s&%s" % ( - reverse('monitoring:api_metric_data', args={'request.users'}), - 'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=2628000', - 'group_by=user' - ) + url = f"{reverse('monitoring:api_metric_data', args={'request.users'})}?{'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=2628000'}&{'group_by=user'}" # Unauthorized response = self.client.get(url) out = json.loads(ensure_string(response.content)) @@ -2214,12 +2198,12 @@ def test_unique_visitors_count_endpoints(self): month_data = d["data"] is_empty = [ md for md in month_data if not ( - md["max"] - or md["metric_count"] - or md["min"] - or md["samples_count"] - or md["sum"] - or md["val"] + md["max"] + or md["metric_count"] + or md["min"] + or md["samples_count"] + or md["sum"] + or md["val"] ) ] if is_empty: @@ -2275,12 +2259,12 @@ def test_anonymous_sessions_count_endpoints(self): month_data = d["data"] is_empty = [ md for md in month_data if not ( - md["max"] - or md["metric_count"] - or md["min"] - or md["samples_count"] - or md["sum"] - or md["val"] + md["max"] + or md["metric_count"] + or md["min"] + or md["samples_count"] + or md["sum"] + or md["val"] ) ] if is_empty: @@ -2340,11 +2324,7 @@ def test_unique_visitors_list_endpoints(self): } ] # url - url = "%s?%s&%s" % ( - reverse('monitoring:api_metric_data', args={'request.users'}), - 'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=2628000', - 'group_by=user_on_label' - ) + url = f"{reverse('monitoring:api_metric_data', args={'request.users'})}?{'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=2628000'}&{'group_by=user_on_label'}" # Unauthorized response = self.client.get(url) out = json.loads(ensure_string(response.content)) @@ -2667,11 +2647,7 @@ def test_hits_for_event_type_endpoint(self): 'val': '0.0000'} ] # url - url = "%s?%s&%s" % ( - reverse('monitoring:api_metric_data', args={'request.count'}), - 'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=31536000', - 'group_by=event_type' - ) + url = f"{reverse('monitoring:api_metric_data', args={'request.count'})}?{'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=31536000'}&{'group_by=event_type'}" response = self.client.get(url) out = json.loads(ensure_string(response.content)) self.assertEqual(out["error"], "unauthorized_request") @@ -2700,10 +2676,8 @@ def test_hits_for_event_type_endpoint(self): def test_countries_endpoint(self): # url - url = "%s?%s" % ( - reverse('monitoring:api_metric_data', args={'request.country'}), - 'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=31536000' - ) + url = (f"{reverse('monitoring:api_metric_data', args={'request.country'})}?" + f"{'valid_from=2018-09-11T20:00:00.000Z&valid_to=2019-09-11T20:00:00.000Z&interval=31536000'}") response = self.client.get(url) out = json.loads(ensure_string(response.content)) self.assertEqual(out["error"], "unauthorized_request") diff --git a/geonode/monitoring/utils.py b/geonode/monitoring/utils.py index 41bf9b37204..e8e7c8da1a0 100644 --- a/geonode/monitoring/utils.py +++ b/geonode/monitoring/utils.py @@ -110,7 +110,7 @@ def get_href(self, link, format=None): return href.geturl() if format in self.REPORT_FORMATS: href, ext = os.path.splitext(href.geturl()) - return '{}.{}'.format(href, format) + return f'{href}.{format}' return format def get_requests(self, format=None, since=None, until=None): @@ -119,7 +119,7 @@ def get_requests(self, format=None, since=None, until=None): """ from requests.auth import HTTPBasicAuth - rest_url = '{}rest/monitor/requests.html'.format(self.base_url) + rest_url = f'{self.base_url}rest/monitor/requests.html' qargs = {} if since: # since = since.astimezone(utc) @@ -146,14 +146,14 @@ def get_requests(self, format=None, since=None, until=None): if data: yield data else: - log.warning("Skipping payload for {}".format(href)) + log.warning(f"Skipping payload for {href}") def get_request(self, href, format=format): from requests.auth import HTTPBasicAuth username = settings.OGC_SERVER['default']['USER'] password = settings.OGC_SERVER['default']['PASSWORD'] - log.debug(" href: %s " % href) + log.debug(f" href: {href} ") r = requests.get( href, auth=HTTPBasicAuth(username, password), @@ -187,10 +187,10 @@ def _from_html(self, val): raise ValueError("Cannot convert from html") def to_json(self, data, from_format): - h = getattr(self, '_from_{}'.format(from_format), None) + h = getattr(self, f'_from_{from_format}', None) if not h or not len(data): raise ValueError( - "Cannot convert from {} - no handler".format(from_format)) + f"Cannot convert from {from_format} - no handler") return h(data) @@ -259,7 +259,7 @@ class TypeChecks(object): @classmethod def audit_format(cls, val): if val not in cls.AUDIT_FORMATS: - raise ValueError("Invalid value for audit format: {}".format(val)) + raise ValueError(f"Invalid value for audit format: {val}") return val @staticmethod @@ -268,7 +268,7 @@ def host_type(val): try: return Host.objects.get(name=val) except Host.DoesNotExist: - raise ValueError("Host {} does not exist".format(val)) + raise ValueError(f"Host {val} does not exist") @staticmethod def resource_type(val): @@ -281,7 +281,7 @@ def resource_type(val): rtype, rname = val.split('=') except (ValueError, IndexError,): raise ValueError( - "{} is not valid resource description".format(val)) + f"{val} is not valid resource description") return MonitoredResource.objects.get(type=rtype, name=rname) @staticmethod @@ -289,7 +289,7 @@ def resource_type_type(val): from geonode.monitoring.models import MonitoredResource if val in MonitoredResource._TYPES: return val - raise ValueError("Invalid monitored resource type: {}".format(val)) + raise ValueError(f"Invalid monitored resource type: {val}") @staticmethod def metric_name_type(val): @@ -297,7 +297,7 @@ def metric_name_type(val): try: return Metric.objects.get(name=val) except Metric.DoesNotExist: - raise ValueError("Metric {} doesn't exist".format(val)) + raise ValueError(f"Metric {val} doesn't exist") @staticmethod def service_type(val): @@ -305,7 +305,7 @@ def service_type(val): try: return Service.objects.get(name=val) except Service.DoesNotExist: - raise ValueError("Service {} does not exist".format(val)) + raise ValueError(f"Service {val} does not exist") @staticmethod def service_type_type(val): @@ -313,7 +313,7 @@ def service_type_type(val): try: return ServiceType.objects.get(name=val) except ServiceType.DoesNotExist: - raise ValueError("Service Type {} does not exist".format(val)) + raise ValueError(f"Service Type {val} does not exist") @staticmethod def label_type(val): @@ -325,7 +325,7 @@ def label_type(val): return MetricLabel.objects.get(name=val) except MetricLabel.DoesNotExist: pass - raise ValueError("Invalid label value: {}".format(val)) + raise ValueError(f"Invalid label value: {val}") @staticmethod def user_type(val): @@ -334,7 +334,7 @@ def user_type(val): if MetricLabel.objects.filter(user=val).count(): return val except MetricLabel.DoesNotExist: - raise ValueError("Invalid user value: {}".format(val)) + raise ValueError(f"Invalid user value: {val}") @staticmethod def event_type_type(val): @@ -342,7 +342,7 @@ def event_type_type(val): try: return EventType.objects.get(name=val) except EventType.DoesNotExist: - raise ValueError("Event Type {} doesn't exist".format(val)) + raise ValueError(f"Event Type {val} doesn't exist") @staticmethod def ows_service_type(val): @@ -351,7 +351,7 @@ def ows_service_type(val): elif str(val).lower() in ("false", "0"): return False else: - raise ValueError("Invalid ows_service value {}".format(val)) + raise ValueError(f"Invalid ows_service value {val}") def dump(obj, additional_fields=tuple()): @@ -366,7 +366,7 @@ def dump(obj, additional_fields=tuple()): if isinstance(field, RelatedField): if val is not None: v = val - val = {'class': '{}.{}'.format(val.__class__.__module__, val.__class__.__name__), + val = {'class': f'{val.__class__.__module__}.{val.__class__.__name__}', 'id': val.pk} if hasattr(v, 'name'): val['name'] = v.name @@ -412,14 +412,10 @@ def collect_metric(**options): hexdigest = md5(name).hexdigest() lock_id = f'{name.decode()}-lock-{hexdigest}' _start_time = _end_time = datetime.utcnow().isoformat() - log.info('[{}] Collecting Metrics - started @ {}'.format( - lock_id, - _start_time)) + log.info(f'[{lock_id}] Collecting Metrics - started @ {_start_time}') with AcquireLock(lock_id) as lock: if lock.acquire() is True: - log.info('[{}] Collecting Metrics - [...acquired lock] @ {}'.format( - lock_id, - _start_time)) + log.info(f'[{lock_id}] Collecting Metrics - [...acquired lock] @ {_start_time}') try: oservice = options['service'] if not oservice: @@ -462,17 +458,11 @@ def collect_metric(**options): # notifications_check = now - interval c.emit_notifications() # notifications_check)) _end_time = datetime.utcnow().isoformat() - log.info('[{}] Collecting Metrics - finished @ {}'.format( - lock_id, - _end_time)) + log.info(f'[{lock_id}] Collecting Metrics - finished @ {_end_time}') except Exception as e: - log.info('[{}] Collecting Metrics - errored @ {}'.format( - lock_id, - _end_time)) + log.info(f'[{lock_id}] Collecting Metrics - errored @ {_end_time}') log.exception(e) - log.info('[{}] Collecting Metrics - exit @ {}'.format( - lock_id, - _end_time)) + log.info(f'[{lock_id}] Collecting Metrics - exit @ {_end_time}') return (_start_time, _end_time) diff --git a/geonode/monitoring/views.py b/geonode/monitoring/views.py index e2a3e3947fa..444a79d6fa8 100644 --- a/geonode/monitoring/views.py +++ b/geonode/monitoring/views.py @@ -145,9 +145,9 @@ def _check_type(self, tname): val = d[tname] if not val: return - tcheck = getattr(TypeChecks, '{}_type'.format(tname), None) + tcheck = getattr(TypeChecks, f'{tname}_type', None) if not tcheck: - raise forms.ValidationError("No type check for {}".format(tname)) + raise forms.ValidationError(f"No type check for {tname}") try: return tcheck(val) except (Exception,) as err: @@ -522,7 +522,7 @@ def get(self, request, *args, **kwargs): ex = exposes[service]() except KeyError: return json_response( - errors={'exposed': 'No service for {}'.format(service)}, status=404) + errors={'exposed': f'No service for {service}'}, status=404) out = {'data': ex.expose(), 'timestamp': datetime.utcnow().replace(tzinfo=pytz.utc)} return json_response(out) @@ -565,7 +565,7 @@ def _get_clean_model(self, cls, name): try: return cls.objects.get(name=val) except cls.DoesNotExist: - raise forms.ValidationError("Invalid {}: {}".format(name, val)) + raise forms.ValidationError(f"Invalid {name}: {val}") def clean_metric(self): return self._get_clean_model(Metric, 'metric') @@ -587,11 +587,11 @@ def clean_resource(self): vtype, vname = val.split('=') except IndexError: raise forms.ValidationError( - "Invalid resource name: {}".format(val)) + f"Invalid resource name: {val}") try: return MonitoredResource.objects.get(name=vname, type=vtype) except MonitoredResource.DoesNotExist: - raise forms.ValidationError("Invalid resource: {}".format(val)) + raise forms.ValidationError(f"Invalid resource: {val}") class UserNotificationConfigView(View): diff --git a/geonode/notifications_helper.py b/geonode/notifications_helper.py index f64f6f931c3..32504f0e186 100644 --- a/geonode/notifications_helper.py +++ b/geonode/notifications_helper.py @@ -126,10 +126,10 @@ def get_notification_recipients(notice_type_label, exclude_user=None, resource=N for user in profiles: try: if not user.is_superuser and \ - not user.has_perm('view_resourcebase', resource.get_self_resource()): + not user.has_perm('view_resourcebase', resource.get_self_resource()): exclude_users_ids.append(user.id) - if user.pk == resource.owner.pk and \ - not notice_type_label.split("_")[-1] in ("updated", "rated", "comment", "approved", "published"): + if user.pk == resource.owner.pk and not notice_type_label.split( + "_")[-1] in ("updated", "rated", "comment", "approved", "published"): exclude_users_ids.append(user.id) except Exception: # fallback which wont send mails diff --git a/geonode/people/adapters.py b/geonode/people/adapters.py index 676b2a65aa5..4bb8cf0428b 100644 --- a/geonode/people/adapters.py +++ b/geonode/people/adapters.py @@ -88,7 +88,7 @@ def update_profile(sociallogin): for field in profile_fields: try: extractor_method = getattr( - extractor, "extract_{}".format(field)) + extractor, f"extract_{field}") value = extractor_method(sociallogin.account.extra_data) if not user_field(user, field): user_field(user, field, value) diff --git a/geonode/people/management/commands/setupsociallogins.py b/geonode/people/management/commands/setupsociallogins.py index 20de80bf057..3cc22e52b87 100644 --- a/geonode/people/management/commands/setupsociallogins.py +++ b/geonode/people/management/commands/setupsociallogins.py @@ -19,19 +19,19 @@ class Command(BaseCommand): @staticmethod def _get_client_id_arg(provider): - return "{}-client-id".format(provider) + return f"{provider}-client-id" @staticmethod def _get_client_secret_arg(provider): - return "{}-secret-key".format(provider) + return f"{provider}-secret-key" @staticmethod def _get_client_id_env(provider): - return "{}_OAUTH2_CLIENT_ID".format(provider.upper()) + return f"{provider.upper()}_OAUTH2_CLIENT_ID" @staticmethod def _get_client_secret_env(provider): - return "{}_OAUTH2_SECRET_KEY".format(provider.upper()) + return f"{provider.upper()}_OAUTH2_SECRET_KEY" @staticmethod def get_social_providers(): @@ -48,24 +48,16 @@ def add_arguments(self, parser): for provider_name, provider_id in self.get_social_providers(): client_id_arg = self._get_client_id_arg(provider_name) parser.add_argument( - "--{}".format(client_id_arg), + f"--{client_id_arg}", help=( - "Specify the client id for {}. You may also specify " - "the {} environment variable instead".format( - provider_name, - self._get_client_id_env(provider_name) - ) + f"Specify the client id for {provider_name}. You may also specify the {self._get_client_id_env(provider_name)} environment variable instead" ) ) client_secret_arg = self._get_client_secret_arg(provider_name) parser.add_argument( - "--{}".format(client_secret_arg), + f"--{client_secret_arg}", help=( - "Specify the secret key for {}. You may also specify " - "the {} environment variable instead".format( - provider_name, - self._get_client_secret_env(provider_name) - ) + f"Specify the secret key for {provider_name}. You may also specify the {self._get_client_secret_env(provider_name)} environment variable instead" ) ) @@ -87,13 +79,12 @@ def handle(self, *args, **options): ) if all((client_id, client_secret)): self.stdout.write( - "Configuring provider {}...".format(provider_name)) + f"Configuring provider {provider_name}...") self._handle_provider( provider_name, provider_id, client_id, client_secret) else: self.stdout.write( - "Provider {} not all params were specified, " - "skipping...".format(provider_name) + f"Provider {provider_name} not all params were specified, skipping..." ) else: self.stdout.write( @@ -116,4 +107,4 @@ def _handle_provider(self, name, id_, client_id, secret_key): provider.save() else: self.stdout.write( - "Provider {} already exists, skipping...".format(name)) + f"Provider {name} already exists, skipping...") diff --git a/geonode/people/models.py b/geonode/people/models.py index 6da32596f8d..6ab0ec5f9ad 100644 --- a/geonode/people/models.py +++ b/geonode/people/models.py @@ -139,7 +139,7 @@ def get_absolute_url(self): return reverse('profile_detail', args=[self.username, ]) def __str__(self): - return "{0}".format(self.username) + return f"{self.username}" @staticmethod def class_name(value): @@ -170,20 +170,18 @@ def keyword_list(self): @property def name_long(self): if self.first_name and self.last_name: - return '%s %s (%s)' % (self.first_name, - self.last_name, self.username) + return f'{self.first_name} {self.last_name} ({self.username})' elif (not self.first_name) and self.last_name: - return '%s (%s)' % (self.last_name, self.username) + return f'{self.last_name} ({self.username})' elif self.first_name and (not self.last_name): - return '%s (%s)' % (self.first_name, self.username) + return f'{self.first_name} ({self.username})' else: return self.username @property def full_name_or_nick(self): if self.first_name and self.last_name: - return '%s %s' % (self.first_name, - self.last_name) + return f'{self.first_name} {self.last_name}' else: return self.username diff --git a/geonode/people/signals.py b/geonode/people/signals.py index 325d9f4c83e..4c90401bb91 100644 --- a/geonode/people/signals.py +++ b/geonode/people/signals.py @@ -108,7 +108,7 @@ def update_user_email_addresses(sender, **kwargs): EmailAddress.objects.add_email( request=None, user=user, email=sociallogin_email, confirm=False) except IntegrityError: - logging.exception(msg="Could not add email address {} to user {}".format(sociallogin_email, user)) + logging.exception(msg=f"Could not add email address {sociallogin_email} to user {user}") def notify_admins_new_signup(sender, **kwargs): diff --git a/geonode/people/tests.py b/geonode/people/tests.py index 3980a39671c..076a6f9e0c1 100644 --- a/geonode/people/tests.py +++ b/geonode/people/tests.py @@ -136,8 +136,7 @@ def test_forgot_username(self): # Verify that the subject of the first message is correct. self.assertEqual( mail.outbox[0].subject, - "Your username for " + - site.name) + f"Your username for {site.name}") def test_get_profile(self): admin = get_user_model().objects.get(username='admin') diff --git a/geonode/people/utils.py b/geonode/people/utils.py index 0d86c97f5f6..3f877bb8b9e 100644 --- a/geonode/people/utils.py +++ b/geonode/people/utils.py @@ -64,27 +64,27 @@ def format_address(street=None, zipcode=None, city=None, area=None, country=None address = "" if city and area: if street: - address += street + ", " - address += city + ", " + area + address += f"{street}, " + address += f"{city}, {area}" if zipcode: - address += " " + zipcode + address += f" {zipcode}" elif (not city) and area: if street: - address += street + ", " + address += f"{street}, " address += area if zipcode: - address += " " + zipcode + address += f" {zipcode}" elif city and (not area): if street: - address += street + ", " + address += f"{street}, " address += city if zipcode: - address += " " + zipcode + address += f" {zipcode}" else: if street: - address += ", " + street + address += f", {street}" if zipcode: - address += " " + zipcode + address += f" {zipcode}" if address: address += ", United States" diff --git a/geonode/people/views.py b/geonode/people/views.py index bcadd605c4d..3d315d84993 100644 --- a/geonode/people/views.py +++ b/geonode/people/views.py @@ -71,7 +71,7 @@ def profile_edit(request, username=None): form = ProfileForm(request.POST, request.FILES, instance=profile) if form.is_valid(): form.save() - messages.success(request, ("Profile %s updated." % username)) + messages.success(request, (f"Profile {username} updated.")) return redirect( reverse( 'profile_detail', @@ -117,7 +117,7 @@ def forgot_username(request): site = Site.objects.get_current() - email_subject = _("Your username for " + site.name) + email_subject = _(f"Your username for {site.name}") if request.method == 'POST': username_form = ForgotUsernameForm(request.POST) @@ -128,7 +128,7 @@ def forgot_username(request): if users: username = users[0].username - email_message = email_subject + " : " + username + email_message = f"{email_subject} : {username}" send_email(email_subject, email_message, settings.DEFAULT_FROM_EMAIL, [username_form.cleaned_data['email']], fail_silently=False) message = _("Your username has been emailed to you.") diff --git a/geonode/proxy/templatetags/proxy_lib_tags.py b/geonode/proxy/templatetags/proxy_lib_tags.py index b8d2c170257..2afa55a35d2 100644 --- a/geonode/proxy/templatetags/proxy_lib_tags.py +++ b/geonode/proxy/templatetags/proxy_lib_tags.py @@ -49,7 +49,7 @@ def original_link_available(context, resourceid, url): download_url = urljoin(settings.SITEURL, reverse("download", args={resourceid})) if urlsplit(url).netloc != urlsplit(download_url).netloc or \ - urlsplit(url).path != urlsplit(download_url).path: + urlsplit(url).path != urlsplit(download_url).path: return True layer_files = [] diff --git a/geonode/proxy/tests.py b/geonode/proxy/tests.py index 4ddee32fd9a..02819a0ba52 100644 --- a/geonode/proxy/tests.py +++ b/geonode/proxy/tests.py @@ -43,7 +43,7 @@ from geonode.base.populate_test_data import create_models TEST_DOMAIN = '.github.com' -TEST_URL = 'https://help%s/' % TEST_DOMAIN +TEST_URL = f'https://help{TEST_DOMAIN}/' class ProxyTest(GeoNodeBaseTestSupport): @@ -59,8 +59,7 @@ def setUp(self): @override_settings(DEBUG=True, PROXY_ALLOWED_HOSTS=()) def test_validate_host_disabled_in_debug(self): """If PROXY_ALLOWED_HOSTS is empty and DEBUG is True, all hosts pass the proxy.""" - response = self.client.get('%s?url=%s' % - (self.proxy_url, self.url)) + response = self.client.get(f'{self.proxy_url}?url={self.url}') # 404 - NOT FOUND if response.status_code != 404: self.assertTrue(response.status_code in (200, 301)) @@ -68,8 +67,7 @@ def test_validate_host_disabled_in_debug(self): @override_settings(DEBUG=False, PROXY_ALLOWED_HOSTS=()) def test_validate_host_disabled_not_in_debug(self): """If PROXY_ALLOWED_HOSTS is empty and DEBUG is False requests should return 403.""" - response = self.client.get('%s?url=%s' % - (self.proxy_url, self.url)) + response = self.client.get(f'{self.proxy_url}?url={self.url}') # 404 - NOT FOUND if response.status_code != 404: self.assertEqual(response.status_code, 403) @@ -78,8 +76,7 @@ def test_validate_host_disabled_not_in_debug(self): @override_settings(DEBUG=False, PROXY_ALLOWED_HOSTS=(TEST_DOMAIN,)) def test_proxy_allowed_host(self): """If PROXY_ALLOWED_HOSTS is empty and DEBUG is False requests should return 403.""" - response = self.client.get('%s?url=%s' % - (self.proxy_url, self.url)) + response = self.client.get(f'{self.proxy_url}?url={self.url}') # 404 - NOT FOUND if response.status_code != 404: self.assertTrue(response.status_code in (200, 301)) @@ -98,7 +95,7 @@ def test_validate_remote_services_hosts(self): method=INDEXED, base_url='http://bogus.pocus.com/ows') response = self.client.get( - '%s?url=%s' % (self.proxy_url, 'http://bogus.pocus.com/ows/wms?request=GetCapabilities')) + f"{self.proxy_url}?url={'http://bogus.pocus.com/ows/wms?request=GetCapabilities'}") # 200 - FOUND self.assertTrue(response.status_code in (200, 301)) @@ -119,7 +116,7 @@ class Response(object): geonode.proxy.views.http_client.request = request_mock url = "http://example.org/test/test/../../index.html" - self.client.get('%s?url=%s' % (self.proxy_url, url)) + self.client.get(f'{self.proxy_url}?url={url}') assert request_mock.call_args[0][0] == 'http://example.org/index.html' diff --git a/geonode/proxy/views.py b/geonode/proxy/views.py index 7aa146c4c3c..7e487e0119b 100644 --- a/geonode/proxy/views.py +++ b/geonode/proxy/views.py @@ -97,9 +97,9 @@ def proxy(request, url=None, response_callback=None, scheme = str(url.scheme) locator = str(url.path) if url.query != "": - locator += '?' + url.query + locator += f"?{url.query}" if url.fragment != "": - locator += '#' + url.fragment + locator += f"#{url.fragment}" # White-Black Listing Hosts site_url = urlsplit(settings.SITEURL) @@ -167,8 +167,7 @@ def proxy(request, url=None, response_callback=None, if request.method == "GET" and access_token and 'access_token' not in _url: query_separator = '&' if '?' in _url else '?' - _url = ('%s%saccess_token=%s' % - (_url, query_separator, access_token)) + _url = f'{_url}{query_separator}access_token={access_token}' _data = request.body.decode('utf-8') @@ -176,10 +175,10 @@ def proxy(request, url=None, response_callback=None, if check_ogc_backend(geoserver.BACKEND_PACKAGE): from geonode.geoserver.helpers import ogc_server_settings _url = _url.replace( - '%s%s' % (settings.SITEURL, 'geoserver'), + f"{settings.SITEURL}{'geoserver'}", ogc_server_settings.LOCATION.rstrip('/')) _data = _data.replace( - '%s%s' % (settings.SITEURL, 'geoserver'), + f"{settings.SITEURL}{'geoserver'}", ogc_server_settings.LOCATION.rstrip('/')) response, content = http_client.request( @@ -356,7 +355,7 @@ def download(request, resourceid, sender=Layer): links = Link.objects.filter(resource=instance.resourcebase_ptr) for link in links: link_name = slugify(link.name) - link_file = os.path.join(target_md_folder, "".join([link_name, ".%s" % link.extension])) + link_file = os.path.join(target_md_folder, "".join([link_name, f".{link.extension}"])) if link.link_type in ('data'): # Skipping 'data' download links continue @@ -397,7 +396,7 @@ def download(request, resourceid, sender=Layer): content=open(target_file, mode='rb'), status=200, content_type="application/zip") - response['Content-Disposition'] = 'attachment; filename="%s"' % target_file_name + response['Content-Disposition'] = f'attachment; filename="{target_file_name}"' return response except NotImplementedError: traceback.print_exc() @@ -434,7 +433,7 @@ def get(self, request): headers, access_token = get_headers(request, _url, _raw_url) if access_token: _j = '&' if _url.query else '?' - _raw_url = _j.join([_raw_url, 'access_token={}'.format(access_token)]) + _raw_url = _j.join([_raw_url, f'access_token={access_token}']) data.append({'url': _raw_url, 'type': 'OGC:WMS'}) # WCS @@ -443,7 +442,7 @@ def get(self, request): headers, access_token = get_headers(request, _url, _raw_url) if access_token: _j = '&' if _url.query else '?' - _raw_url = _j.join([_raw_url, 'access_token={}'.format(access_token)]) + _raw_url = _j.join([_raw_url, f'access_token={access_token}']) data.append({'url': _raw_url, 'type': 'OGC:WCS'}) # WFS @@ -452,7 +451,7 @@ def get(self, request): headers, access_token = get_headers(request, _url, _raw_url) if access_token: _j = '&' if _url.query else '?' - _raw_url = _j.join([_raw_url, 'access_token={}'.format(access_token)]) + _raw_url = _j.join([_raw_url, f'access_token={access_token}']) data.append({'url': _raw_url, 'type': 'OGC:WFS'}) # catalogue from configuration @@ -463,7 +462,7 @@ def get(self, request): headers, access_token = get_headers(request, _url, _raw_url) if access_token: _j = '&' if _url.query else '?' - _raw_url = _j.join([_raw_url, 'access_token={}'.format(access_token)]) + _raw_url = _j.join([_raw_url, f'access_token={access_token}']) data.append({'url': _raw_url, 'type': 'OGC:CSW'}) # main site url diff --git a/geonode/qgis_server/gis_tools.py b/geonode/qgis_server/gis_tools.py index 07e0eaa44b1..91a270c7ace 100644 --- a/geonode/qgis_server/gis_tools.py +++ b/geonode/qgis_server/gis_tools.py @@ -52,13 +52,7 @@ def set_attributes(layer, overwrite=False): qgis_server = geonode_config.QGIS_SERVER_CONFIG['qgis_server_url'] basename, _ = splitext(qgis_layer.base_layer_path) - dft_url = qgis_server + '?' + urlencode({ - 'MAP': basename + '.qgs', - 'SERVICE': 'WFS', - 'VERSION': '1.0.0', - 'REQUEST': 'DescribeFeatureType', - 'LAYER': layer_name - }) + dft_url = f"{qgis_server}?{urlencode({'MAP': f'{basename}.qgs', 'SERVICE': 'WFS', 'VERSION': '1.0.0', 'REQUEST': 'DescribeFeatureType', 'LAYER': layer_name})}" # noinspection PyBroadException try: diff --git a/geonode/qgis_server/helpers.py b/geonode/qgis_server/helpers.py index a841f0d78bc..00a82739d4d 100644 --- a/geonode/qgis_server/helpers.py +++ b/geonode/qgis_server/helpers.py @@ -110,8 +110,7 @@ def validate_django_settings(): if not default_ogc_backend['BACKEND'] == qgis_server.BACKEND_PACKAGE: raise ImproperlyConfigured( - "OGC_SERVER['default']['BACKEND'] should be set to " - "{package}.".format(package=qgis_server.BACKEND_PACKAGE)) + f"OGC_SERVER['default']['BACKEND'] should be set to {qgis_server.BACKEND_PACKAGE}.") return True @@ -225,8 +224,7 @@ def tile_url(layer, z, x, y, style=None, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format( - layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -301,13 +299,13 @@ def map_thumbnail_url(instance, bbox=None, internal=True): try: qgis_map = QGISServerMap.objects.get(map=instance) except QGISServerMap.DoesNotExist: - msg = 'No QGIS Server Map for existing map {0}'.format(instance.title) + msg = f'No QGIS Server Map for existing map {instance.title}' logger.debug(msg) raise qgis_project = qgis_map.qgis_project_path if not os.path.exists(qgis_project): - msg = 'Map project not found for {0}'.format(qgis_project) + msg = f'Map project not found for {qgis_project}' logger.debug(msg) raise ValueError(msg) @@ -342,8 +340,7 @@ def layer_thumbnail_url(instance, style=None, bbox=None, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=instance) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format( - instance.name) + msg = f'No QGIS Server Layer for existing layer {instance.name}' logger.debug(msg) raise @@ -448,7 +445,7 @@ def legend_url(layer, layertitle=False, style=None, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -522,8 +519,7 @@ def qgs_url(layer, style=None, internal=True): json_layers = json.dumps(layers) - url_server = qgis_server_url + \ - '?SERVICE=PROJECTDEFINITIONS&LAYERS=' + json_layers + url_server = f"{qgis_server_url}?SERVICE=PROJECTDEFINITIONS&LAYERS={json_layers}" return url_server @@ -568,8 +564,7 @@ def qlr_url(layer, style=None, internal=True): }] json_layers = json.dumps(layers) - url_server = qgis_server_url + \ - '?SERVICE=LAYERDEFINITIONS&LAYERS=' + json_layers + url_server = f"{qgis_server_url}?SERVICE=LAYERDEFINITIONS&LAYERS={json_layers}" return url_server @@ -590,7 +585,7 @@ def wms_get_capabilities_url(layer=None, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -628,7 +623,7 @@ def style_get_url(layer, style_name, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -669,7 +664,7 @@ def style_add_url(layer, style_name, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -710,7 +705,7 @@ def style_remove_url(layer, style_name, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -748,7 +743,7 @@ def style_set_default_url(layer, style_name, internal=True): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -804,7 +799,7 @@ def style_list(layer, internal=True, generating_qgis_capabilities=False): try: qgis_layer = QGISServerLayer.objects.get(layer=layer) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer for existing layer {0}'.format(layer.name) + msg = f'No QGIS Server Layer for existing layer {layer.name}' logger.debug(msg) raise @@ -866,7 +861,7 @@ def style_list(layer, internal=True, generating_qgis_capabilities=False): return styles_obj except Exception: - msg = 'No QGIS Style for existing layer {0}'.format(layer.name) + msg = f'No QGIS Style for existing layer {layer.name}' logger.debug(msg) raise @@ -893,9 +888,7 @@ def create_qgis_project( qgis_layer = QGISServerLayer.objects.get(layer=layer) files = qgis_layer.base_layer_path names = layer.name - logger.debug('File %s is exists: %s' % ( - files, str(os.path.exists(files)) - )) + logger.debug(f'File {files} is exists: {str(os.path.exists(files))}') elif isinstance(layer, list): qgis_layer = [] for lyr in layer: @@ -903,9 +896,7 @@ def create_qgis_project( files = [ql.base_layer_path for ql in qgis_layer] for fl in files: - logger.debug('File %s is exists: %s' % ( - fl, str(os.path.exists(fl)) - )) + logger.debug(f'File {fl} is exists: {str(os.path.exists(fl))}') files = ';'.join(files) @@ -913,7 +904,7 @@ def create_qgis_project( names = ';'.join(names) else: raise ValueError( - 'Unexpected argument layer: {0}'.format(layer)) + f'Unexpected argument layer: {layer}') overwrite = str(overwrite).lower() @@ -934,35 +925,35 @@ def delete_orphaned_qgis_server_layers(): """Delete orphaned QGIS Server files.""" layer_path = settings.QGIS_SERVER_CONFIG['layer_directory'] if not os.path.exists(layer_path): - print("{path} not exists".format(path=layer_path)) + print(f"{layer_path} not exists") return for filename in os.listdir(layer_path): basename, __ = os.path.splitext(filename) fn = os.path.join(layer_path, filename) if QGISServerLayer.objects.filter( base_layer_path__icontains=basename).count() == 0: - print("Removing orphan layer file {}".format(fn)) + print(f"Removing orphan layer file {fn}") try: os.remove(fn) except OSError: - print("Could not delete file {}".format(fn)) + print(f"Could not delete file {fn}") def delete_orphaned_qgis_server_caches(): """Delete orphaned QGIS Server tile caches.""" tiles_path = settings.QGIS_SERVER_CONFIG['tiles_directory'] if not os.path.exists(tiles_path): - print("{path} not exists".format(path=tiles_path)) + print(f"{tiles_path} not exists") return for basename in os.listdir(tiles_path): path = os.path.join(tiles_path, basename) if QGISServerLayer.objects.filter( base_layer_path__icontains=basename).count() == 0: - print("Removing orphan layer file {}".format(path)) + print(f"Removing orphan layer file {path}") try: shutil.rmtree(path) except OSError: - print("Could not delete file {}".format(path)) + print(f"Could not delete file {path}") def get_model_path(instance): @@ -973,7 +964,4 @@ def get_model_path(instance): """ model_type = ContentType.objects.get_for_model(instance) - return "{app_label}.{model_name}".format( - app_label=model_type.app_label, - model_name=model_type.model - ) + return f"{model_type.app_label}.{model_type.model}" diff --git a/geonode/qgis_server/management/commands/import_qgis_styles.py b/geonode/qgis_server/management/commands/import_qgis_styles.py index f4352a01199..d9324345765 100644 --- a/geonode/qgis_server/management/commands/import_qgis_styles.py +++ b/geonode/qgis_server/management/commands/import_qgis_styles.py @@ -33,7 +33,7 @@ def handle(self, *args, **options): try: l.qgis_layer except Exception: - print("Layer {} has no associated qgis_layer".format(l.name)) + print(f"Layer {l.name} has no associated qgis_layer") continue if l.qgis_layer: diff --git a/geonode/qgis_server/models.py b/geonode/qgis_server/models.py index 1696ca4199c..f6b656a2ab3 100644 --- a/geonode/qgis_server/models.py +++ b/geonode/qgis_server/models.py @@ -97,9 +97,7 @@ def files(self): extensions_list += ['.aux.xml'] found_files = [] for ext in extensions_list: - file_path = '{base}.{ext}'.format( - base=base_name, - ext=ext) + file_path = f'{base_name}.{ext}' if os.path.exists(file_path): found_files.append(file_path) return found_files @@ -133,7 +131,7 @@ def qgis_project_path(self): QGIS Project path: /usr/src/app/geonode/qgis_layer/jakarta_flood.qgs """ - return '{prefix}.qgs'.format(prefix=self.qgis_layer_path_prefix) + return f'{self.qgis_layer_path_prefix}.qgs' @property def cache_path(self): @@ -159,7 +157,7 @@ def qml_path(self): :return: Base path of qml style :rtype: str """ - return '{prefix}.qml'.format(prefix=self.qgis_layer_path_prefix) + return f'{self.qgis_layer_path_prefix}.qml' def delete_qgis_layer(self): """Delete all files related to this object from disk.""" @@ -171,7 +169,7 @@ def delete_qgis_layer(self): # Removing the cache. path = self.cache_path - logger.debug('Removing the cache from a qgis layer : %s' % path) + logger.debug(f'Removing the cache from a qgis layer : {path}') try: rmtree(path) except OSError: @@ -363,7 +361,7 @@ def qgis_project_path(self): based on map_name_format QGIS Project path: /usr/src/app/geonode/qgis_layer/map_1.qgs """ - return '{prefix}.qgs'.format(prefix=self.qgis_map_path_prefix) + return f'{self.qgis_map_path_prefix}.qgs' @property def cache_path(self): diff --git a/geonode/qgis_server/signals.py b/geonode/qgis_server/signals.py index 6cd088ac62c..e910490a270 100644 --- a/geonode/qgis_server/signals.py +++ b/geonode/qgis_server/signals.py @@ -115,7 +115,7 @@ def qgis_server_post_save(instance, sender, **kwargs): qgis_layer, created = QGISServerLayer.objects.get_or_create( layer=instance) - logger.debug('Geonode Layer Path %s' % geonode_layer_path) + logger.debug(f'Geonode Layer Path {geonode_layer_path}') base_filename, original_ext = os.path.splitext(geonode_layer_path) extensions = QGISServerLayer.accepted_format @@ -123,14 +123,14 @@ def qgis_server_post_save(instance, sender, **kwargs): is_shapefile = False for ext in extensions: - if os.path.exists(base_filename + '.' + ext): + if os.path.exists(f"{base_filename}.{ext}"): is_shapefile = is_shapefile or ext == 'shp' try: if created: # Assuming different layer has different filename because # geonode rename it shutil.copy2( - base_filename + '.' + ext, + f"{base_filename}.{ext}", QGIS_layer_directory ) logger.debug('Create new basefile') @@ -138,16 +138,16 @@ def qgis_server_post_save(instance, sender, **kwargs): # If there is already a file, replace the old one qgis_layer_base_filename = qgis_layer.qgis_layer_path_prefix shutil.copy2( - base_filename + '.' + ext, - qgis_layer_base_filename + '.' + ext + f"{base_filename}.{ext}", + f"{qgis_layer_base_filename}.{ext}" ) logger.debug('Overwrite existing basefile') logger.debug( - 'Copying %s' % base_filename + '.' + ext + ' Success') - logger.debug('Into %s' % QGIS_layer_directory) + f"Copying {base_filename}.{ext} Success") + logger.debug(f'Into {QGIS_layer_directory}') except IOError as e: logger.debug( - 'Copying %s' % base_filename + '.' + ext + ' FAILED ' + e) + f"Copying {base_filename}.{ext} FAILED {e}") if created: # Only set when creating new QGISServerLayer Object geonode_filename = os.path.basename(geonode_layer_path) @@ -178,8 +178,7 @@ def qgis_server_post_save(instance, sender, **kwargs): if srid: instance.srid = srid except Exception as e: - logger.debug("Can't retrieve projection: {layer}".format( - layer=geonode_layer_path)) + logger.debug(f"Can't retrieve projection: {geonode_layer_path}") logger.exception(e) # Refresh and create the instance default links @@ -212,7 +211,7 @@ def qgis_server_post_save(instance, sender, **kwargs): # Get the path of the metadata file basename, _ = os.path.splitext(qgis_layer.base_layer_path) - xml_file_path = basename + '.xml' + xml_file_path = f"{basename}.xml" if os.path.exists(xml_file_path): try: update_xml(xml_file_path, new_values) @@ -220,7 +219,7 @@ def qgis_server_post_save(instance, sender, **kwargs): pass # Also update xml in QGIS Server - xml_file_path = qgis_layer.qgis_layer_path_prefix + '.xml' + xml_file_path = f"{qgis_layer.qgis_layer_path_prefix}.xml" if os.path.exists(xml_file_path): try: update_xml(xml_file_path, new_values) @@ -242,7 +241,7 @@ def qgis_server_post_save(instance, sender, **kwargs): @on_ogc_backend(qgis_server.BACKEND_PACKAGE) def qgis_server_pre_save_maplayer(instance, sender, **kwargs): - logger.debug('QGIS Server Pre Save Map Layer %s' % instance.name) + logger.debug(f'QGIS Server Pre Save Map Layer {instance.name}') try: layer = Layer.objects.get(alternate=instance.name) if layer: @@ -275,11 +274,10 @@ def qgis_server_post_save_map(instance, sender, **kwargs): raise QGISServerLayer.DoesNotExist layers.append(_l) except Layer.DoesNotExist: - msg = 'No Layer found for typename: {0}'.format(layer.name) + msg = f'No Layer found for typename: {layer.name}' logger.debug(msg) except QGISServerLayer.DoesNotExist: - msg = 'No QGIS Server Layer found for typename: {0}'.format( - layer.name) + msg = f'No QGIS Server Layer found for typename: {layer.name}' logger.debug(msg) if not layers: @@ -293,7 +291,7 @@ def qgis_server_post_save_map(instance, sender, **kwargs): reverse( 'map_download', kwargs={'mapid': instance.id})) - logger.debug('map_download_url: %s' % map_download_url) + logger.debug(f'map_download_url: {map_download_url}') link_name = 'Download Data Layers' Link.objects.update_or_create( resource=instance.resourcebase_ptr, @@ -311,7 +309,7 @@ def qgis_server_post_save_map(instance, sender, **kwargs): reverse( 'map_wmc', kwargs={'mapid': instance.id})) - logger.debug('wmc_download_url: %s' % ogc_wmc_url) + logger.debug(f'wmc_download_url: {ogc_wmc_url}') link_name = 'Download Web Map Context' link_mime = 'application/xml' Link.objects.update_or_create( @@ -331,7 +329,7 @@ def qgis_server_post_save_map(instance, sender, **kwargs): reverse( 'map_download_qlr', kwargs={'mapid': instance.id})) - logger.debug('qlr_map_download_url: %s' % ogc_qlr_url) + logger.debug(f'qlr_map_download_url: {ogc_qlr_url}') link_name = 'Download QLR Layer file' link_mime = 'application/xml' Link.objects.update_or_create( @@ -374,10 +372,9 @@ def qgis_server_post_save_map(instance, sender, **kwargs): overwrite=overwrite, internal=True) - logger.debug('Create project url: {url}'.format(url=response.url)) + logger.debug(f'Create project url: {response.url}') logger.debug( - 'Creating the QGIS Project : %s -> %s' % ( - qgis_map.qgis_project_path, ensure_string(response.content))) + f'Creating the QGIS Project : {qgis_map.qgis_project_path} -> {ensure_string(response.content)}') # Generate map thumbnail create_qgis_server_thumbnail.apply_async(( diff --git a/geonode/qgis_server/tasks/update.py b/geonode/qgis_server/tasks/update.py index c48c267a2b5..9a897ca9da1 100644 --- a/geonode/qgis_server/tasks/update.py +++ b/geonode/qgis_server/tasks/update.py @@ -80,7 +80,7 @@ def create_qgis_server_thumbnail(model_path, object_id, overwrite=False, bbox=No return True if not thumbnail_remote_url: return True - logger.debug('Create thumbnail for %s' % thumbnail_remote_url) + logger.debug(f'Create thumbnail for {thumbnail_remote_url}') if overwrite: # if overwrite, then delete existing thumbnail links @@ -98,8 +98,7 @@ def create_qgis_server_thumbnail(model_path, object_id, overwrite=False, bbox=No # if it is socket exception, we should raise it, because there is # something wrong with the url except socket.error as e: - logger.error('Thumbnail url not accessed {url}'.format( - url=thumbnail_remote_url)) + logger.error(f'Thumbnail url not accessed {thumbnail_remote_url}') logger.exception(e) # reraise exception with original traceback raise @@ -138,7 +137,7 @@ def cache_request(self, url, cache_file): :return: True if succeeded :rtype: bool """ - logger.debug('Requesting url: {url}'.format(url=url)) + logger.debug(f'Requesting url: {url}') response = requests.get(url, stream=True) if not response.status_code == 200: diff --git a/geonode/qgis_server/tests/test_management.py b/geonode/qgis_server/tests/test_management.py index 73f7d1fc7ee..cc19a2f89cd 100644 --- a/geonode/qgis_server/tests/test_management.py +++ b/geonode/qgis_server/tests/test_management.py @@ -88,7 +88,7 @@ def test_import_layers(self): self.assertTrue(os.path.exists(qgis_layer.cache_path)) tiles_png = os.path.join( qgis_layer.cache_path, 'default', str(tiles['z']), str(tiles['x']), - str(tiles['y']) + '.png') + f"{str(tiles['y'])}.png") self.assertTrue(os.path.exists(tiles_png)) self.assertEqual(what(tiles_png), 'png') diff --git a/geonode/qgis_server/tests/test_qgis_settings.py b/geonode/qgis_server/tests/test_qgis_settings.py index 1180e9b780d..9a0d951b97d 100644 --- a/geonode/qgis_server/tests/test_qgis_settings.py +++ b/geonode/qgis_server/tests/test_qgis_settings.py @@ -48,7 +48,7 @@ def test_qgis_server_connection(self): 'Service unknown or unsupported', response.content, message) # Test if OTF-Plugin is installed - url = qgis_server_url + '?SERVICE=MAPCOMPOSITION' + url = f"{qgis_server_url}?SERVICE=MAPCOMPOSITION" response = requests.get(url) message = 'OTF-Project is not installed on QGIS-Server {url}' message = message.format(url=url) diff --git a/geonode/qgis_server/views.py b/geonode/qgis_server/views.py index ae1b9482d2f..b84c15ab31d 100644 --- a/geonode/qgis_server/views.py +++ b/geonode/qgis_server/views.py @@ -81,7 +81,7 @@ def download_zip(request, layername): # Folder name in ZIP archive which contains the above files # E.g [thearchive.zip]/somefiles/file2.txt zip_subdir = layer.name - zip_filename = "%s.zip" % zip_subdir + zip_filename = f"{zip_subdir}.zip" # Open StringIO to grab in-memory ZIP contents s = io.StringIO() @@ -105,7 +105,7 @@ def download_zip(request, layername): resp = HttpResponse( s.getvalue(), content_type="application/x-zip-compressed") # ..and correct content-disposition - resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename + resp['Content-Disposition'] = f'attachment; filename={zip_filename}' return resp @@ -135,7 +135,7 @@ def download_qgs(request, layername): result.content, content_type="application/x-qgis-project", status=result.status_code) response['Content-Disposition'] = \ - 'attachment; filename=%s.qgs' % layer_title + f'attachment; filename={layer_title}.qgs' return response @@ -153,7 +153,7 @@ def download_map(request, mapid): # Folder name in ZIP archive which contains the above files # E.g [thearchive.zip]/somefiles/file2.txt zip_subdir = mapid - zip_filename = "%s.zip" % zip_subdir + zip_filename = f"{zip_subdir}.zip" # Open StringIO to grab in-memory ZIP contents s = io.StringIO() @@ -187,7 +187,7 @@ def download_map(request, mapid): resp = HttpResponse( s.getvalue(), content_type="application/x-zip-compressed") # ..and correct content-disposition - resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename + resp['Content-Disposition'] = f'attachment; filename={zip_filename}' return resp @@ -238,7 +238,7 @@ def legend(request, layername, layertitle=False, style=None): return HttpResponseServerError('Failed to fetch legend.') if image_format(legend_filename) != 'png': - logger.error('%s is not valid PNG.' % legend_filename) + logger.error(f'{legend_filename} is not valid PNG.') os.remove(legend_filename) if not os.path.exists(legend_filename): @@ -329,7 +329,7 @@ def tile(request, layername, z, x, y, style=None): return HttpResponseServerError('Failed to fetch tile.') if image_format(tile_filename) != 'png': - logger.error('%s is not valid PNG.' % tile_filename) + logger.error(f'{tile_filename} is not valid PNG.') os.remove(tile_filename) if not os.path.exists(tile_filename): @@ -384,7 +384,7 @@ def geotiff(request, layername): # get geotiff file if exists for ext in QGISServerLayer.geotiff_format: - target_file = qgis_layer.qgis_layer_path_prefix + '.' + ext + target_file = f"{qgis_layer.qgis_layer_path_prefix}.{ext}" if os.path.exists(target_file): filename = target_file break @@ -392,7 +392,7 @@ def geotiff(request, layername): filename = None if not filename: - msg = 'No Geotiff layer found for %s' % layername + msg = f'No Geotiff layer found for {layername}' logger.debug(msg) raise Http404(msg) @@ -463,7 +463,7 @@ def qgis_server_request(request): # our proxy if params.get('REQUEST') == 'GetCapabilities': qgis_server_base_url = qgis_server_endpoint(internal=True) - pattern = '{endpoint}'.format(endpoint=qgis_server_base_url) + pattern = f'{qgis_server_base_url}' content = re.sub( pattern, qgis_server_endpoint(internal=False), content) @@ -511,8 +511,8 @@ def qgis_server_pdf(request): "rotation": False } ], - "printURL": "%s" % print_url, - "createURL": "%s" % print_url + "printURL": f"{print_url}", + "createURL": f"{print_url}" } return HttpResponse( @@ -524,7 +524,7 @@ def qgis_server_map_print(request): temp = [] for key, value in request.POST.items(): temp[key] = value - print("{}\n{}\n--------".format(key, value)) + print(f"{key}\n{value}\n--------") return HttpResponse( json.dumps(temp), content_type="application/json") @@ -580,8 +580,7 @@ def qml_style(request, layername, style_name=None): response = HttpResponse( ensure_string(response.content), content_type='text/xml') response[ - 'Content-Disposition'] = 'attachment; filename=%s.qml' % ( - style_name, ) + 'Content-Disposition'] = f'attachment; filename={style_name}.qml' else: response = HttpResponse( ensure_string(response.content), status=response.status_code) @@ -671,7 +670,7 @@ def qml_style(request, layername, style_name=None): qgis_style.title = style_title qgis_style.save() - alert_message = 'Successfully add style %s' % style_name + alert_message = f'Successfully add style {style_name}' except Exception: alert_message = 'Failed to fetch styles' @@ -711,7 +710,7 @@ def qml_style(request, layername, style_name=None): if not (response.status_code == 200 and ensure_string(response.content) == 'OK'): alert_message = ensure_string(response.content) if 'NAME is NOT an existing style.' in ensure_string(response.content): - alert_message = '%s is not an existing style' % style_name + alert_message = f'{style_name} is not an existing style' try: style_list(layer, internal=False) except Exception: @@ -735,7 +734,7 @@ def qml_style(request, layername, style_name=None): try: style_list(layer, internal=False) - alert_message = 'Successfully deleted style %s' % style_name + alert_message = f'Successfully deleted style {style_name}' except Exception: alert_message = 'Failed to fetch styles' @@ -802,7 +801,7 @@ def default_qml_style(request, layername, style_name=None): qgis_layer.default_style = style qgis_layer.save() - alert_message = 'Successfully changed default style %s' % style_name + alert_message = f'Successfully changed default style {style_name}' return TemplateResponse( request, @@ -876,6 +875,6 @@ def download_qlr(request, layername): content_type="application/x-qgis-layer-definition", status=result.status_code) response['Content-Disposition'] = \ - 'attachment; filename=%s.qlr' % layer_title + f'attachment; filename={layer_title}.qlr' return response diff --git a/geonode/security/middleware.py b/geonode/security/middleware.py index c38d99208c9..abfddc778f2 100644 --- a/geonode/security/middleware.py +++ b/geonode/security/middleware.py @@ -36,7 +36,7 @@ # make sure login_url can be mapped to redirection URL and will match request.path login_url = settings.LOGIN_URL.replace(settings.SITEURL.rstrip('/'), '') if not login_url.startswith('/'): - login_url = '/' + login_url + login_url = f"/{login_url}" if check_ogc_backend(geoserver.BACKEND_PACKAGE): white_list_paths = ( @@ -101,7 +101,7 @@ def process_request(self, request): if not any(path.match(request.path) for path in white_list): return HttpResponseRedirect( - "{login_path}?next={request_path}".format(login_path=self.redirect_to, request_path=request.path) + f"{self.redirect_to}?next={request.path}" ) @@ -143,6 +143,4 @@ def do_logout(self, request): if not any(path.match(request.path) for path in white_list): return HttpResponseRedirect( - '{login_path}?next={request_path}'.format( - login_path=self.redirect_to, - request_path=request.path)) + f'{self.redirect_to}?next={request.path}') diff --git a/geonode/security/models.py b/geonode/security/models.py index 2c6086f084b..9cbfd0babc2 100644 --- a/geonode/security/models.py +++ b/geonode/security/models.py @@ -93,7 +93,7 @@ def get_all_level_info(self): if managers: for manager in managers: if manager not in users and not manager.is_superuser and \ - manager != resource.owner: + manager != resource.owner: for perm in ADMIN_PERMISSIONS + VIEW_PERMISSIONS: assign_perm(perm, manager, resource) users[manager] = ADMIN_PERMISSIONS + VIEW_PERMISSIONS @@ -107,7 +107,7 @@ def get_all_level_info(self): if managers: for manager in managers: if manager not in users and not manager.is_superuser and \ - manager != resource.owner: + manager != resource.owner: for perm in ADMIN_PERMISSIONS + VIEW_PERMISSIONS: assign_perm(perm, manager, resource) users[manager] = ADMIN_PERMISSIONS + VIEW_PERMISSIONS @@ -161,7 +161,7 @@ def skip_registered_members_common_group(user_group): if groups_settings.AUTO_ASSIGN_REGISTERED_MEMBERS_TO_REGISTERED_MEMBERS_GROUP_NAME: _members_group_name = groups_settings.REGISTERED_MEMBERS_GROUP_NAME if (settings.RESOURCE_PUBLISHING or settings.ADMIN_MODERATE_UPLOADS) and \ - _members_group_name == user_group.name: + _members_group_name == user_group.name: return True return False @@ -401,7 +401,7 @@ def get_user_perms(self, user): resource_perms = Permission.objects.filter( codename__in=PERMISSIONS_TO_FETCH, content_type_id=ctype.id - ).values('codename') + ).values('codename') user_model = get_user_obj_perms_model(self) user_resource_perms = user_model.objects.filter( @@ -409,7 +409,7 @@ def get_user_perms(self, user): content_type_id=ctype.id, user_id=user.id, permission__codename__in=resource_perms - ).values_list('permission__codename', flat=True) + ).values_list('permission__codename', flat=True) return user_resource_perms diff --git a/geonode/security/oauth2_grant_types.py b/geonode/security/oauth2_grant_types.py index affded7fb07..ff3492a9956 100644 --- a/geonode/security/oauth2_grant_types.py +++ b/geonode/security/oauth2_grant_types.py @@ -361,7 +361,7 @@ def validate_authorization_request(self, request): duplicate_params = request.duplicate_params if param in duplicate_params: raise errors.InvalidRequestFatalError( - description='Duplicate %s parameter.' % param, + description=f'Duplicate {param} parameter.', request=request) except ValueError: log.exception( @@ -470,7 +470,7 @@ def validate_token_request(self, request): for param in ('client_id', 'grant_type', 'redirect_uri'): if param in request.duplicate_params: - raise errors.InvalidRequestError(description='Duplicate %s parameter.' % param, + raise errors.InvalidRequestError(description=f'Duplicate {param} parameter.', request=request) if self.request_validator.client_authentication_required(request): @@ -520,7 +520,7 @@ def validate_token_request(self, request): if challenge_method not in self._code_challenge_methods: raise errors.ServerError( - description="code_challenge_method {} is not supported.".format(challenge_method), + description=f"code_challenge_method {challenge_method} is not supported.", request=request ) @@ -565,7 +565,7 @@ def validate_token_request(self, request): def validate_code_challenge(self, challenge, challenge_method, verifier): if challenge_method in self._code_challenge_methods: return self._code_challenge_methods[challenge_method](verifier, challenge) - raise NotImplementedError('Unknown challenge_method %s' % challenge_method) + raise NotImplementedError(f'Unknown challenge_method {challenge_method}') class OpenIDAuthorizationCodeGrant(OpenIDGrantTypeBase): diff --git a/geonode/security/oauth2_validators.py b/geonode/security/oauth2_validators.py index fbe2b679d7a..57cb260c0a5 100644 --- a/geonode/security/oauth2_validators.py +++ b/geonode/security/oauth2_validators.py @@ -85,8 +85,8 @@ def get_id_token(self, token, token_handler, request): # http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDToken # if request.grant_type in 'authorization_code' and 'access_token' in token: if (request.grant_type == "authorization_code" and "access_token" in token) or \ - request.response_type == "code id_token token" or \ - (request.response_type == "id_token token" and "access_token" in token): + request.response_type == "code id_token token" or \ + (request.response_type == "id_token token" and "access_token" in token): acess_token = token["access_token"] sha256 = hashlib.sha256(acess_token.encode("ascii")) bits128 = sha256.hexdigest()[:16] diff --git a/geonode/security/tests.py b/geonode/security/tests.py index fd6027fc358..3636440b8d0 100644 --- a/geonode/security/tests.py +++ b/geonode/security/tests.py @@ -718,7 +718,8 @@ def test_perm_specs_synchronization(self): self.assertTrue('limits' in rule) rule_limits = rule['limits'] - self.assertEqual(rule_limits['allowedArea'], 'MULTIPOLYGON (((145.8046418749977 -42.49606500060302, \ + self.assertEqual( + rule_limits['allowedArea'], 'MULTIPOLYGON (((145.8046418749977 -42.49606500060302, \ 146.7000276171853 -42.53655428642583, 146.7110139453067 -43.07256577359489, \ 145.9804231249952 -43.05651288026286, 145.8046418749977 -42.49606500060302)))') self.assertEqual(rule_limits['catalogMode'], 'MIXED') @@ -754,7 +755,8 @@ def test_perm_specs_synchronization(self): self.assertTrue('limits' in rule) rule_limits = rule['limits'] self.assertEqual( - rule_limits['allowedArea'], 'MULTIPOLYGON (((145.8046418749977 -42.49606500060302, 146.7000276171853 \ + rule_limits['allowedArea'], + 'MULTIPOLYGON (((145.8046418749977 -42.49606500060302, 146.7000276171853 \ -42.53655428642583, 146.7110139453067 -43.07256577359489, 145.9804231249952 \ -43.05651288026286, 145.8046418749977 -42.49606500060302)))') self.assertEqual(rule_limits['catalogMode'], 'MIXED') diff --git a/geonode/security/utils.py b/geonode/security/utils.py index ec4f73d55a5..bd0c406c045 100644 --- a/geonode/security/utils.py +++ b/geonode/security/utils.py @@ -160,13 +160,13 @@ def get_geofence_rules(page=0, entries=1, count=False): curl -X GET -u admin:geoserver \ http://:/geoserver/rest/geofence/rules/count.json """ - _url = url + 'rest/geofence/rules/count.json' + _url = f"{url}rest/geofence/rules/count.json" elif page or entries: """ curl -X GET -u admin:geoserver \ http://:/geoserver/rest/geofence/rules.json?page={page}&entries={entries} """ - _url = url + 'rest/geofence/rules.json?page={}&entries={}'.format(page, entries) + _url = f"{url}rest/geofence/rules.json?page={page}&entries={entries}" r = requests.get(_url, headers=_headers, auth=HTTPBasicAuth(user, passwd), @@ -221,7 +221,7 @@ def purge_geofence_all(): http://:/geoserver/rest/geofence/rules.json """ headers = {'Content-type': 'application/json'} - r = requests.get(url + 'rest/geofence/rules.json', + r = requests.get(f"{url}rest/geofence/rules.json", headers=headers, auth=HTTPBasicAuth(user, passwd), timeout=10, @@ -237,16 +237,16 @@ def purge_geofence_all(): # Delete GeoFence Rules associated to the Layer # curl -X DELETE -u admin:geoserver http://:/geoserver/rest/geofence/rules/id/{r_id} for rule in rules: - r = requests.delete(url + 'rest/geofence/rules/id/' + str(rule['id']), + r = requests.delete(f"{url}rest/geofence/rules/id/{str(rule['id'])}", headers=headers, auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): - msg = "Could not DELETE GeoServer Rule id[%s]" % rule['id'] + msg = f"Could not DELETE GeoServer Rule id[{rule['id']}]" e = Exception(msg) - logger.debug("Response [{}] : {}".format(r.status_code, r.text)) + logger.debug(f"Response [{r.status_code}] : {r.text}") raise e except Exception: - logger.debug("Response [{}] : {}".format(r.status_code, r.text)) + logger.debug(f"Response [{r.status_code}] : {r.text}") except Exception: tb = traceback.format_exc() logger.debug(tb) @@ -287,14 +287,14 @@ def purge_geofence_layer_rules(resource): # curl -X DELETE -u admin:geoserver http://:/geoserver/rest/geofence/rules/id/{r_id} for r_id in r_ids: r = requests.delete( - url + 'rest/geofence/rules/id/' + str(r_id), + f"{url}rest/geofence/rules/id/{str(r_id)}", headers=headers, auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): msg = "Could not DELETE GeoServer Rule for Layer " msg = msg + str(layer_name) e = Exception(msg) - logger.debug("Response [{}] : {}".format(r.status_code, r.text)) + logger.debug(f"Response [{r.status_code}] : {r.text}") raise e except Exception as e: logger.exception(e) @@ -312,7 +312,7 @@ def set_geofence_invalidate_cache(): curl -X GET -u admin:geoserver \ http://:/geoserver/rest/ruleCache/invalidate """ - r = requests.put(url + 'rest/ruleCache/invalidate', + r = requests.put(f"{url}rest/ruleCache/invalidate", auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): @@ -337,11 +337,11 @@ def toggle_layer_cache(layer_name, enable=True, filters=None, formats=None): curl -v -u admin:geoserver -XGET \ "http://:/geoserver/gwc/rest/layers/geonode:tasmania_roads.xml" """ - r = requests.get(url + 'gwc/rest/layers/{}.xml'.format(layer_name), + r = requests.get(f"{url}gwc/rest/layers/{layer_name}.xml", auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): - logger.debug("Could not Retrieve {} Cache.".format(layer_name)) + logger.debug(f"Could not Retrieve {layer_name} Cache.") return False try: xml_content = r.content @@ -398,12 +398,12 @@ def toggle_layer_cache(layer_name, enable=True, filters=None, formats=None): """ headers = {'Content-type': 'text/xml'} payload = ET.tostring(tree) - r = requests.post(url + 'gwc/rest/layers/{}.xml'.format(layer_name), + r = requests.post(f"{url}gwc/rest/layers/{layer_name}.xml", headers=headers, data=payload, auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): - logger.debug("Could not Update {} Cache.".format(layer_name)) + logger.debug(f"Could not Update {layer_name} Cache.") return False except Exception: tb = traceback.format_exc() @@ -428,11 +428,11 @@ def delete_layer_cache(layer_name): curl -v -u admin:geoserver -XDELETE \ "http://:/geoserver/gwc/rest/layers/geonode:tasmania_roads.xml" """ - r = requests.delete(url + 'gwc/rest/layers/{}.xml'.format(layer_name), + r = requests.delete(f"{url}gwc/rest/layers/{layer_name}.xml", auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): - logger.debug("Could not Delete {} Cache.".format(layer_name)) + logger.debug(f"Could not Delete {layer_name} Cache.") return False return True except Exception: @@ -457,14 +457,14 @@ def set_geowebcache_invalidate_cache(layer_alternate, cat=None): http://localhost:8080/geoserver/gwc/rest/masstruncate """ headers = {'Content-type': 'text/xml'} - payload = "%s" % layer_alternate + payload = f"{layer_alternate}" r = requests.post( - url + 'gwc/rest/masstruncate', + f"{url}gwc/rest/masstruncate", headers=headers, data=payload, auth=HTTPBasicAuth(user, passwd)) if (r.status_code < 200 or r.status_code > 201): - logger.debug("Could not Truncate GWC Cache for Layer '%s'." % layer_alternate) + logger.debug(f"Could not Truncate GWC Cache for Layer '{layer_alternate}'.") except Exception: tb = traceback.format_exc() logger.debug(tb) @@ -484,7 +484,7 @@ def set_geofence_all(instance): """ resource = instance.get_self_resource() - logger.debug("Inside set_geofence_all for instance {}".format(instance)) + logger.debug(f"Inside set_geofence_all for instance {instance}") workspace = get_layer_workspace(resource.layer) layer_name = resource.layer.name if resource.layer and hasattr(resource.layer, 'name') \ else resource.layer.alternate.split(":")[0] @@ -508,14 +508,14 @@ def set_geofence_all(instance): access="ALLOW" ) response = requests.post( - url + 'rest/geofence/rules', + f"{url}rest/geofence/rules", headers=headers, data=payload, auth=HTTPBasicAuth(user, passwd) ) if response.status_code not in (200, 201): logger.debug( - "Response {!r} : {}".format(response.status_code, response.text)) + f"Response {response.status_code!r} : {response.text}") raise RuntimeError("Could not ADD GeoServer ANONYMOUS Rule " f"for Layer {layer_name}") except Exception: @@ -612,12 +612,12 @@ def sync_geofence_with_guardian(layer, perms, user=None, group=None, group_perms 'image/gif', 'image/png8' ] - toggle_layer_cache('{}:{}'.format(_layer_workspace, _layer_name), enable=True, filters=filters, formats=formats) + toggle_layer_cache(f'{_layer_workspace}:{_layer_name}', enable=True, filters=filters, formats=formats) for service, allowed in gf_services.items(): if layer and _layer_name and allowed: if _user: - logger.debug("Adding 'user' to geofence the rule: %s %s %s" % (layer, service, _user)) + logger.debug(f"Adding 'user' to geofence the rule: {layer} {service} {_user}") _wkt = None if users_geolimits and users_geolimits.count(): _wkt = users_geolimits.last().wkt @@ -627,7 +627,7 @@ def sync_geofence_with_guardian(layer, perms, user=None, group=None, group_perms service, request=request, user=_user, allow=enabled) _update_geofence_rule(layer, _layer_name, _layer_workspace, service, user=_user, geo_limit=_wkt) elif not _group: - logger.debug("Adding to geofence the rule: %s %s *" % (layer, service)) + logger.debug(f"Adding to geofence the rule: {layer} {service} *") _wkt = None if anonymous_geolimits and anonymous_geolimits.count(): _wkt = anonymous_geolimits.last().wkt @@ -641,7 +641,7 @@ def sync_geofence_with_guardian(layer, perms, user=None, group=None, group_perms _update_geofence_rule(layer, _layer_name, _layer_workspace, service, request=request, user=_user, allow=enabled) if _group: - logger.debug("Adding 'group' to geofence the rule: %s %s %s" % (layer, service, _group)) + logger.debug(f"Adding 'group' to geofence the rule: {layer} {service} {_group}") _wkt = None if groups_geolimits and groups_geolimits.count(): _wkt = groups_geolimits.last().wkt @@ -733,7 +733,7 @@ def _get_geofence_payload(layer, layer_name, workspace, access, user=None, group priority_el.text = str(highest_priority if highest_priority >= 0 else 0) if group is not None: role_el = etree.SubElement(root_el, "roleName") - role_el.text = "ROLE_{}".format(group.upper()) + role_el.text = f"ROLE_{group.upper()}" workspace_el = etree.SubElement(root_el, "workspace") workspace_el.text = workspace layer_el = etree.SubElement(root_el, "layer") @@ -773,10 +773,9 @@ def _update_geofence_rule(layer, layer_name, workspace, request=request, geo_limit=geo_limit ) - logger.debug("request data: {}".format(payload)) + logger.debug(f"request data: {payload}") response = requests.post( - "{base_url}rest/geofence/rules".format( - base_url=settings.OGC_SERVER['default']['LOCATION']), + f"{settings.OGC_SERVER['default']['LOCATION']}rest/geofence/rules", data=payload, headers={ 'Content-type': 'application/xml' @@ -786,10 +785,9 @@ def _update_geofence_rule(layer, layer_name, workspace, password=settings.OGC_SERVER['default']['PASSWORD'] ) ) - logger.debug("response status_code: {}".format(response.status_code)) + logger.debug(f"response status_code: {response.status_code}") if response.status_code not in (200, 201): - msg = ("Could not ADD GeoServer User {!r} Rule for " - "Layer {!r}: '{!r}'".format(user, layer, response.text)) + msg = f"Could not ADD GeoServer User {user!r} Rule for Layer {layer!r}: '{response.text!r}'" if 'Duplicate Rule' in response.text: logger.debug(msg) else: @@ -817,7 +815,7 @@ def sync_resources_with_guardian(resource=None): purge_geofence_layer_rules(r) layer = Layer.objects.get(id=r.id) perm_spec = layer.get_all_level_info() - logger.debug(" %s --------------------------- %s " % (layer, perm_spec)) + logger.debug(f" {layer} --------------------------- {perm_spec} ") # All the other users if 'users' in perm_spec: for user, perms in perm_spec['users'].items(): @@ -836,7 +834,7 @@ def sync_resources_with_guardian(resource=None): r.clear_dirty_state() except Exception as e: logger.exception(e) - logger.warn("!WARNING! - Failure Synching-up Security Rules for Resource [%s]" % (r)) + logger.warn(f"!WARNING! - Failure Synching-up Security Rules for Resource [{r}]") def spec_perms_is_empty(perm_spec): diff --git a/geonode/security/views.py b/geonode/security/views.py index 569eb5d2420..c90e1a02b59 100644 --- a/geonode/security/views.py +++ b/geonode/security/views.py @@ -85,9 +85,7 @@ def resource_permissions_handle_post(request, resource): not view_any: success = False - message = "User {} has download permissions but cannot " \ - "access the resource. Please update permission " \ - "consistently!".format(user.username) + message = f"User {user.username} has download permissions but cannot access the resource. Please update permission consistently!" return HttpResponse( json.dumps({'success': success, 'message': message}), @@ -337,7 +335,7 @@ def attributes_sats_refresh(request): json.dumps( { 'success': 'false', - 'message': 'Error trying to fetch the resource "%s" from GeoServer!' % layer.store + 'message': f'Error trying to fetch the resource "{layer.store}" from GeoServer!' }), status=302, content_type='text/plain') @@ -355,7 +353,7 @@ def attributes_sats_refresh(request): json.dumps( { 'success': 'false', - 'message': 'Exception occurred: "%s"' % str(e) + 'message': f'Exception occurred: "{str(e)}"' }), status=302, content_type='text/plain') diff --git a/geonode/services/management/commands/importservice.py b/geonode/services/management/commands/importservice.py index ddf8fe58f0c..1eb27286208 100644 --- a/geonode/services/management/commands/importservice.py +++ b/geonode/services/management/commands/importservice.py @@ -103,7 +103,7 @@ def handle(self, url, name, type, method, console=sys.stdout, **options): json_response = json.loads(ensure_string(response.content)) if "id" in json_response: - print("Service created with id of {}".format(json_response["id"])) + print(f"Service created with id of {json_response['id']}") service = Service.objects.get(id=json_response["id"]) else: logger.error("Something went wrong: {}".format(ensure_string(response.content))) diff --git a/geonode/services/models.py b/geonode/services/models.py index ba1de3b7259..d275b8f292d 100644 --- a/geonode/services/models.py +++ b/geonode/services/models.py @@ -152,7 +152,7 @@ class Service(ResourceBase): # Supported Capabilities def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" @property def service_url(self): diff --git a/geonode/services/serviceprocessors/arcgis.py b/geonode/services/serviceprocessors/arcgis.py index 07dd5506ccd..537067d24e5 100644 --- a/geonode/services/serviceprocessors/arcgis.py +++ b/geonode/services/serviceprocessors/arcgis.py @@ -221,7 +221,7 @@ def harvest_resource(self, resource_id, geonode_service): self._harvest_resource(layer_meta, geonode_service) else: raise RuntimeError( - "Resource {!r} cannot be harvested".format(resource_id)) + f"Resource {resource_id!r} cannot be harvested") def has_resources(self): try: @@ -232,19 +232,16 @@ def has_resources(self): def _offers_geonode_projection(self, srs): geonode_projection = getattr(settings, "DEFAULT_MAP_CRS", "EPSG:3857") - return geonode_projection in "EPSG:{}".format(srs) + return geonode_projection in f"EPSG:{srs}" def _get_indexed_layer_fields(self, layer_meta): - srs = "EPSG:%s" % layer_meta.extent.spatialReference.wkid + srs = f"EPSG:{layer_meta.extent.spatialReference.wkid}" bbox = utils.decimal_encode([layer_meta.extent.xmin, layer_meta.extent.ymin, layer_meta.extent.xmax, layer_meta.extent.ymax]) - typename = slugify("{}-{}".format( - layer_meta.id, - ''.join(c for c in layer_meta.title if ord(c) < 128) - )) + typename = slugify(f"{layer_meta.id}-{''.join(c for c in layer_meta.title if ord(c) < 128)}") return { "name": layer_meta.title, @@ -297,19 +294,13 @@ def _create_layer_service_link(self, geonode_layer): Link.objects.get_or_create( resource=geonode_layer.resourcebase_ptr, url=geonode_layer.ows_url, - name="ESRI {}: {} Service".format( - geonode_layer.remote_service.type, - geonode_layer.store - ), + name=f"ESRI {geonode_layer.remote_service.type}: {geonode_layer.store} Service", defaults={ "extension": "html", - "name": "ESRI {}: {} Service".format( - geonode_layer.remote_service.type, - geonode_layer.store - ), + "name": f"ESRI {geonode_layer.remote_service.type}: {geonode_layer.store} Service", "url": geonode_layer.ows_url, "mime": "text/html", - "link_type": "ESRI:{}".format(geonode_layer.remote_service.type), + "link_type": f"ESRI:{geonode_layer.remote_service.type}", } ) diff --git a/geonode/services/serviceprocessors/base.py b/geonode/services/serviceprocessors/base.py index 9232ca751ea..2f43329df6e 100644 --- a/geonode/services/serviceprocessors/base.py +++ b/geonode/services/serviceprocessors/base.py @@ -76,7 +76,7 @@ def get_proxified_ows_url(url, version=None, proxy_base=None): urlencode( qd, doseq=True), - safe='') if qd else 'version%3D' + version + '%26request%3DGetCapabilities%26service%3Dwms' + safe='') if qd else f"version%3D{version}%26request%3DGetCapabilities%26service%3Dwms" proxy_base = proxy_base if proxy_base else urljoin( settings.SITEURL, reverse('proxy')) proxified_url = "{proxy_base}?url={ows_url}%3F{ows_request}".format(proxy_base=proxy_base, @@ -93,7 +93,7 @@ def get_geoserver_cascading_workspace(create=True): name = getattr(settings, "CASCADE_WORKSPACE", "cascaded-services") workspace = catalog.get_workspace(name) if workspace is None and create: - uri = "http://www.geonode.org/{}".format(name) + uri = f"http://www.geonode.org/{name}" workspace = catalog.create_workspace(name, uri) return workspace diff --git a/geonode/services/serviceprocessors/handler.py b/geonode/services/serviceprocessors/handler.py index 70295cc9b65..9907a46a0c7 100644 --- a/geonode/services/serviceprocessors/handler.py +++ b/geonode/services/serviceprocessors/handler.py @@ -51,7 +51,7 @@ def get_service_handler(base_url, proxy_base=None, service_type=enumerations.AUT else: to_check = (k for k, v in handlers.items() if v["OWS"]) for type_ in to_check: - logger.debug("Checking {}...".format(type_)) + logger.debug(f"Checking {type_}...") try: service = get_service_handler(base_url, type_) except Exception: @@ -59,14 +59,13 @@ def get_service_handler(base_url, proxy_base=None, service_type=enumerations.AUT else: break else: - raise RuntimeError("Could not parse service {!r} with any of the " - "available service handlers".format(base_url)) + raise RuntimeError(f"Could not parse service {base_url!r} with any of the available service handlers") else: handler = handlers.get(service_type, {}).get("handler") try: service = handler(base_url) except Exception: logger.exception( - msg="Could not parse service {!r}".format(base_url)) + msg=f"Could not parse service {base_url!r}") raise return service diff --git a/geonode/services/serviceprocessors/wms.py b/geonode/services/serviceprocessors/wms.py index 590fd2eb500..875346a2cae 100644 --- a/geonode/services/serviceprocessors/wms.py +++ b/geonode/services/serviceprocessors/wms.py @@ -107,8 +107,7 @@ def WebMapService(url, username=username, password=password, timeout=timeout, headers=headers)) raise NotImplementedError( - 'The WMS version (%s) you requested is not implemented. Please use 1.1.1 or 1.3.0.' % - version) + f'The WMS version ({version}) you requested is not implemented. Please use 1.1.1 or 1.3.0.') class WmsServiceHandler(base.ServiceHandlerBase, @@ -221,7 +220,7 @@ def harvest_resource(self, resource_id, geonode_service): """ layer_meta = self.get_resource(resource_id) - logger.debug("layer_meta: {}".format(layer_meta)) + logger.debug(f"layer_meta: {layer_meta}") if self.indexing_method == CASCADED: logger.debug("About to import cascaded layer...") geoserver_resource = self._import_cascaded_resource(layer_meta) @@ -238,7 +237,7 @@ def harvest_resource(self, resource_id, geonode_service): ) if existance_test_qs.exists(): raise RuntimeError( - "Resource {!r} has already been harvested".format(resource_id)) + f"Resource {resource_id!r} has already been harvested") resource_fields["keywords"] = keywords resource_fields["is_approved"] = True resource_fields["is_published"] = True @@ -311,9 +310,8 @@ def _create_layer_legend_link(self, geonode_layer): "fontAntiAliasing:true;fontSize:12;forceLabels:on") } kvp = "&".join("{}={}".format(*item) for item in params.items()) - legend_url = "{}{}{}".format( - geonode_layer.remote_service.service_url, _q_separator, kvp) - logger.debug("legend_url: {}".format(legend_url)) + legend_url = f"{geonode_layer.remote_service.service_url}{_q_separator}{kvp}" + logger.debug(f"legend_url: {legend_url}") Link.objects.get_or_create( resource=geonode_layer.resourcebase_ptr, url=legend_url, @@ -329,7 +327,7 @@ def _create_layer_legend_link(self, geonode_layer): def _create_layer_service_link(self, geonode_layer): ogc_wms_url = geonode_layer.ows_url - ogc_wms_name = 'OGC WMS: %s Service' % geonode_layer.store + ogc_wms_name = f'OGC WMS: {geonode_layer.store} Service' ogc_wms_link_type = 'OGC:WMS' if Link.objects.filter(resource=geonode_layer.resourcebase_ptr, name=ogc_wms_name, @@ -351,13 +349,13 @@ def _get_cascaded_layer_fields(self, geoserver_resource): workspace = geoserver_resource.workspace.name if hasattr(geoserver_resource, 'workspace') else None store = geoserver_resource.store if hasattr(geoserver_resource, 'store') else None bbox = utils.decimal_encode(geoserver_resource.native_bbox) if hasattr(geoserver_resource, 'native_bbox') else \ - utils.decimal_encode(geoserver_resource.boundingBox) + utils.decimal_encode(geoserver_resource.boundingBox) return { "name": name, "workspace": workspace or "remoteWorkspace", "store": store.name if store and hasattr(store, 'name') else self.name, - "typename": "{}:{}".format(workspace, name) if workspace not in name else name, - "alternate": "{}:{}".format(workspace, name) if workspace not in name else name, + "typename": f"{workspace}:{name}" if workspace not in name else name, + "alternate": f"{workspace}:{name}" if workspace not in name else name, "storeType": "remoteStore", "title": geoserver_resource.title, "abstract": geoserver_resource.abstract, @@ -398,8 +396,8 @@ def _get_store(self, create=True): workspace = base.get_geoserver_cascading_workspace(create=create) cat = workspace.catalog store = cat.get_store(self.name, workspace=workspace) - logger.debug("name: {}".format(self.name)) - logger.debug("store: {}".format(store)) + logger.debug(f"name: {self.name}") + logger.debug(f"store: {store}") if store is None and create: # store did not exist. Create it store = cat.create_wmsstore( name=self.name, @@ -429,12 +427,10 @@ def _import_cascaded_resource(self, layer_meta): layer_resource.projection_policy = "REPROJECT_TO_DECLARED" cat.save(layer_resource) if layer_resource is None: - raise RuntimeError("Could not cascade resource {!r} through " - "geoserver".format(layer_meta)) + raise RuntimeError(f"Could not cascade resource {layer_meta!r} through geoserver") layer_resource = layer_resource.resource else: - logger.debug("Layer {} is already present. Skipping...".format( - layer_meta.id)) + logger.debug(f"Layer {layer_meta.id} is already present. Skipping...") layer_resource.refresh() return layer_resource @@ -520,7 +516,7 @@ def harvest_resource(self, resource_id, geonode_service): ) if existance_test_qs.exists(): raise RuntimeError( - "Resource {!r} has already been harvested".format(resource_id)) + f"Resource {resource_id!r} has already been harvested") resource_fields["keywords"] = keywords resource_fields["is_approved"] = True resource_fields["is_published"] = True @@ -537,9 +533,9 @@ def harvest_resource(self, resource_id, geonode_service): def _probe_geonode_wms(self, raw_url): url = urlsplit(raw_url) - base_url = '%s://%s/' % (url.scheme, url.netloc) + base_url = f'{url.scheme}://{url.netloc}/' response = requests.get( - '%sapi/ows_endpoints/' % base_url, {}, + f'{base_url}api/ows_endpoints/', {}, timeout=30, verify=False) content = response.content @@ -554,21 +550,21 @@ def _probe_geonode_wms(self, raw_url): data = _json_obj['data'] for ows_endpoint in data: if 'OGC:OWS' == ows_endpoint['type']: - return ows_endpoint['url'] + '?' + url.query + return f"{ows_endpoint['url']}?{url.query}" except Exception: pass # OLD-style not OWS Enabled GeoNode - _url = "%s://%s/geoserver/ows" % (url.scheme, url.netloc) + _url = f"{url.scheme}://{url.netloc}/geoserver/ows" return _url def _enrich_layer_metadata(self, geonode_layer): workspace, layername = geonode_layer.name.split( ":") if ":" in geonode_layer.name else (None, geonode_layer.name) url = urlsplit(self.url) - base_url = '%s://%s/' % (url.scheme, url.netloc) + base_url = f'{url.scheme}://{url.netloc}/' response = requests.get( - '%sapi/layers/?name=%s' % (base_url, layername), {}, + f'{base_url}api/layers/?name={layername}', {}, timeout=10, verify=False) content = response.content @@ -600,20 +596,19 @@ def _enrich_layer_metadata(self, geonode_layer): thumbnail_remote_url = _layer["thumbnail_url"] _url = urlsplit(thumbnail_remote_url) if not _url.scheme: - thumbnail_remote_url = "{}{}".format( - geonode_layer.remote_service.service_url, _url.path) + thumbnail_remote_url = f"{geonode_layer.remote_service.service_url}{_url.path}" resp, image = http_client.request( thumbnail_remote_url) if 'ServiceException' in str(image) or \ resp.status_code < 200 or resp.status_code > 299: - msg = 'Unable to obtain thumbnail: %s' % image + msg = f'Unable to obtain thumbnail: {image}' logger.debug(msg) # Replace error message with None. image = None if image is not None: - thumbnail_name = 'layer-%s-thumb.png' % geonode_layer.uuid + thumbnail_name = f'layer-{geonode_layer.uuid}-thumb.png' geonode_layer.save_thumbnail( thumbnail_name, image=image) else: diff --git a/geonode/services/signals.py b/geonode/services/signals.py index db6c16f6aea..4bfd2658cca 100644 --- a/geonode/services/signals.py +++ b/geonode/services/signals.py @@ -45,7 +45,7 @@ def remove_harvest_job(sender, **kwargs): resource_id = layer.alternate.split(":")[1] if re.match(f'^{workspace.name}:', resource_id) else layer.alternate if HarvestJob.objects.filter(resource_id=resource_id): for job in HarvestJob.objects.filter(resource_id=resource_id, service=layer.remote_service): - logger.debug("job: {}".format(job.id)) + logger.debug(f"job: {job.id}") job.delete() else: pass # layer was not harvested from a service, we've nothing to do diff --git a/geonode/services/tasks.py b/geonode/services/tasks.py index 1a550f231b5..2511de9996a 100644 --- a/geonode/services/tasks.py +++ b/geonode/services/tasks.py @@ -91,8 +91,7 @@ def harvest_resource(self, harvest_job_id): f"tentative {_cnt}: {e}") time.sleep(1.0) except Exception as err: - logger.exception(msg="An error has occurred while harvesting " - "resource {!r}".format(harvest_job.resource_id)) + logger.exception(msg=f"An error has occurred while harvesting resource {harvest_job.resource_id!r}") details = str(err) # TODO: pass more context about the error finally: if not details: diff --git a/geonode/services/test_selenium.py b/geonode/services/test_selenium.py index 96d5d55ebf1..e523099e9a1 100644 --- a/geonode/services/test_selenium.py +++ b/geonode/services/test_selenium.py @@ -26,7 +26,7 @@ def setUpClass(cls): cls.cookie = cls.client.cookies['sessionid'] cls.selenium = webdriver.Firefox() cls.selenium.implicitly_wait(10) - cls.selenium.get(cls.live_server_url + '/') + cls.selenium.get(f"{cls.live_server_url}/") cls.selenium.add_cookie({'name': 'sessionid', 'value': cls.cookie.value, 'secure': False, 'path': '/'}) cls.selenium.refresh() reg_url = reverse('register_service') diff --git a/geonode/services/tests.py b/geonode/services/tests.py index 4aaf8a1bbe7..62700fa2649 100644 --- a/geonode/services/tests.py +++ b/geonode/services/tests.py @@ -101,7 +101,7 @@ def test_get_cascading_workspace_creates_new_workspace(self, mock_settings, cat.get_workspace.assert_called_with(mock_settings.CASCADE_WORKSPACE) cat.create_workspace.assert_called_with( mock_settings.CASCADE_WORKSPACE, - "http://www.geonode.org/{}".format(mock_settings.CASCADE_WORKSPACE) + f"http://www.geonode.org/{mock_settings.CASCADE_WORKSPACE}" ) @mock.patch("geonode.services.serviceprocessors.handler.WmsServiceHandler", @@ -784,7 +784,7 @@ def setUpClass(cls): cls.cookie = cls.client.cookies['sessionid'] cls.selenium = webdriver.Firefox() cls.selenium.implicitly_wait(10) - cls.selenium.get(cls.live_server_url + '/') + cls.selenium.get(f"{cls.live_server_url}/") cls.selenium.add_cookie({'name': 'sessionid', 'value': cls.cookie.value, 'secure': False, 'path': '/'}) cls.selenium.refresh() reg_url = reverse('register_service') diff --git a/geonode/services/utils.py b/geonode/services/utils.py index 2d0cb439ed7..0847b232940 100644 --- a/geonode/services/utils.py +++ b/geonode/services/utils.py @@ -26,7 +26,7 @@ def flip_coordinates(c1, c2): if c1 > c2: - logger.debug('Flipping coordinates %s, %s' % (c1, c2)) + logger.debug(f'Flipping coordinates {c1}, {c2}') temp = c1 c1 = c2 c2 = temp @@ -54,8 +54,7 @@ def bbox2wktpolygon(bbox): miny = float(bbox[1]) maxx = float(bbox[2]) maxy = float(bbox[3]) - return 'POLYGON((%.2f %.2f, %.2f %.2f, %.2f %.2f, %.2f %.2f, %.2f %.2f))' \ - % (minx, miny, minx, maxy, maxx, maxy, maxx, miny, minx, miny) + return f'POLYGON(({minx:.2f} {miny:.2f}, {minx:.2f} {maxy:.2f}, {maxx:.2f} {maxy:.2f}, {maxx:.2f} {miny:.2f}, {minx:.2f} {miny:.2f}))' def inverse_mercator(xy): diff --git a/geonode/services/views.py b/geonode/services/views.py index 18676a8d69c..dda3aeef0c5 100644 --- a/geonode/services/views.py +++ b/geonode/services/views.py @@ -56,8 +56,7 @@ def service_proxy(request, service_id): if not service.proxy_base: service_url = service.base_url else: - service_url = "{ows_url}?{ows_request}".format( - ows_url=service.base_url, ows_request=request.META['QUERY_STRING']) + service_url = f"{service.base_url}?{request.META['QUERY_STRING']}" if urljoin(settings.SITEURL, reverse('proxy')) != service.proxy_base: service_url = "{proxy_base}?url={service_url}".format(proxy_base=service.proxy_base, service_url=quote(service_url, safe='')) @@ -182,7 +181,7 @@ def harvest_resources(request, service_id): requested = list(set(requested)) resources_to_harvest = [] for id in _gen_harvestable_ids(requested, available_resources): - logger.debug("id: {}".format(id)) + logger.debug(f"id: {id}") harvest_job, created = HarvestJob.objects.get_or_create( service=service, resource_id=id @@ -192,7 +191,7 @@ def harvest_resources(request, service_id): tasks.harvest_resource.apply_async((harvest_job.id,)) else: logger.warning( - "resource {} already has a harvest job".format(id)) + f"resource {id} already has a harvest job") msg_async = _("The selected resources are being imported") msg_sync = _("The selected resources have been imported") messages.add_message( @@ -230,7 +229,7 @@ def harvest_single_resource(request, service_id, resource_id): messages.add_message( request, messages.SUCCESS, - _("Resource {} is being processed".format(resource_id)) + _(f"Resource {resource_id} is being processed") ) return redirect( reverse("service_detail", @@ -368,6 +367,6 @@ def remove_service(request, service_id): messages.add_message( request, messages.INFO, - _("Service {} has been deleted".format(service.name)) + _(f"Service {service.name} has been deleted") ) return HttpResponseRedirect(reverse("services")) diff --git a/geonode/settings.py b/geonode/settings.py index 072d5754d06..71bc3cf2a70 100644 --- a/geonode/settings.py +++ b/geonode/settings.py @@ -88,9 +88,7 @@ SITE_HOST_SCHEMA = os.getenv('SITE_HOST_SCHEMA', 'http') SITE_HOST_NAME = os.getenv('SITE_HOST_NAME', 'localhost') SITE_HOST_PORT = os.getenv('SITE_HOST_PORT', 8000) -_default_siteurl = "%s://%s:%s/" % (SITE_HOST_SCHEMA, - SITE_HOST_NAME, - SITE_HOST_PORT) if SITE_HOST_PORT else "%s://%s/" % (SITE_HOST_SCHEMA, SITE_HOST_NAME) +_default_siteurl = f"{SITE_HOST_SCHEMA}://{SITE_HOST_NAME}:{SITE_HOST_PORT}/" if SITE_HOST_PORT else f"{SITE_HOST_SCHEMA}://{SITE_HOST_NAME}/" SITEURL = os.getenv('SITEURL', _default_siteurl) # we need hostname for deployed @@ -99,7 +97,7 @@ # add trailing slash to site url. geoserver url will be relative to this if not SITEURL.endswith('/'): - SITEURL = '{}/'.format(SITEURL) + SITEURL = f'{SITEURL}/' DATABASE_URL = os.getenv( 'DATABASE_URL', @@ -281,8 +279,8 @@ # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). # Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = os.getenv('MEDIA_URL', '%s/%s/' % (FORCE_SCRIPT_NAME, MEDIAFILES_LOCATION)) -LOCAL_MEDIA_URL = os.getenv('LOCAL_MEDIA_URL', '%s/%s/' % (FORCE_SCRIPT_NAME, MEDIAFILES_LOCATION)) +MEDIA_URL = os.getenv('MEDIA_URL', f'{FORCE_SCRIPT_NAME}/{MEDIAFILES_LOCATION}/') +LOCAL_MEDIA_URL = os.getenv('LOCAL_MEDIA_URL', f'{FORCE_SCRIPT_NAME}/{MEDIAFILES_LOCATION}/') # Absolute path to the directory that holds static files like app media. # Example: "/home/media/media.lawrence.com/apps/" @@ -292,7 +290,7 @@ # URL that handles the static files like app media. # Example: "http://media.lawrence.com" -STATIC_URL = os.getenv('STATIC_URL', '%s/%s/' % (FORCE_SCRIPT_NAME, STATICFILES_LOCATION)) +STATIC_URL = os.getenv('STATIC_URL', f'{FORCE_SCRIPT_NAME}/{STATICFILES_LOCATION}/') # Additional directories which hold static files _DEFAULT_STATICFILES_DIRS = [ @@ -319,18 +317,17 @@ AWS_STORAGE_BUCKET_NAME = os.environ.get('S3_BUCKET_NAME', '') AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', '') AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', '') -AWS_S3_BUCKET_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME +AWS_S3_BUCKET_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com' AWS_QUERYSTRING_AUTH = False if not DEBUG and S3_STATIC_ENABLED: STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' - STATIC_URL = "https://%s/%s/" % (AWS_S3_BUCKET_DOMAIN, - STATICFILES_LOCATION) + STATIC_URL = f"https://{AWS_S3_BUCKET_DOMAIN}/{STATICFILES_LOCATION}/" if not DEBUG and S3_MEDIA_ENABLED: MEDIAFILES_LOCATION = 'media' DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' - MEDIA_URL = "https://%s/%s/" % (AWS_S3_BUCKET_DOMAIN, MEDIAFILES_LOCATION) + MEDIA_URL = f"https://{AWS_S3_BUCKET_DOMAIN}/{MEDIAFILES_LOCATION}/" # Cache Bustin Settings CACHE_BUSTING_STATIC_ENABLED = ast.literal_eval(os.environ.get('CACHE_BUSTING_STATIC_ENABLED', 'False')) @@ -695,7 +692,7 @@ # This middleware checks for ACCESS_TOKEN validity and if expired forces # user logout MIDDLEWARE += \ - ('geonode.security.middleware.SessionControlMiddleware',) + ('geonode.security.middleware.SessionControlMiddleware',) SESSION_COOKIE_SECURE = ast.literal_eval(os.environ.get('SESSION_COOKIE_SECURE', 'False')) CSRF_COOKIE_SECURE = ast.literal_eval(os.environ.get('CSRF_COOKIE_SECURE', 'False')) @@ -776,16 +773,16 @@ # - authorized exempt urls needed for oauth when GeoNode is set to lockdown AUTH_EXEMPT_URLS = ( r'^%s/?$' % FORCE_SCRIPT_NAME, - '%s/o/*' % FORCE_SCRIPT_NAME, - '%s/gs/*' % FORCE_SCRIPT_NAME, - '%s/account/*' % FORCE_SCRIPT_NAME, - '%s/static/*' % FORCE_SCRIPT_NAME, - '%s/api/o/*' % FORCE_SCRIPT_NAME, - '%s/api/roles' % FORCE_SCRIPT_NAME, - '%s/api/adminRole' % FORCE_SCRIPT_NAME, - '%s/api/users' % FORCE_SCRIPT_NAME, - '%s/api/layers' % FORCE_SCRIPT_NAME, - '%s/monitoring' % FORCE_SCRIPT_NAME, + f'{FORCE_SCRIPT_NAME}/o/*', + f'{FORCE_SCRIPT_NAME}/gs/*', + f'{FORCE_SCRIPT_NAME}/account/*', + f'{FORCE_SCRIPT_NAME}/static/*', + f'{FORCE_SCRIPT_NAME}/api/o/*', + f'{FORCE_SCRIPT_NAME}/api/roles', + f'{FORCE_SCRIPT_NAME}/api/adminRole', + f'{FORCE_SCRIPT_NAME}/api/users', + f'{FORCE_SCRIPT_NAME}/api/layers', + f'{FORCE_SCRIPT_NAME}/monitoring', r'^/i18n/setlang/?$', ) @@ -847,8 +844,8 @@ # per-deployment settings should go here # Login and logout urls override -LOGIN_URL = os.getenv('LOGIN_URL', '{}account/login/'.format(SITEURL)) -LOGOUT_URL = os.getenv('LOGOUT_URL', '{}account/logout/'.format(SITEURL)) +LOGIN_URL = os.getenv('LOGIN_URL', f'{SITEURL}account/login/') +LOGOUT_URL = os.getenv('LOGOUT_URL', f'{SITEURL}account/logout/') ACCOUNT_LOGIN_REDIRECT_URL = os.getenv('LOGIN_REDIRECT_URL', SITEURL) ACCOUNT_LOGOUT_REDIRECT_URL = os.getenv('LOGOUT_REDIRECT_URL', SITEURL) @@ -877,8 +874,8 @@ # add trailing slash to geoserver location url. if not GEOSERVER_LOCATION.endswith('/'): - GEOSERVER_LOCATION = '{}/'.format(GEOSERVER_LOCATION) - + GEOSERVER_LOCATION = f'{GEOSERVER_LOCATION}/' + GEOSERVER_PUBLIC_SCHEMA = os.getenv( 'GEOSERVER_PUBLIC_SCHEMA', SITE_HOST_SCHEMA ) @@ -894,7 +891,7 @@ _default_public_location = '{}://{}:{}/geoserver/'.format( GEOSERVER_PUBLIC_SCHEMA, GEOSERVER_PUBLIC_HOST, - GEOSERVER_PUBLIC_PORT) if GEOSERVER_PUBLIC_PORT else '{}://{}/geoserver/'.format(GEOSERVER_PUBLIC_SCHEMA, GEOSERVER_PUBLIC_HOST) + GEOSERVER_PUBLIC_PORT) if GEOSERVER_PUBLIC_PORT else f'{GEOSERVER_PUBLIC_SCHEMA}://{GEOSERVER_PUBLIC_HOST}/geoserver/' GEOSERVER_PUBLIC_LOCATION = os.getenv( 'GEOSERVER_PUBLIC_LOCATION', _default_public_location @@ -912,7 +909,8 @@ 'GEOSERVER_ADMIN_PASSWORD', 'geoserver' ) -GEOFENCE_SECURITY_ENABLED = False if TEST and not INTEGRATION else ast.literal_eval(os.getenv('GEOFENCE_SECURITY_ENABLED', 'True')) +GEOFENCE_SECURITY_ENABLED = False if TEST and not INTEGRATION else ast.literal_eval( + os.getenv('GEOFENCE_SECURITY_ENABLED', 'True')) # OGC (WMS/WFS/WCS) Server Settings # OGC (WMS/WFS/WCS) Server Settings @@ -937,8 +935,7 @@ 'WMST_ENABLED': ast.literal_eval(os.getenv('WMST_ENABLED', 'False')), 'BACKEND_WRITE_ENABLED': ast.literal_eval(os.getenv('BACKEND_WRITE_ENABLED', 'True')), 'WPS_ENABLED': ast.literal_eval(os.getenv('WPS_ENABLED', 'False')), - 'LOG_FILE': '%s/geoserver/data/logs/geoserver.log' - % os.path.abspath(os.path.join(PROJECT_ROOT, os.pardir)), + 'LOG_FILE': f'{os.path.abspath(os.path.join(PROJECT_ROOT, os.pardir))}/geoserver/data/logs/geoserver.log', # Set to name of database in DATABASES dictionary to enable # 'datastore', 'DATASTORE': os.getenv('DEFAULT_BACKEND_DATASTORE', ''), @@ -1165,7 +1162,7 @@ # # AUTH_IP_WHITELIST = ['192.168.1.158', '192.168.1.159'] AUTH_IP_WHITELIST = [HOSTNAME, 'localhost', 'django', 'geonode'] if os.getenv('AUTH_IP_WHITELIST') is None \ - else re.split(r' *[,|:|;] *', os.getenv('AUTH_IP_WHITELIST')) + else re.split(r' *[,|:|;] *', os.getenv('AUTH_IP_WHITELIST')) # A tuple of hosts the proxy can send requests to. try: @@ -1173,8 +1170,16 @@ PROXY_ALLOWED_HOSTS = ast.literal_eval(os.getenv('PROXY_ALLOWED_HOSTS')) except ValueError: # fallback to regular list of values separated with misc chars - PROXY_ALLOWED_HOSTS = [HOSTNAME, 'localhost', 'django', 'geonode', 'spatialreference.org', 'nominatim.openstreetmap.org', 'dev.openlayers.org'] if os.getenv('PROXY_ALLOWED_HOSTS') is None \ - else re.split(r' *[,|:|;] *', os.getenv('PROXY_ALLOWED_HOSTS')) + PROXY_ALLOWED_HOSTS = [ + HOSTNAME, + 'localhost', + 'django', + 'geonode', + 'spatialreference.org', + 'nominatim.openstreetmap.org', + 'dev.openlayers.org'] if os.getenv('PROXY_ALLOWED_HOSTS') is None else re.split( + r' *[,|:|;] *', + os.getenv('PROXY_ALLOWED_HOSTS')) # The proxy to use when making cross origin requests. PROXY_URL = os.environ.get('PROXY_URL', '/proxy/?url=') @@ -1254,10 +1259,10 @@ except ValueError: # fallback to regular list of values separated with misc chars AVATAR_PROVIDERS = ( - 'avatar.providers.PrimaryAvatarProvider', - 'avatar.providers.GravatarAvatarProvider', - 'avatar.providers.DefaultAvatarProvider' - ) if os.getenv('AVATAR_PROVIDERS') is None \ + 'avatar.providers.PrimaryAvatarProvider', + 'avatar.providers.GravatarAvatarProvider', + 'avatar.providers.DefaultAvatarProvider' + ) if os.getenv('AVATAR_PROVIDERS') is None \ else re.split(r' *[,|:|;] *', os.getenv('AVATAR_PROVIDERS')) # Number of results per page listed in the GeoNode search pages @@ -1437,15 +1442,15 @@ def get_geonode_catalogue_service(): if PYCSW: pycsw_config = PYCSW["CONFIGURATION"] if pycsw_config: - pycsw_catalogue = { - ("%s" % pycsw_config['metadata:main']['identification_title']): { - "url": CATALOGUE['default']['URL'], - "type": "csw", - "title": pycsw_config['metadata:main']['identification_title'], - "autoload": True - } + pycsw_catalogue = { + f"{pycsw_config['metadata:main']['identification_title']}": { + "url": CATALOGUE['default']['URL'], + "type": "csw", + "title": pycsw_config['metadata:main']['identification_title'], + "autoload": True } - return pycsw_catalogue + } + return pycsw_catalogue return None GEONODE_CATALOGUE_SERVICE = get_geonode_catalogue_service() @@ -1456,7 +1461,7 @@ def get_geonode_catalogue_service(): "type": "wms", "title": "Demo WMS Service", "autoload": False - }, + }, "Demo WMTS Service": { "url": "https://demo.geo-solutions.it/geoserver/gwc/service/wmts", "type": "wmts", @@ -1468,7 +1473,8 @@ def get_geonode_catalogue_service(): MAPSTORE_CATALOGUE_SELECTED_SERVICE = "Demo WMS Service" if GEONODE_CATALOGUE_SERVICE: - MAPSTORE_CATALOGUE_SERVICES[list(list(GEONODE_CATALOGUE_SERVICE.keys()))[0]] = GEONODE_CATALOGUE_SERVICE[list(list(GEONODE_CATALOGUE_SERVICE.keys()))[0]] + MAPSTORE_CATALOGUE_SERVICES[list(list(GEONODE_CATALOGUE_SERVICE.keys()))[0] + ] = GEONODE_CATALOGUE_SERVICE[list(list(GEONODE_CATALOGUE_SERVICE.keys()))[0]] MAPSTORE_CATALOGUE_SELECTED_SERVICE = list(list(GEONODE_CATALOGUE_SERVICE.keys()))[0] DEFAULT_MS2_BACKGROUNDS = [ @@ -1495,9 +1501,9 @@ def get_geonode_catalogue_service(): "name": "s2cloudless:s2cloudless", "url": "https://maps.geo-solutions.it/geoserver/wms", "group": "background", - "thumbURL": "%sstatic/mapstorestyle/img/s2cloudless-s2cloudless.png" % SITEURL, + "thumbURL": f"{SITEURL}static/mapstorestyle/img/s2cloudless-s2cloudless.png", "visibility": False - }, { + }, { "source": "ol", "group": "background", "id": "none", @@ -1506,8 +1512,8 @@ def get_geonode_catalogue_service(): "type": "empty", "visibility": False, "args": ["Empty Background", {"visibility": False}] - } - # Custom XYZ Tile Provider + } + # Custom XYZ Tile Provider # { # "type": "tileprovider", # "title": "Title", @@ -1528,13 +1534,12 @@ def get_geonode_catalogue_service(): "title": "MapBox streets-v11", "provider": "MapBoxStyle", "name": "MapBox streets-v11", - "accessToken": "%s" % MAPBOX_ACCESS_TOKEN, + "accessToken": f"{MAPBOX_ACCESS_TOKEN}", "source": "streets-v11", - "thumbURL": "https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/6/33/23?access_token=%s" % MAPBOX_ACCESS_TOKEN, + "thumbURL": f"https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/6/33/23?access_token={MAPBOX_ACCESS_TOKEN}", "group": "background", - "visibility": True - } - DEFAULT_MS2_BACKGROUNDS = [BASEMAP,] + DEFAULT_MS2_BACKGROUNDS + "visibility": True} + DEFAULT_MS2_BACKGROUNDS = [BASEMAP, ] + DEFAULT_MS2_BACKGROUNDS if BING_API_KEY: BASEMAP = { @@ -1546,7 +1551,7 @@ def get_geonode_catalogue_service(): "apiKey": "{{apiKey}}", "visibility": False } - DEFAULT_MS2_BACKGROUNDS = [BASEMAP,] + DEFAULT_MS2_BACKGROUNDS + DEFAULT_MS2_BACKGROUNDS = [BASEMAP, ] + DEFAULT_MS2_BACKGROUNDS MAPSTORE_BASELAYERS = DEFAULT_MS2_BACKGROUNDS @@ -1570,47 +1575,38 @@ def get_geonode_catalogue_service(): } # HTML WYSIWYG Editor (TINYMCE) Menu Bar Settings -TINYMCE_DEFAULT_CONFIG = { - "theme": "silver", - "height": 500, - "plugins": 'print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern noneditable help charmap quickbars emoticons', - "imagetools_cors_hosts": ['picsum.photos'], - "menubar": 'file edit view insert format tools table help', - "toolbar": 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save | insertfile image media template link anchor codesample | ltr rtl', - "toolbar_sticky": "true", - "autosave_ask_before_unload": "true", - "autosave_interval": "30s", - "autosave_prefix": "{path}{query}-{id}-", - "autosave_restore_when_empty": "false", - "autosave_retention": "2m", - "image_advtab": "true", - "content_css": '//www.tiny.cloud/css/codepen.min.css', - "importcss_append": "true", - "image_caption": "true", - "quickbars_selection_toolbar": 'bold italic | quicklink h2 h3 blockquote quickimage quicktable', - "noneditable_noneditable_class": "mceNonEditable", - "toolbar_mode": 'sliding', - "contextmenu": "link image imagetools table", - "templates": [ - { - "title": 'New Table', - "description": 'creates a new table', - "content": '
' - }, - { - "title": 'Starting my story', - "description": 'A cure for writers block', - "content": 'Once upon a time...' - }, - { - "title": 'New list with dates', - "description": 'New List with dates', - "content": '
cdate
mdate

My List

' - } - ], - "template_cdate_format": '[Date Created (CDATE): %m/%d/%Y : %H:%M:%S]', - "template_mdate_format": '[Date Modified (MDATE): %m/%d/%Y : %H:%M:%S]', -} +TINYMCE_DEFAULT_CONFIG = {"theme": "silver", + "height": 500, + "plugins": 'print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern noneditable help charmap quickbars emoticons', + "imagetools_cors_hosts": ['picsum.photos'], + "menubar": 'file edit view insert format tools table help', + "toolbar": 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save | insertfile image media template link anchor codesample | ltr rtl', + "toolbar_sticky": "true", + "autosave_ask_before_unload": "true", + "autosave_interval": "30s", + "autosave_prefix": "{path}{query}-{id}-", + "autosave_restore_when_empty": "false", + "autosave_retention": "2m", + "image_advtab": "true", + "content_css": '//www.tiny.cloud/css/codepen.min.css', + "importcss_append": "true", + "image_caption": "true", + "quickbars_selection_toolbar": 'bold italic | quicklink h2 h3 blockquote quickimage quicktable', + "noneditable_noneditable_class": "mceNonEditable", + "toolbar_mode": 'sliding', + "contextmenu": "link image imagetools table", + "templates": [{"title": 'New Table', + "description": 'creates a new table', + "content": '
'}, + {"title": 'Starting my story', + "description": 'A cure for writers block', + "content": 'Once upon a time...'}, + {"title": 'New list with dates', + "description": 'New List with dates', + "content": '
cdate
mdate

My List

'}], + "template_cdate_format": '[Date Created (CDATE): %m/%d/%Y : %H:%M:%S]', + "template_mdate_format": '[Date Modified (MDATE): %m/%d/%Y : %H:%M:%S]', + } # Make Free-Text Kaywords writable from users or read-only # - if True only admins can edit free-text kwds from admin dashboard @@ -1662,7 +1658,7 @@ def get_geonode_catalogue_service(): 'CELERY_RESULT_BACKEND_PATH', os.path.join(PROJECT_ROOT, '.celery_results')) if not os.path.exists(CELERY_RESULT_BACKEND_PATH): os.makedirs(CELERY_RESULT_BACKEND_PATH) - CELERY_RESULT_BACKEND = 'file:///%s' % CELERY_RESULT_BACKEND_PATH + CELERY_RESULT_BACKEND = f'file:///{CELERY_RESULT_BACKEND_PATH}' CELERY_BROKER_URL = os.environ.get('BROKER_URL', _BROKER_URL) CELERY_RESULT_PERSISTENT = ast.literal_eval(os.environ.get('CELERY_RESULT_PERSISTENT', 'False')) @@ -1855,7 +1851,7 @@ def get_geonode_catalogue_service(): 3. Superusers can do enything. - if [ GROUP_PRIVATE_RESOURCES == True ] - The "unapproved" and "unpublished" Resources will be accessible **ONLY** by owners, superusers and member of + The "unapproved" and "unpublished" Resources will be accessible **ONLY** by owners, superusers and member of the belonging groups. - if [ GROUP_MANDATORY_RESOURCES == True ] @@ -1905,7 +1901,7 @@ def get_geonode_catalogue_service(): SOCIALACCOUNT_ADAPTER = 'geonode.people.adapters.SocialAccountAdapter' SOCIALACCOUNT_AUTO_SIGNUP = ast.literal_eval(os.environ.get('SOCIALACCOUNT_AUTO_SIGNUP', 'True')) -#This will hide or show local registration form in allauth view. True will show form +# This will hide or show local registration form in allauth view. True will show form SOCIALACCOUNT_WITH_GEONODE_LOCAL_SINGUP = strtobool(os.environ.get('SOCIALACCOUNT_WITH_GEONODE_LOCAL_SINGUP', 'True')) # Uncomment this to enable Linkedin and Facebook login @@ -1985,16 +1981,16 @@ def get_geonode_catalogue_service(): PUBLIC_GEOSERVER = { "source": { "title": "GeoServer - Public Layers", - "attribution": "© %s" % SITEURL, + "attribution": f"© {SITEURL}", "ptype": LOCAL_GXP_PTYPE, - "url": OGC_SERVER['default']['PUBLIC_LOCATION'] + "ows", + "url": f"{OGC_SERVER['default']['PUBLIC_LOCATION']}ows", "restUrl": "/gs/rest" } } LOCAL_GEOSERVER = { "source": { "title": "GeoServer - Private Layers", - "attribution": "© %s" % SITEURL, + "attribution": f"© {SITEURL}", "ptype": LOCAL_GXP_PTYPE, "url": "/gs/ows", "restUrl": "/gs/rest" @@ -2055,7 +2051,6 @@ def get_geonode_catalogue_service(): USER_ANALYTICS_GZIP = ast.literal_eval(os.getenv('USER_ANALYTICS_GZIP', 'False')) GEOIP_PATH = os.getenv('GEOIP_PATH', os.path.join(PROJECT_ROOT, 'GeoIPCities.dat')) -#This controls if tastypie search on resourches is performed only with titles +# This controls if tastypie search on resourches is performed only with titles SEARCH_RESOURCES_EXTENDED = strtobool(os.getenv('SEARCH_RESOURCES_EXTENDED', 'True')) # -- END Settings for MONITORING plugin - diff --git a/geonode/social/signals.py b/geonode/social/signals.py index 3e3b5118f0c..14fdcffc207 100644 --- a/geonode/social/signals.py +++ b/geonode/social/signals.py @@ -119,8 +119,8 @@ def activity_post_modify_object(sender, instance, created=None, **kwargs): if created is False: # object was saved. if not isinstance(instance, Layer) and \ - not isinstance(instance, Document) and \ - not isinstance(instance, Map): + not isinstance(instance, Document) and \ + not isinstance(instance, Map): verb = action.get('updated_verb') raw_action = 'updated' @@ -136,7 +136,7 @@ def activity_post_modify_object(sender, instance, created=None, **kwargs): if verb: try: activity.send(action.get('actor'), - verb="{verb}".format(verb=verb), + verb=f"{verb}", action_object=action.get('action_object'), target=action.get('target', None), object_name=action.get('object_name'), @@ -175,7 +175,7 @@ def relationship_post_save(instance, sender, created, **kwargs): def rating_post_save(instance, sender, created, **kwargs): """ Send a notification when rating a layer, map or document """ - notice_type_label = '%s_rated' % instance.content_object.class_name.lower() + notice_type_label = f'{instance.content_object.class_name.lower()}_rated' recipients = get_notification_recipients(notice_type_label, instance.user, resource=instance.content_object) @@ -188,7 +188,7 @@ def comment_post_save(instance, sender, created, **kwargs): """ Send a notification when a comment to a layer, map or document has been submitted """ - notice_type_label = '%s_comment' % instance.content_type.model.lower() + notice_type_label = f'{instance.content_type.model.lower()}_comment' recipients = get_comment_notification_recipients(notice_type_label, instance.author, resource=instance.content_object) diff --git a/geonode/social/templatetags/social_tags.py b/geonode/social/templatetags/social_tags.py index a72decafe87..f142fc72091 100644 --- a/geonode/social/templatetags/social_tags.py +++ b/geonode/social/templatetags/social_tags.py @@ -90,7 +90,7 @@ def activity_item(action, **kwargs): activity_class = 'delete' if raw_action == 'created' and \ - object_type in ('layer', 'document'): + object_type in ('layer', 'document'): activity_class = 'upload' ctx = dict( diff --git a/geonode/social/views.py b/geonode/social/views.py index 208c16b23e5..cea7fbee6f2 100644 --- a/geonode/social/views.py +++ b/geonode/social/views.py @@ -60,7 +60,7 @@ def _filter_actions(action, request): resource = obj.get_self_resource() user = request.user if user.has_perm('base.view_resourcebase', resource) or \ - user.has_perm('view_resourcebase', resource): + user.has_perm('view_resourcebase', resource): _filtered_actions.append(_action.id) except ResourceBase.DoesNotExist: _filtered_actions.append(_action.id) diff --git a/geonode/tasks/tasks.py b/geonode/tasks/tasks.py index a87efe801e7..eb307009710 100644 --- a/geonode/tasks/tasks.py +++ b/geonode/tasks/tasks.py @@ -123,8 +123,8 @@ def after_return(self, *args, **kwargs): for conn in connections.all(): try: if not conn.in_atomic_block and \ - (not conn.connection or - (conn.connection.cursor() and not conn.is_usable())): + (not conn.connection or + (conn.connection.cursor() and not conn.is_usable())): conn.close() except Exception: pass diff --git a/geonode/tests/csw.py b/geonode/tests/csw.py index 3839fabc1f1..bcca6d6e08b 100644 --- a/geonode/tests/csw.py +++ b/geonode/tests/csw.py @@ -124,11 +124,11 @@ def test_csw_outputschema_dc(self): for link in record.references: if check_ogc_backend(geoserver.BACKEND_PACKAGE): if link['scheme'] == 'OGC:WMS': - self.assertEqual(link['url'], "{}ows".format(settings.GEOSERVER_PUBLIC_LOCATION)) + self.assertEqual(link['url'], f"{settings.GEOSERVER_PUBLIC_LOCATION}ows") elif link['scheme'] == 'OGC:WFS': - self.assertEqual(link['url'], "{}ows".format(settings.GEOSERVER_PUBLIC_LOCATION)) + self.assertEqual(link['url'], f"{settings.GEOSERVER_PUBLIC_LOCATION}ows") elif link['scheme'] == 'OGC:WCS': - self.assertEqual(link['url'], "{}ows".format(settings.GEOSERVER_PUBLIC_LOCATION)) + self.assertEqual(link['url'], f"{settings.GEOSERVER_PUBLIC_LOCATION}ows") elif check_ogc_backend(qgis_server.BACKEND_PACKAGE): if link['scheme'] == 'OGC:WMS': self.assertEqual( @@ -176,12 +176,12 @@ def test_csw_outputschema_iso(self): if link.protocol == 'OGC:WMS': self.assertEqual( link.url, - '{}ows'.format(settings.GEOSERVER_PUBLIC_LOCATION), + f'{settings.GEOSERVER_PUBLIC_LOCATION}ows', 'Expected a specific OGC:WMS URL') elif link.protocol == 'OGC:WFS': self.assertEqual( link.url, - '{}wfs'.format(settings.GEOSERVER_PUBLIC_LOCATION), + f'{settings.GEOSERVER_PUBLIC_LOCATION}wfs', 'Expected a specific OGC:WFS URL') if check_ogc_backend(qgis_server.BACKEND_PACKAGE): if link.protocol == 'OGC:WMS': diff --git a/geonode/tests/integration.py b/geonode/tests/integration.py index a3e164d7b07..1de034259a1 100644 --- a/geonode/tests/integration.py +++ b/geonode/tests/integration.py @@ -160,7 +160,7 @@ def test_layer_upload(self): import requests from requests.auth import HTTPBasicAuth - r = requests.get(url + 'gwc/rest/seed/%s.json' % saved_layer.alternate, + r = requests.get(f"{url}gwc/rest/seed/{saved_layer.alternate}.json", auth=HTTPBasicAuth(user, passwd)) self.assertEqual(r.status_code, 200) o = json.loads(r.text) @@ -173,14 +173,14 @@ def test_layer_upload(self): set_styles, create_gs_thumbnail) - _log("0. ------------ %s " % saved_layer) + _log(f"0. ------------ {saved_layer} ") self.assertIsNotNone(saved_layer) workspace, name = saved_layer.alternate.split(':') self.assertIsNotNone(workspace) self.assertIsNotNone(name) ws = gs_catalog.get_workspace(workspace) self.assertIsNotNone(ws) - _log("1. ------------ %s " % saved_layer.store) + _log(f"1. ------------ {saved_layer.store} ") self.assertIsNotNone(saved_layer.store) # Save layer attributes @@ -192,12 +192,12 @@ def test_layer_upload(self): # set SLD sld = saved_layer.default_style.sld_body if saved_layer.default_style else None self.assertIsNotNone(sld) - _log("2. ------------ %s " % sld) + _log(f"2. ------------ {sld} ") set_layer_style(saved_layer, saved_layer.alternate, sld) fixup_style(gs_catalog, saved_layer.alternate, None) self.assertIsNotNone(get_sld_for(gs_catalog, saved_layer)) - _log("3. ------------ %s " % get_sld_for(gs_catalog, saved_layer)) + _log(f"3. ------------ {get_sld_for(gs_catalog, saved_layer)} ") create_gs_thumbnail(saved_layer, overwrite=True) _log(saved_layer.get_thumbnail_url()) @@ -333,19 +333,15 @@ def test_layer_upload(self): item['file'], not_expected_layers)) assert errors, msg else: - msg = ('Upload should have returned either "name" or ' - '"errors" for file %s.' % item['file']) + msg = f"Upload should have returned either \"name\" or \"errors\" for file {item['file']}." assert 'name' in item, msg layers[item['file']] = item['name'] - msg = ('There were %s compatible layers in the directory,' - ' but only %s were sucessfully uploaded' % - (len(expected_layers), len(layers))) - # assert len(layers) == len(expected_layers), msg + msg = (f'There were {len(expected_layers)} compatible layers in the directory, ' + f'but only {len(layers)} were sucessfully uploaded') for layer in expected_layers: - msg = ('The following file should have been uploaded' - 'but was not: %s. ' % layer) + msg = f'The following file should have been uploadedbut was not: {layer}. ' assert layer in layers, msg layer_name = layers[layer] @@ -363,7 +359,7 @@ def test_layer_upload(self): 'rest/layers'), username=gs_username, password=gs_password) - if page.find('rest/layers/%s.html' % layer_name) > 0: + if page.find(f'rest/layers/{layer_name}.html') > 0: found = True if not found: msg = ( @@ -404,7 +400,7 @@ def test_layer_upload_metadata(self): gisdata.PROJECT_ROOT, 'both/good/sangis.org/Airport/Air_Runways.shp') - self.assertTrue('%s.xml' % thelayer, + self.assertTrue(f'{thelayer}.xml', 'Expected layer XML metadata to exist') try: if os.path.exists(thelayer): @@ -713,10 +709,9 @@ def test_repeated_upload(self): uploaded3 = file_upload(thefile, overwrite=False) check_layer(uploaded3) try: - msg = ('Expected %s but got %s' % (uploaded1.name, uploaded2.name)) + msg = f'Expected {uploaded1.name} but got {uploaded2.name}' assert uploaded1.name == uploaded2.name, msg - msg = ('Expected a different name when uploading %s using ' - 'overwrite=False but got %s' % (thefile, uploaded3.name)) + msg = f'Expected a different name when uploading {thefile} using overwrite=False but got {uploaded3.name}' assert uploaded1.name != uploaded3.name, msg finally: # Clean up and completely delete the layers @@ -923,12 +918,12 @@ def test_keywords_upload(self): overwrite=True) try: keywords = uploaded.keyword_list() - msg = 'No keywords found in layer %s' % uploaded.name + msg = f'No keywords found in layer {uploaded.name}' assert len(keywords) > 0, msg assert 'foo' in uploaded.keyword_list( - ), 'Could not find "foo" in %s' % keywords + ), f'Could not find "foo" in {keywords}' assert 'bar' in uploaded.keyword_list( - ), 'Could not find "bar" in %s' % keywords + ), f'Could not find "bar" in {keywords}' finally: # Clean up and completely delete the layers uploaded.delete() @@ -1008,9 +1003,9 @@ def test_layer_replace(self): layer_path, __ = os.path.splitext(new_vector_file) with open(f'{layer_path}.shp', 'rb') as layer_base, \ - open(f'{layer_path}.dbf', 'rb') as layer_dbf, \ - open(f'{layer_path}.shx', 'rb') as layer_shx, \ - open(f'{layer_path}.prj', 'rb') as layer_prj: + open(f'{layer_path}.dbf', 'rb') as layer_dbf, \ + open(f'{layer_path}.shx', 'rb') as layer_shx, \ + open(f'{layer_path}.prj', 'rb') as layer_prj: response = self.client.post( vector_replace_url, @@ -1037,10 +1032,10 @@ def test_layer_replace(self): gisdata.VECTOR_DATA, 'san_andres_y_providencia_administrative.shp') layer_path, __ = os.path.splitext(new_vector_file) - with open(layer_path + '.shp', 'rb') as layer_base, \ - open(layer_path + '.dbf', 'rb') as layer_dbf, \ - open(layer_path + '.shx', 'rb') as layer_shx, \ - open(layer_path + '.prj', 'rb') as layer_prj: + with open(f"{layer_path}.shp", 'rb') as layer_base, \ + open(f"{layer_path}.dbf", 'rb') as layer_dbf, \ + open(f"{layer_path}.shx", 'rb') as layer_shx, \ + open(f"{layer_path}.prj", 'rb') as layer_prj: response = self.client.post( vector_replace_url, @@ -1245,7 +1240,7 @@ def test_layer_interaction(self): self.assertTrue('styles' in obj and obj['styles']) # Test filter layers by id - filter_url = self.layer_list_url + '?id=' + str(layer_id) + filter_url = f"{self.layer_list_url}?id={str(layer_id)}" resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) # This is a list url @@ -1261,7 +1256,7 @@ def test_layer_interaction(self): prev_obj = obj # Test filter layers by name - filter_url = self.layer_list_url + '?name=' + self.layer.name + filter_url = f"{self.layer_list_url}?name={self.layer.name}" resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) # This is a list url @@ -1275,7 +1270,7 @@ def test_layer_interaction(self): def test_style_interaction(self): """Style API interaction check.""" # filter styles by layer id - filter_url = self.style_list_url + '?layer__id=' + str(self.layer.id) + filter_url = f"{self.style_list_url}?layer__id={str(self.layer.id)}" resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) # This is a list url @@ -1283,7 +1278,7 @@ def test_style_interaction(self): self.assertEqual(len(objects), 1) # filter styles by layer name - filter_url = self.style_list_url + '?layer__name=' + self.layer.name + filter_url = f"{self.style_list_url}?layer__name={self.layer.name}" resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) # This is a list url @@ -1340,7 +1335,7 @@ def test_add_delete_styles(self): 'resource_name': 'styles' } ) - filter_url = style_list_url + '?layer__name=' + self.layer.name + filter_url = f"{style_list_url}?layer__name={self.layer.name}" resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) objects = self.deserialize(resp)['objects'] @@ -1401,7 +1396,7 @@ def test_add_delete_styles(self): self.assertEqual(resp.status_code, 201) # Check styles count - filter_url = style_list_url + '?layer__name=' + self.layer.name + filter_url = f"{style_list_url}?layer__name={self.layer.name}" resp = self.api_client.get(filter_url) self.assertValidJSONResponse(resp) objects = self.deserialize(resp)['objects'] diff --git a/geonode/tests/suite/base.py b/geonode/tests/suite/base.py index 739cbc79653..c46128b7208 100644 --- a/geonode/tests/suite/base.py +++ b/geonode/tests/suite/base.py @@ -49,7 +49,7 @@ def setup_test_db(worker_index, fixtures, fn, *args): if worker_index is not None: test_database_name = 'test_%d_%s' % (worker_index, old_name) else: - test_database_name = 'test_%s' % (old_name) + test_database_name = f'test_{old_name}' create_test_db(test_database_name) if fixtures: diff --git a/geonode/tests/suite/runner.py b/geonode/tests/suite/runner.py index 03934f6ec9c..5ec8d460b1e 100644 --- a/geonode/tests/suite/runner.py +++ b/geonode/tests/suite/runner.py @@ -136,7 +136,7 @@ def _run_tests(self, tests, **kwargs): group_tests = tests[group] del tests[group] - logger.debug('Running tests in a main process: %s' % (group_tests)) + logger.debug(f'Running tests in a main process: {group_tests}') pending_not_thread_safe_tests[group] = group_tests result = self._tests_func(tests=group_tests, worker_index=None) results_queue.put((group, result), block=False) @@ -166,13 +166,13 @@ def _run_tests(self, tests, **kwargs): worker_count = worker_max worker_args = (tests_queue, results_queue, stop_event) - logger.debug("Number of workers %s " % worker_count) + logger.debug(f"Number of workers {worker_count} ") workers = self._create_worker_pool(pool_size=worker_count, target_func=self._run_tests_worker, worker_args=worker_args) for index, worker in enumerate(workers): - logger.debug('Staring worker %s' % (index)) + logger.debug(f'Staring worker {index}') worker.start() if workers: @@ -190,7 +190,7 @@ def _run_tests(self, tests, **kwargs): else: pending_not_thread_safe_tests.pop(group) except KeyError: - logger.debug('Got a result for unknown group: %s' % (group)) + logger.debug(f'Got a result for unknown group: {group}') else: completed_tests[group] = result self._print_result(result) @@ -238,15 +238,13 @@ def pop_item(): try: result = None logger.debug( - 'Worker %s is running tests %s' % - (index, tests)) + f'Worker {index} is running tests {tests}') result = self._tests_func( tests=tests, worker_index=index) results_queue.put((group, result)) logger.debug( - 'Worker %s has finished running tests %s' % - (index, tests)) + f'Worker {index} has finished running tests {tests}') except (KeyboardInterrupt, SystemExit): if isinstance(self, TwistedParallelTestSuiteRunner): # Twisted raises KeyboardInterrupt when the tests @@ -258,18 +256,17 @@ def pop_item(): import traceback tb = traceback.format_exc() logger.error(tb) - logger.debug('Running tests failed, reason: %s' % (str(e))) + logger.debug(f'Running tests failed, reason: {str(e)}') result = TestResult().from_exception(e) results_queue.put((group, result)) except Empty: logger.debug( - 'Worker %s timed out while waiting for tests to run' % - (index)) + f'Worker {index} timed out while waiting for tests to run') finally: tests_queue.close() results_queue.close() - logger.debug('Worker %s is stopping' % (index)) + logger.debug(f'Worker {index} is stopping') def _pre_tests_func(self): # This method gets called before _tests_func is called @@ -289,7 +286,7 @@ def _print_result(self, result): def _exit(self, start_time, end_time, failure_count, error_count): time_difference = (end_time - start_time) - print("Total run time: {} seconds".format(time_difference), file=sys.stderr) + print(f"Total run time: {time_difference} seconds", file=sys.stderr) try: sys.exit(failure_count + error_count) except Exception: @@ -397,8 +394,7 @@ def dependency_ordered(self, test_databases, dependencies): all_deps.update(dependencies.get(alias, [])) if not all_deps.isdisjoint(aliases): raise ImproperlyConfigured( - "Circular dependency: databases %r depend on each other, " - "but are aliases." % aliases + f"Circular dependency: databases {aliases!r} depend on each other, but are aliases." ) dependencies_map[sig] = all_deps diff --git a/geonode/tests/utils.py b/geonode/tests/utils.py index 2a0799350d0..4607a0089fc 100644 --- a/geonode/tests/utils.py +++ b/geonode/tests/utils.py @@ -108,12 +108,12 @@ def make_request(self, path, data=None, ajax=False, debug=True, force_login=Fals # logger.error(f" make_request ----------> url: {url}") if ajax: - url += "{}force_ajax=true".format('&' if '?' in url else '?') + url += f"{'&' if '?' in url else '?'}force_ajax=true" self._session.headers['X_REQUESTED_WITH'] = "XMLHttpRequest" cookie_value = self._session.cookies.get(settings.SESSION_COOKIE_NAME) if force_login and cookie_value: - self.response_cookies += "; {}={}".format(settings.SESSION_COOKIE_NAME, cookie_value) + self.response_cookies += f"; {settings.SESSION_COOKIE_NAME}={cookie_value}" if self.csrf_token: self._session.headers['X-CSRFToken'] = self.csrf_token @@ -159,9 +159,9 @@ def make_request(self, path, data=None, ajax=False, debug=True, force_login=Fals message = '' if hasattr(ex, 'message'): if debug: - logger.error('error in request to %s' % path) + logger.error(f'error in request to {path}') logger.error(ex.message) - message = ex.message[ex.message.index(':')+2:] + message = ex.message[ex.message.index(':') + 2:] else: message = str(ex) raise HTTPError(url, response.status_code, message, response.headers, None) @@ -210,7 +210,7 @@ def upload_file(self, _file): if ext.lower() == '.shp': for spatial_file in spatial_files: ext, _ = spatial_file.split('_') - file_path = base + '.' + ext + file_path = f"{base}.{ext}" # sometimes a shapefile is missing an extra file, # allow for that if os.path.exists(file_path): @@ -238,7 +238,7 @@ def upload_file(self, _file): try: return resp, resp.json() except ValueError: - logger.exception(ValueError("probably not json, status {}".format(resp.status_code))) + logger.exception(ValueError(f"probably not json, status {resp.status_code}")) return resp, resp.content def get_html(self, path, debug=True): @@ -307,7 +307,7 @@ def get_web_page(url, username=None, password=None, login_url=None): e.args = (msg,) raise except URLError as e: - msg = 'Could not open URL "%s": %s' % (url, e) + msg = f'Could not open URL "{url}": {e}' e.args = (msg,) raise else: @@ -319,9 +319,9 @@ def get_web_page(url, username=None, password=None, login_url=None): def check_layer(uploaded): """Verify if an object is a valid Layer. """ - msg = ('Was expecting layer object, got %s' % (type(uploaded))) + msg = f'Was expecting layer object, got {type(uploaded)}' assert isinstance(uploaded, Layer), msg - msg = ('The layer does not have a valid name: %s' % uploaded.name) + msg = f'The layer does not have a valid name: {uploaded.name}' assert len(uploaded.name) > 0, msg diff --git a/geonode/themes/models.py b/geonode/themes/models.py index 86f1f9392c1..7b6497689b0 100644 --- a/geonode/themes/models.py +++ b/geonode/themes/models.py @@ -38,16 +38,16 @@ class Partner(models.Model): @property def logo_class(self): - _logo_class = slugify("logo_%s" % self.name) - return "{0}".format(_logo_class) + _logo_class = slugify(f"logo_{self.name}") + return f"{_logo_class}" @property def partner_link(self): - _href = self.href if self.href.startswith('http') else 'http://%s' % self.href - return "{0}".format(_href) + _href = self.href if self.href.startswith('http') else f'http://{self.href}' + return f"{_href}" def __str__(self): - return "{0}".format(self.title) + return f"{self.title}" class Meta: ordering = ("name", ) @@ -206,7 +206,7 @@ class GeoNodeThemeCustomization(models.Model): def file_link(self): if self.logo: - return "download" % (self.logo.url,) + return f"download" else: return "No attachment" @@ -215,11 +215,11 @@ def file_link(self): @property def theme_uuid(self): if not self.identifier: - self.identifier = slugify("theme id %s %s" % (self.id, self.date)) - return "{0}".format(self.identifier) + self.identifier = slugify(f"theme id {self.id} {self.date}") + return f"{self.identifier}" def __str__(self): - return "{0}".format(self.name) + return f"{self.name}" class Meta: ordering = ("date", ) diff --git a/geonode/thumbs/background.py b/geonode/thumbs/background.py index 2d03417f1ba..8e6e58614db 100644 --- a/geonode/thumbs/background.py +++ b/geonode/thumbs/background.py @@ -91,7 +91,7 @@ def __init__( # WMS specific attributes (to be overwritten in specific background classes) service_url = options.get("service_url", None) - self.service_url = service_url + "/" if service_url and not service_url.endswith("/") else service_url + self.service_url = f"{service_url}/" if service_url and not service_url.endswith("/") else service_url self.layer_name = options.get("layer_name", None) self.format = options.get("format", "image/png") self.version = options.get("version", "1.3.0") diff --git a/geonode/thumbs/thumbnails.py b/geonode/thumbs/thumbnails.py index c35b85922b2..eaafdc99fc2 100644 --- a/geonode/thumbs/thumbnails.py +++ b/geonode/thumbs/thumbnails.py @@ -218,7 +218,7 @@ def _generate_thumbnail_name(instance: Union[Layer, Map]) -> Optional[str]: """ if isinstance(instance, Layer): - file_name = "layer-%s-thumb.png" % instance.uuid + file_name = f"layer-{instance.uuid}-thumb.png" elif isinstance(instance, Map): # if a Map is empty - nothing to do here @@ -226,7 +226,7 @@ def _generate_thumbnail_name(instance: Union[Layer, Map]) -> Optional[str]: logger.debug(f"Thumbnail generation skipped - Map {instance.title} has no defined layers") return None - file_name = "map-%s-thumb.png" % instance.uuid + file_name = f"map-{instance.uuid}-thumb.png" else: raise ThumbnailError( "Thumbnail generation didn't recognize the provided instance: it's neither a Layer nor a Map." diff --git a/geonode/thumbs/utils.py b/geonode/thumbs/utils.py index be8f2a80795..9d2c0d90564 100644 --- a/geonode/thumbs/utils.py +++ b/geonode/thumbs/utils.py @@ -205,7 +205,7 @@ def construct_wms_url( # add WMS endpoint to requests to Geoserver wms_endpoint = getattr(ogc_server_settings, "WMS_ENDPOINT") or "ows" - thumbnail_url = thumbnail_url + f"{wms_endpoint}?" + "&".join(f"{key}={val}" for key, val in params.items()) + thumbnail_url = f"{thumbnail_url}{wms_endpoint}?{'&'.join(f'{key}={val}' for key, val in params.items())}" return thumbnail_url diff --git a/geonode/upload/admin.py b/geonode/upload/admin.py index eca61b48d5a..8753e9efec0 100644 --- a/geonode/upload/admin.py +++ b/geonode/upload/admin.py @@ -24,7 +24,7 @@ def import_link(obj): - return "Geoserver Importer Link" % obj.get_import_url() + return f"Geoserver Importer Link" import_link.short_description = 'Link' diff --git a/geonode/upload/files.py b/geonode/upload/files.py index 91a8346a284..c31742e3b4e 100644 --- a/geonode/upload/files.py +++ b/geonode/upload/files.py @@ -75,8 +75,8 @@ def all_files(self): return [self.base_file] + self.auxillary_files def __repr__(self): - return "" % ( - self.base_file, self.file_type, self.auxillary_files, self.sld_files, self.xml_files) + return (f"") class FileType(object): @@ -114,7 +114,7 @@ def find_auxillary_files(self, base, others): return aux_files, slds, xmls def __repr__(self): - return "" % self.code + return f"" TYPE_UNKNOWN = FileType("unknown", None, None) @@ -298,8 +298,7 @@ def scan_file(file_name, scan_hint=None, charset=None): if len(found) == 1: found[0].xml_files = xml_files else: - raise Exception(_("One or more XML files was provided, but no " + - "matching files were found for them.")) + raise Exception(_("One or more XML files was provided, but no matching files were found for them.")) # detect slds and assign if a single upload is found sld_files = _find_file_type(safe_paths, extension='.sld') @@ -307,8 +306,7 @@ def scan_file(file_name, scan_hint=None, charset=None): if len(found) == 1: found[0].sld_files = sld_files else: - raise Exception(_("One or more SLD files was provided, but no " + - "matching files were found for them.")) + raise Exception(_("One or more SLD files was provided, but no matching files were found for them.")) return SpatialFiles(dirname, found, archive=archive) diff --git a/geonode/upload/models.py b/geonode/upload/models.py index b503ee03e50..ccf9b854487 100644 --- a/geonode/upload/models.py +++ b/geonode/upload/models.py @@ -109,14 +109,13 @@ def update_from_session(self, upload_session): self.save() def get_resume_url(self): - return reverse('data_upload') + "?id=%s" % self.import_id + return f"{reverse('data_upload')}?id={self.import_id}" def get_delete_url(self): return reverse('data_upload_delete', args=[self.import_id]) def get_import_url(self): - return "%srest/imports/%s" % ( - ogc_server_settings.LOCATION, self.import_id) + return f"{ogc_server_settings.LOCATION}rest/imports/{self.import_id}" def delete(self, cascade=True): models.Model.delete(self) @@ -134,10 +133,7 @@ def delete(self, cascade=True): shutil.rmtree(self.upload_dir) def __str__(self): - return 'Upload [%s] gs%s - %s, %s' % (self.pk, - self.import_id, - self.name, - self.user) + return f'Upload [{self.pk}] gs{self.import_id} - {self.name}, {self.user}' class UploadFile(models.Model): @@ -146,7 +142,7 @@ class UploadFile(models.Model): slug = models.SlugField(max_length=50, blank=True) def __str__(self): - return "{0}".format(self.slug) + return f"{self.slug}" def get_absolute_url(self): return reverse('data_upload_new', args=[self.slug, ]) diff --git a/geonode/upload/tests/__init__.py b/geonode/upload/tests/__init__.py index 7cb1e85e918..719b69c6ff1 100644 --- a/geonode/upload/tests/__init__.py +++ b/geonode/upload/tests/__init__.py @@ -93,7 +93,7 @@ def test_scan_file(self): """ exts = ('.shp', '.shx', '.sld', '.xml', '.prj', '.dbf') - with create_files(['san_andres_y_providencia_location{0}'.format(s) for s in exts]) as tests: + with create_files([f'san_andres_y_providencia_location{s}' for s in exts]) as tests: shp = [s for s in tests if s.endswith('.shp')][0] spatial_files = scan_file(shp) self.assertTrue(isinstance(spatial_files, SpatialFiles)) @@ -127,7 +127,7 @@ def test_scan_file(self): basedir = os.path.dirname(spatial_file.base_file) for f in file_names: - path = os.path.join(basedir, '_%s' % f) + path = os.path.join(basedir, f'_{f}') self.assertTrue(os.path.exists(path)) # Test the scan_file function with a raster spatial file takes SLD also. diff --git a/geonode/upload/tests/integration.py b/geonode/upload/tests/integration.py index efb9a89e733..8976bc927fd 100644 --- a/geonode/upload/tests/integration.py +++ b/geonode/upload/tests/integration.py @@ -73,13 +73,7 @@ DB_NAME = settings.DATABASES['default']['NAME'] DB_USER = settings.DATABASES['default']['USER'] DB_PASSWORD = settings.DATABASES['default']['PASSWORD'] -DATASTORE_URL = 'postgis://{}:{}@{}:{}/{}'.format( - DB_USER, - DB_PASSWORD, - DB_HOST, - DB_PORT, - DB_NAME -) +DATASTORE_URL = f'postgis://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}' postgis_db = dj_database_url.parse(DATASTORE_URL, conn_max_age=0) logging.getLogger('south').setLevel(logging.WARNING) @@ -101,11 +95,9 @@ def get_wms(version='1.1.1', type_name=None, username=None, password=None): # right now owslib does not support auth for get caps # requests. Either we should roll our own or fix owslib if type_name: - url = GEOSERVER_URL + \ - '%swms?request=getcapabilities' % type_name.replace(':', '/') + url = f"{GEOSERVER_URL}{type_name.replace(':', '/')}wms?request=getcapabilities" else: - url = GEOSERVER_URL + \ - 'wms?request=getcapabilities' + url = f"{GEOSERVER_URL}wms?request=getcapabilities" ogc_server_settings = settings.OGC_SERVER['default'] if username and password: return WebMapService( @@ -150,7 +142,7 @@ def setUp(self): GEONODE_URL, GEONODE_USER, GEONODE_PASSWD ) self.catalog = Catalog( - GEOSERVER_URL + 'rest', + f"{GEOSERVER_URL}rest", GEOSERVER_USER, GEOSERVER_PASSWD, retries=ogc_server_settings.MAX_RETRIES, @@ -197,7 +189,7 @@ def check_layer_geoserver_caps(self, type_name): type_name=type_name, username=GEOSERVER_USER, password=GEOSERVER_PASSWD) ws, layer_name = type_name.split(':') self.assertTrue(layer_name in wms.contents, - '%s is not in %s' % (layer_name, wms.contents)) + f'{layer_name} is not in {wms.contents}') def check_layer_geoserver_rest(self, layer_name): """ Check that a layer shows up in GeoServer rest api after @@ -228,7 +220,7 @@ def check_save_step(self, resp, data): self.assertEqual(resp.status_code, 200) self.assertTrue(isinstance(data, dict)) # make that the upload returns a success True key - self.assertTrue(data['success'], 'expected success but got %s' % data) + self.assertTrue(data['success'], f'expected success but got {data}') self.assertTrue('redirect_to' in data) def complete_upload(self, file_path, resp, data, is_raster=False): @@ -267,8 +259,7 @@ def finish_upload( if data['success']: self.assertTrue( data['success'], - 'expected success but got %s' % - data) + f'expected success but got {data}') self.assertTrue('redirect_to' in data) current_step = data['redirect_to'] self.wait_for_progress(data.get('progress')) @@ -294,8 +285,7 @@ def finish_upload( # @todo - make the check match completely (endswith at least) # currently working around potential 'orphaned' db tables self.assertTrue( - layer_name in url, 'expected %s in URL, got %s' % - (layer_name, url)) + layer_name in url, f'expected {layer_name} in URL, got {url}') return url except Exception: return current_step @@ -311,10 +301,9 @@ def check_upload_model(self, original_name): # the import session is COMPLETE if upload and not upload.complete: logger.warning( - "Upload not complete for Layer %s" % - original_name) + f"Upload not complete for Layer {original_name}") except Upload.DoesNotExist: - self.fail('expected to find Upload object for %s' % original_name) + self.fail(f'expected to find Upload object for {original_name}') def check_layer_complete(self, layer_page, original_name): '''check everything to verify the layer is complete''' @@ -341,8 +330,7 @@ def check_layer_complete(self, layer_page, original_name): pass if not caps_found: logger.warning( - "Could not recognize Layer %s on GeoServer WMS Capa" % - original_name) + f"Could not recognize Layer {original_name} on GeoServer WMS Capa") self.check_upload_model(layer_name) def check_invalid_projection(self, layer_name, resp, data): @@ -416,7 +404,7 @@ def wait_for_progress(self, progress_url): json_data = resp.json() # "COMPLETE" state means done if json_data and json_data.get('state', '') == 'RUNNING' and \ - self.wait_for_progress_cnt < 100: + self.wait_for_progress_cnt < 100: self.wait_for_progress_cnt += 1 self.wait_for_progress(progress_url) else: @@ -449,12 +437,12 @@ def test_shp_upload(self): fname = os.path.join( GOOD_DATA, 'vector', - '%s.shp' % layer_name) + f'{layer_name}.shp') self.upload_file(fname, self.complete_upload, - check_name='%s' % layer_name) + check_name=f'{layer_name}') - test_layer = Layer.objects.filter(name__icontains='%s' % layer_name).last() + test_layer = Layer.objects.filter(name__icontains=f'{layer_name}').last() if test_layer: layer_attributes = test_layer.attributes self.assertIsNotNone(layer_attributes) @@ -482,20 +470,14 @@ def test_shp_upload(self): self.assertIn( _link_orig.url, test_layer.csw_anytext, - "The link URL {0} is not present in the 'csw_anytext' attribute of the layer '{1}'".format( - _link_orig.url, - test_layer.alternate - ) - ) + f"The link URL {_link_orig.url} is not present in the 'csw_anytext' attribute of the layer '{test_layer.alternate}'") # Check catalogue catalogue = get_catalogue() record = catalogue.get_record(test_layer.uuid) self.assertIsNotNone(record) self.assertTrue( hasattr(record, 'links'), - "No records have been found in the catalogue for the resource '{}'".format( - test_layer.alternate - ) + f"No records have been found in the catalogue for the resource '{test_layer.alternate}'" ) # Check 'metadata' links for each record for mime, name, metadata_url in record.links['metadata']: @@ -510,10 +492,7 @@ def test_shp_upload(self): ) self.assertIsNotNone( _post_migrate_link_meta, - "No '{}' links have been found in the catalogue for the resource '{}'".format( - name, - test_layer.alternate - ) + f"No '{name}' links have been found in the catalogue for the resource '{test_layer.alternate}'" ) except Link.DoesNotExist: _post_migrate_link_meta = None @@ -657,7 +636,7 @@ def test_time(self): timedir = os.path.join(GOOD_DATA, 'time') layer_name = 'boxes_with_date' - shp = os.path.join(timedir, '%s.shp' % layer_name) + shp = os.path.join(timedir, f'{layer_name}.shp') # get to time step resp, data = self.client.upload_file(shp) @@ -685,15 +664,13 @@ def test_time(self): self.assertTrue( url.endswith(layer_name), - 'expected url to end with %s, but got %s' % - (layer_name, - url)) + f'expected url to end with {layer_name}, but got {url}') self.assertEqual(resp.status_code, 200) url = unquote(url) self.check_layer_complete(url, layer_name) wms = get_wms( - type_name='geonode:%s' % layer_name, username=GEOSERVER_USER, password=GEOSERVER_PASSWD) + type_name=f'geonode:{layer_name}', username=GEOSERVER_USER, password=GEOSERVER_PASSWD) layer_info = list(wms.items())[0][1] self.assertEqual(100, len(layer_info.timepositions)) else: @@ -705,7 +682,7 @@ def test_configure_time(self): cascading_delete(layer_name=layer_name, catalog=gs_catalog) def get_wms_timepositions(): - alternate_name = 'geonode:%s' % layer_name + alternate_name = f'geonode:{layer_name}' if alternate_name in get_wms().contents: metadata = get_wms().contents[alternate_name] self.assertTrue(metadata is not None) @@ -714,7 +691,7 @@ def get_wms_timepositions(): return None thefile = os.path.join( - GOOD_DATA, 'time', '%s.shp' % layer_name + GOOD_DATA, 'time', f'{layer_name}.shp' ) resp, data = self.client.upload_file(thefile) @@ -747,15 +724,13 @@ def get_wms_timepositions(): self.assertTrue( url.endswith(layer_name), - 'expected url to end with %s, but got %s' % - (layer_name, - url)) + f'expected url to end with {layer_name}, but got {url}') self.assertEqual(resp.status_code, 200) url = unquote(url) self.check_layer_complete(url, layer_name) wms = get_wms( - type_name='geonode:%s' % layer_name, username=GEOSERVER_USER, password=GEOSERVER_PASSWD) + type_name=f'geonode:{layer_name}', username=GEOSERVER_USER, password=GEOSERVER_PASSWD) layer_info = list(wms.items())[0][1] self.assertEqual(100, len(layer_info.timepositions)) else: diff --git a/geonode/upload/tests/test_settings.py b/geonode/upload/tests/test_settings.py index bc8586f9e5a..15e6493bfb9 100644 --- a/geonode/upload/tests/test_settings.py +++ b/geonode/upload/tests/test_settings.py @@ -40,7 +40,7 @@ # add trailing slash to site url. geoserver url will be relative to this if not SITEURL.endswith('/'): - SITEURL = '{}/'.format(SITEURL) + SITEURL = f'{SITEURL}/' ALLOWED_HOSTS = ['localhost', 'geonode', 'django', 'geonode.example.com'] @@ -105,8 +105,7 @@ 'GEOSERVER_PUBLIC_PORT', 8080 ) -_default_public_location = 'http://{}:{}/geoserver/'.format( - GEOSERVER_PUBLIC_HOST, GEOSERVER_PUBLIC_PORT) if GEOSERVER_PUBLIC_PORT else 'http://{}/geoserver/'.format(GEOSERVER_PUBLIC_HOST) +_default_public_location = f'http://{GEOSERVER_PUBLIC_HOST}:{GEOSERVER_PUBLIC_PORT}/geoserver/' if GEOSERVER_PUBLIC_PORT else f'http://{GEOSERVER_PUBLIC_HOST}/geoserver/' GEOSERVER_WEB_UI_LOCATION = os.getenv( 'GEOSERVER_WEB_UI_LOCATION', GEOSERVER_LOCATION @@ -145,7 +144,7 @@ 'WMST_ENABLED': False, 'BACKEND_WRITE_ENABLED': True, 'WPS_ENABLED': False, - 'LOG_FILE': '%s/geoserver/data/logs/geoserver.log' % os.path.abspath(os.path.join(PROJECT_ROOT, os.pardir)), + 'LOG_FILE': f'{os.path.abspath(os.path.join(PROJECT_ROOT, os.pardir))}/geoserver/data/logs/geoserver.log', # Set to dictionary identifier of database containing spatial data in DATABASES dictionary to enable 'DATASTORE': 'datastore', 'TIMEOUT': int(os.getenv('OGC_REQUEST_TIMEOUT', '60')), @@ -191,7 +190,7 @@ USER_ANALYTICS_ENABLED = ast.literal_eval( os.getenv('USER_ANALYTICS_ENABLED', os.environ.get('MONITORING_ENABLED', 'False'))) USER_ANALYTICS_GZIP = ast.literal_eval(os.getenv('USER_ANALYTICS_GZIP', - os.environ.get('MONITORING_ENABLED', 'False'))) + os.environ.get('MONITORING_ENABLED', 'False'))) MONITORING_CONFIG = os.getenv("MONITORING_CONFIG", None) MONITORING_HOST_NAME = os.getenv("MONITORING_HOST_NAME", HOSTNAME) diff --git a/geonode/upload/upload.py b/geonode/upload/upload.py index bccde9977bf..ac29cb2830c 100644 --- a/geonode/upload/upload.py +++ b/geonode/upload/upload.py @@ -147,7 +147,7 @@ def __init__(self, **kw): if hasattr(self, k): setattr(self, k, v) else: - raise Exception('not handled : %s' % k) + raise Exception(f'not handled : {k}') def cleanup(self): """do what we should at the given state of the upload""" @@ -257,10 +257,8 @@ def _check_geoserver_store(store_name, layer_type, overwrite): "Name already in use and overwrite is False") existing_type = resource.resource_type if existing_type != layer_type: - msg = ("Type of uploaded file {} ({}) does not " - "match type of existing resource type " - "{}".format(store_name, layer_type, - existing_type)) + msg = (f"Type of uploaded file {store_name} ({layer_type}) does not " + f"match type of existing resource type {existing_type}") logger.error(msg) raise GeoNodeException(msg) @@ -281,7 +279,7 @@ def save_step(user, layer, spatial_files, overwrite=True, mosaic=False, time_presentation_reference_value=None, charset_encoding="UTF-8"): logger.debug( - 'Uploading layer: {}, files {!r}'.format(layer, spatial_files)) + f'Uploading layer: {layer}, files {spatial_files!r}') if len(spatial_files) > 1: # we only support more than one file if they're rasters for mosaicing if not all( @@ -289,7 +287,7 @@ def save_step(user, layer, spatial_files, overwrite=True, mosaic=False, raise UploadException( "Please upload only one type of file at a time") name = get_valid_layer_name(layer, overwrite) - logger.debug('Name for layer: {!r}'.format(name)) + logger.debug(f'Name for layer: {name!r}') if not any(spatial_files.all_files()): raise UploadException("Unable to recognize the uploaded file(s)") the_layer_type = _get_layer_type(spatial_files) @@ -297,11 +295,10 @@ def save_step(user, layer, spatial_files, overwrite=True, mosaic=False, if the_layer_type not in ( FeatureType.resource_type, Coverage.resource_type): - raise RuntimeError("Expected layer type to FeatureType or " - "Coverage, not {}".format(the_layer_type)) + raise RuntimeError(f"Expected layer type to FeatureType or Coverage, not {the_layer_type}") files_to_upload = preprocess_files(spatial_files) - logger.debug("files_to_upload: {}".format(files_to_upload)) - logger.debug('Uploading {}'.format(the_layer_type)) + logger.debug(f"files_to_upload: {files_to_upload}") + logger.debug(f'Uploading {the_layer_type}') error_msg = None try: next_id = _get_next_id() @@ -506,7 +503,7 @@ def build_att_remap_transform(att): ) if transforms: - logger.debug('Setting transforms %s' % transforms) + logger.debug(f'Setting transforms {transforms}') upload_session.import_session.tasks[0].add_transforms(transforms) try: upload_session.time_transforms = transforms @@ -576,7 +573,7 @@ def final_step(upload_session, user, charset="UTF-8"): if import_session.state == 'INCOMPLETE': if task.state != 'ERROR': - raise Exception('unknown item state: %s' % task.state) + raise Exception(f'unknown item state: {task.state}') elif import_session.state == 'READY': import_session.commit() elif import_session.state == 'PENDING': @@ -586,8 +583,7 @@ def final_step(upload_session, user, charset="UTF-8"): if not publishing: raise LayerNotReady( - "Expected to find layer named '%s' in geoserver" % - name) + f"Expected to find layer named '{name}' in geoserver") _log('Creating Django record for [%s]', name) target = task.target @@ -662,8 +658,7 @@ def final_step(upload_session, user, charset="UTF-8"): temporal_extent_start=end) except Exception as e: _log( - 'There was an error updating the mosaic temporal extent: ' + - str(e)) + f"There was an error updating the mosaic temporal extent: {str(e)}") else: _has_time = (True if upload_session.time and upload_session.time_info and upload_session.time_transforms else False) @@ -681,7 +676,7 @@ def final_step(upload_session, user, charset="UTF-8"): abstract=abstract or '', owner=user, has_time=_has_time) - ) + ) except IntegrityError: raise assert saved_layer @@ -711,8 +706,7 @@ def _store_file(saved_layer, name=file_name, base=base, file=File( - f, name='%s%s' % - (assigned_name or saved_layer.name, type_name))) + f, name=f'{assigned_name or saved_layer.name}{type_name}')) # save the system assigned name for the remaining files if not assigned_name: the_file = geonode_upload_session.layerfile_set.all()[0].file.name @@ -770,7 +764,7 @@ def _store_file(saved_layer, zf = zipfile.ZipFile(archive, 'r', allowZip64=True) zf.extract(sld_file[0], os.path.dirname(archive)) # Assign the absolute path to this file - sld_file[0] = os.path.dirname(archive) + '/' + sld_file[0] + sld_file[0] = f"{os.path.dirname(archive)}/{sld_file[0]}" sld_file = sld_file[0] sld_uploaded = True # geoserver_set_style.apply_async((saved_layer.id, sld_file)) @@ -794,7 +788,7 @@ def _store_file(saved_layer, zf = zipfile.ZipFile(archive, 'r', allowZip64=True) zf.extract(xml_file[0], os.path.dirname(archive)) # Assign the absolute path to this file - xml_file = os.path.dirname(archive) + '/' + xml_file[0] + xml_file = f"{os.path.dirname(archive)}/{xml_file[0]}" if upload_session.time_info: set_time_info(saved_layer, **upload_session.time_info) diff --git a/geonode/upload/upload_preprocessing.py b/geonode/upload/upload_preprocessing.py index 0963166d975..b980a249068 100644 --- a/geonode/upload/upload_preprocessing.py +++ b/geonode/upload/upload_preprocessing.py @@ -109,7 +109,6 @@ def preprocess_files(spatial_files): def _extract_bbox_param(kml_doc, namespaces, param): return kml_doc.xpath( - "kml:Document/kml:GroundOverlay/kml:LatLonBox/" - "kml:{}/text()".format(param), + f"kml:Document/kml:GroundOverlay/kml:LatLonBox/kml:{param}/text()", namespaces=namespaces )[0] diff --git a/geonode/upload/upload_validators.py b/geonode/upload/upload_validators.py index 24160da4183..a5618dcab97 100644 --- a/geonode/upload/upload_validators.py +++ b/geonode/upload/upload_validators.py @@ -46,7 +46,7 @@ def _supported_type(ext, supported_types): def validate_uploaded_files(cleaned, uploaded_files, field_spatial_types): - logger.debug("uploaded_files: {}".format(uploaded_files)) + logger.debug(f"uploaded_files: {uploaded_files}") requires_datastore = () if ogc_server_settings.DATASTORE else ( 'csv', 'kml') @@ -152,11 +152,9 @@ def _validate_shapefile_components(possible_filenames): else: if additional_component.mandatory: raise forms.ValidationError( - "Could not find {!r} file, which is mandatory for " - "shapefile uploads".format( - additional_component.extension) + f"Could not find {additional_component.extension!r} file, which is mandatory for shapefile uploads" ) - logger.debug("shapefile components: {}".format(components)) + logger.debug(f"shapefile components: {components}") return components @@ -174,8 +172,8 @@ def _validate_kml_bytes(kml_bytes, other_files): "kml:Icon/kml:href/text()", namespaces=namespaces)[0].strip() except IndexError: image_path = "" - logger.debug("image_path: {}".format(image_path)) - logger.debug("other_files: {}".format(other_files)) + logger.debug(f"image_path: {image_path}") + logger.debug(f"other_files: {other_files}") if image_path not in other_files: raise forms.ValidationError( _("Ground overlay image declared in kml file cannot be found")) @@ -259,10 +257,10 @@ def dupes(_a): valid_extensions = None raster_types = [t for t in files.types if t.layer_type == files.raster] - raster_exts = [".%s" % t.code for t in raster_types] + raster_exts = [f".{t.code}" for t in raster_types] raster_aliases = [] for alias in [aliases for aliases in [t.aliases for t in raster_types] if aliases]: - raster_aliases.extend([".%s" % a for a in alias]) + raster_aliases.extend([f".{a}" for a in alias]) raster_exts.extend(raster_aliases) raster_files = [ diff --git a/geonode/upload/utils.py b/geonode/upload/utils.py index ae209f3766e..94346c4378f 100644 --- a/geonode/upload/utils.py +++ b/geonode/upload/utils.py @@ -146,7 +146,7 @@ def error_response(req, exception=None, errors=None, force_ajax=True): return render( req, 'upload/layer_upload_error.html', - context={'error_msg': 'Unexpected error : %s,' % exception}) + context={'error_msg': f'Unexpected error : {exception},'}) def json_load_byteified(file_handle): @@ -257,7 +257,7 @@ def get_next_step(upload_session, offset=1): try: pages = _pages[upload_session.upload_type] except KeyError as e: - raise Exception(_('Unsupported file type: %s' % e.message)) + raise Exception(_(f'Unsupported file type: {e.message}')) index = -1 if upload_session.completed_step and upload_session.completed_step != 'save': index = pages.index(upload_session.completed_step) @@ -299,7 +299,7 @@ def next_step_response(req, upload_session, force_ajax=True): {'status': 'error', 'success': False, 'id': import_session.id, - 'error_msg': "%s" % upload_session.error_msg, + 'error_msg': f"{upload_session.error_msg}", } ) @@ -310,13 +310,13 @@ def next_step_response(req, upload_session, force_ajax=True): upload_session.completed_step = 'check' return next_step_response(req, upload_session, force_ajax=True) if next == 'check' and force_ajax: - url = reverse('data_upload') + "?id=%s" % (import_session.id) + url = f"{reverse('data_upload')}?id={import_session.id}" return json_response( {'url': url, 'status': 'incomplete', 'success': True, 'id': import_session.id, - 'redirect_to': settings.SITEURL + 'upload/check' + "?id=%s%s" % (import_session.id, _force_ajax), + 'redirect_to': f"{settings.SITEURL}upload/check?id={import_session.id}{_force_ajax}", } ) @@ -335,46 +335,46 @@ def next_step_response(req, upload_session, force_ajax=True): upload_session.completed_step = 'time' return next_step_response(req, upload_session, force_ajax) if next == 'time' and force_ajax: - url = reverse('data_upload') + "?id=%s" % (import_session.id) + url = f"{reverse('data_upload')}?id={import_session.id}" return json_response( {'url': url, 'status': 'incomplete', 'success': True, 'id': import_session.id, - 'redirect_to': settings.SITEURL + 'upload/time' + "?id=%s%s" % (import_session.id, _force_ajax), + 'redirect_to': f"{settings.SITEURL}upload/time?id={import_session.id}{_force_ajax}", } ) if next == 'mosaic' and force_ajax: - url = reverse('data_upload') + "?id=%s" % (import_session.id) + url = f"{reverse('data_upload')}?id={import_session.id}" return json_response( {'url': url, 'status': 'incomplete', 'success': True, 'id': import_session.id, - 'redirect_to': settings.SITEURL + 'upload/mosaic' + "?id=%s%s" % (import_session.id, _force_ajax), + 'redirect_to': f"{settings.SITEURL}upload/mosaic?id={import_session.id}{_force_ajax}", } ) if next == 'srs' and force_ajax: - url = reverse('data_upload') + "?id=%s" % (import_session.id) + url = f"{reverse('data_upload')}?id={import_session.id}" return json_response( {'url': url, 'status': 'incomplete', 'success': True, 'id': import_session.id, - 'redirect_to': settings.SITEURL + 'upload/srs' + "?id=%s%s" % (import_session.id, _force_ajax), + 'redirect_to': f"{settings.SITEURL}upload/srs?id={import_session.id}{_force_ajax}", } ) if next == 'csv' and force_ajax: - url = reverse('data_upload') + "?id=%s" % (import_session.id) + url = f"{reverse('data_upload')}?id={import_session.id}" return json_response( {'url': url, 'status': 'incomplete', 'success': True, 'id': import_session.id, - 'redirect_to': settings.SITEURL + 'upload/csv' + "?id=%s%s" % (import_session.id, _force_ajax), + 'redirect_to': f"{settings.SITEURL}upload/csv?id={import_session.id}{_force_ajax}", } ) @@ -391,9 +391,9 @@ def next_step_response(req, upload_session, force_ajax=True): force_ajax=force_ajax) session_id = None if 'id' in req.GET: - session_id = "?id=%s" % (req.GET['id']) + session_id = f"?id={req.GET['id']}" elif import_session and import_session.id: - session_id = "?id=%s" % (import_session.id) + session_id = f"?id={import_session.id}" if req.is_ajax() or force_ajax: content_type = 'text/html' if not req.is_ajax() else None @@ -444,9 +444,8 @@ def check_import_session_is_valid(request, upload_session, import_session): layer = import_session.tasks[0].layer invalid = [a for a in layer.attributes if str(a.name).find(' ') >= 0] if invalid: - att_list = "
%s
" % '. '.join( - [a.name for a in invalid]) - msg = "Attributes with spaces are not supported : %s" % att_list + att_list = f"
{'. '.join([a.name for a in invalid])}
" + msg = f"Attributes with spaces are not supported : {att_list}" upload_session.completed_step = 'error' upload_session.error_msg = msg return layer @@ -522,7 +521,7 @@ def _fixup_base_file(absolute_base_file, tempdir=None): if os.path.exists(absolute_base_file): return absolute_base_file else: - raise Exception(_('File does not exist: %s' % absolute_base_file)) + raise Exception(_(f'File does not exist: {absolute_base_file}')) def _get_layer_values(layer, upload_session, expand=0): @@ -579,7 +578,7 @@ def run_import(upload_session, async_upload=_ASYNC_UPLOAD): import_execution_requested = False if import_session.state == 'INCOMPLETE': if task.state != 'ERROR': - raise Exception(_('unknown item state: %s' % task.state)) + raise Exception(_(f'unknown item state: {task.state}')) elif import_session.state == 'PENDING' and task.target.store_type == 'coverageStore': if task.state == 'READY': import_session.commit(async_upload) @@ -587,8 +586,7 @@ def run_import(upload_session, async_upload=_ASYNC_UPLOAD): if task.state == 'ERROR': progress = task.get_progress() raise Exception(_( - 'error during import: %s' % - progress.get('message'))) + f"error during import: {progress.get('message')}")) # if a target datastore is configured, ensure the datastore exists # in geoserver and set the uploader target appropriately @@ -624,8 +622,8 @@ def progress_redirect(step, upload_id): return json_response(dict( success=True, id=upload_id, - redirect_to=reverse('data_upload', args=[step]) + "?id=%s" % upload_id, - progress=reverse('data_upload_progress') + "?id=%s" % upload_id + redirect_to=f"{reverse('data_upload', args=[step])}?id={upload_id}", + progress=f"{reverse('data_upload_progress')}?id={upload_id}" )) @@ -792,8 +790,8 @@ def import_imagemosaic_granules( timeregex_template = """regex=(?<=_)({mosaic_time_regex})""" - if not os.path.exists(dirname + '/timeregex.properties'): - with open(dirname + '/timeregex.properties', 'w') as timeregex_prop_file: + if not os.path.exists(f"{dirname}/timeregex.properties"): + with open(f"{dirname}/timeregex.properties", 'w') as timeregex_prop_file: timeregex_prop_file.write(timeregex_template.format(**context)) datastore_template = r"""SPI=org.geotools.data.postgis.PostgisNGDataStoreFactory @@ -809,17 +807,17 @@ def import_imagemosaic_granules( min\ connections={db_conn_min} max\ connections={db_conn_max}""" - if not os.path.exists(dirname + '/indexer.properties'): - with open(dirname + '/indexer.properties', 'w') as indexer_prop_file: + if not os.path.exists(f"{dirname}/indexer.properties"): + with open(f"{dirname}/indexer.properties", 'w') as indexer_prop_file: indexer_prop_file.write(indexer_template.format(**context)) - if not os.path.exists(dirname + '/datastore.properties'): - with open(dirname + '/datastore.properties', 'w') as datastore_prop_file: + if not os.path.exists(f"{dirname}/datastore.properties"): + with open(f"{dirname}/datastore.properties", 'w') as datastore_prop_file: datastore_prop_file.write(datastore_template.format(**context)) files_to_upload = [] if not append_to_mosaic_opts and spatial_files: - z = zipfile.ZipFile(dirname + '/' + head + '.zip', "w", allowZip64=True) + z = zipfile.ZipFile(f"{dirname}/{head}.zip", "w", allowZip64=True) for spatial_file in spatial_files: f = spatial_file.base_file dst_basename = os.path.basename(f) @@ -828,16 +826,15 @@ def import_imagemosaic_granules( # Let's import only the first granule z.write(spatial_file.base_file, arcname=dst_head + dst_tail) files_to_upload.append(spatial_file.base_file) - if os.path.exists(dirname + '/indexer.properties'): - z.write(dirname + '/indexer.properties', arcname='indexer.properties') - if os.path.exists(dirname + '/datastore.properties'): + if os.path.exists(f"{dirname}/indexer.properties"): + z.write(f"{dirname}/indexer.properties", arcname='indexer.properties') + if os.path.exists(f"{dirname}/datastore.properties"): z.write( - dirname + - '/datastore.properties', + f"{dirname}/datastore.properties", arcname='datastore.properties') if mosaic_time_regex: z.write( - dirname + '/timeregex.properties', + f"{dirname}/timeregex.properties", arcname='timeregex.properties') z.close() diff --git a/geonode/upload/views.py b/geonode/upload/views.py index f007d07737a..436280fe01f 100644 --- a/geonode/upload/views.py +++ b/geonode/upload/views.py @@ -164,24 +164,24 @@ def save_step_view(req, session): form = LayerUploadForm(req.POST, req.FILES) if form.is_valid(): tempdir = tempfile.mkdtemp(dir=settings.STATIC_ROOT) - logger.debug("valid_extensions: {}".format(form.cleaned_data["valid_extensions"])) + logger.debug(f"valid_extensions: {form.cleaned_data['valid_extensions']}") relevant_files = _select_relevant_files( form.cleaned_data["valid_extensions"], iter(req.FILES.values()) ) - logger.debug("relevant_files: {}".format(relevant_files)) + logger.debug(f"relevant_files: {relevant_files}") _write_uploaded_files_to_disk(tempdir, relevant_files) base_file = os.path.join(tempdir, form.cleaned_data["base_file"].name) name, ext = os.path.splitext(os.path.basename(base_file)) - logger.debug('Name: {0}, ext: {1}'.format(name, ext)) - logger.debug("base_file: {}".format(base_file)) + logger.debug(f'Name: {name}, ext: {ext}') + logger.debug(f"base_file: {base_file}") scan_hint = get_scan_hint(form.cleaned_data["valid_extensions"]) spatial_files = scan_file( base_file, scan_hint=scan_hint, charset=form.cleaned_data["charset"] ) - logger.debug("spatial_files: {}".format(spatial_files)) + logger.debug(f"spatial_files: {spatial_files}") import_session = save_step( req.user, name, @@ -210,7 +210,7 @@ def save_step_view(req, session): form.cleaned_data["charset"], tempdir=tempdir) - _log('provided sld is %s' % sld) + _log(f'provided sld is {sld}') # upload_type = get_upload_type(base_file) upload_session = UploaderSession( tempdir=tempdir, @@ -307,7 +307,7 @@ def srs_step_view(request, upload_session): {'status': 'error', 'success': False, 'id': upload_session.import_session.id, - 'error_msg': "%s" % error, + 'error_msg': f"{error}", } ) else: @@ -401,7 +401,7 @@ def csv_step_view(request, upload_session): {'status': 'error', 'success': False, 'id': upload_session.import_session.id, - 'error_msg': "%s" % error, + 'error_msg': f"{error}", } ) else: @@ -593,7 +593,7 @@ def final_step_view(req, upload_session): return json_response({'status': 'pending', 'success': True, 'id': req.GET['id'], - 'redirect_to': '/upload/final' + "?id=%s%s" % (req.GET['id'], force_ajax)}) + 'redirect_to': f"/upload/final?id={req.GET['id']}{force_ajax}"}) else: # url = reverse('layer_browse') + '?limit={}'.format(settings.CLIENT_RESULTS_LIMIT) url = "upload/layer_upload_invalid.html" @@ -734,16 +734,8 @@ def form_valid(self, form): data = [ { 'name': f.name, - 'url': settings.MEDIA_URL + - "uploads/" + - f.name.replace( - " ", - "_"), - 'thumbnail_url': settings.MEDIA_URL + - "pictures/" + - f.name.replace( - " ", - "_"), + 'url': f"{settings.MEDIA_URL}uploads/{f.name.replace(' ', '_')}", + 'thumbnail_url': f"{settings.MEDIA_URL}pictures/{f.name.replace(' ', '_')}", 'delete_url': reverse( 'data_upload_remove', args=[ diff --git a/geonode/urls.py b/geonode/urls.py index baab169cec4..4e818d063d1 100644 --- a/geonode/urls.py +++ b/geonode/urls.py @@ -221,7 +221,7 @@ ] if settings.NOTIFICATIONS_MODULE in settings.INSTALLED_APPS: - notifications_urls = '{}.urls'.format(settings.NOTIFICATIONS_MODULE) + notifications_urls = f'{settings.NOTIFICATIONS_MODULE}.urls' urlpatterns += [ # '', url(r'^notifications/', include(notifications_urls)), ] diff --git a/geonode/utils.py b/geonode/utils.py index 059bf29994c..d313fe9dd47 100755 --- a/geonode/utils.py +++ b/geonode/utils.py @@ -91,8 +91,7 @@ INVALID_PERMISSION_MESSAGE = _("Invalid permission level.") -ALPHABET = string.ascii_uppercase + string.ascii_lowercase + \ - string.digits + '-_' +ALPHABET = f"{string.ascii_uppercase + string.ascii_lowercase + string.digits}-_" ALPHABET_REVERSE = {c: i for (i, c) in enumerate(ALPHABET)} BASE = len(ALPHABET) SIGN_CHARACTER = '$' @@ -211,21 +210,20 @@ def get_headers(request, url, raw_url, allowed_hosts=[]): value = request.COOKIES.get(name) if name == 'csrftoken': csrftoken = value - cook = "%s=%s" % (name, value) - cookies = cook if not cookies else (cookies + '; ' + cook) + cook = f"{name}={value}" + cookies = cook if not cookies else (f"{cookies}; {cook}") csrftoken = get_token(request) if not csrftoken else csrftoken if csrftoken: headers['X-Requested-With'] = "XMLHttpRequest" headers['X-CSRFToken'] = csrftoken - cook = "%s=%s" % ('csrftoken', csrftoken) - cookies = cook if not cookies else (cookies + '; ' + cook) + cook = f"{'csrftoken'}={csrftoken}" + cookies = cook if not cookies else (f"{cookies}; {cook}") if cookies: if 'JSESSIONID' in request.session and request.session['JSESSIONID']: - cookies = cookies + '; JSESSIONID=' + \ - request.session['JSESSIONID'] + cookies = f"{cookies}; JSESSIONID={request.session['JSESSIONID']}" headers['Cookie'] = cookies if request.method in ("POST", "PUT") and "CONTENT_TYPE" in request.META: @@ -254,18 +252,17 @@ def get_headers(request, url, raw_url, allowed_hosts=[]): access_token = get_or_create_token(request.user) if access_token: - headers['Authorization'] = 'Bearer %s' % access_token + headers['Authorization'] = f'Bearer {access_token}' pragma = "no-cache" referer = request.META[ "HTTP_REFERER"] if "HTTP_REFERER" in request.META else \ - "{scheme}://{netloc}/".format(scheme=site_url.scheme, - netloc=site_url.netloc) + f"{site_url.scheme}://{site_url.netloc}/" encoding = request.META["HTTP_ACCEPT_ENCODING"] if "HTTP_ACCEPT_ENCODING" in request.META else "gzip" headers.update({"Pragma": pragma, "Referer": referer, "Accept-encoding": encoding, - }) + }) return (headers, access_token) @@ -307,7 +304,7 @@ def _split_query(query): elif kw: keywords.append(kw) else: - accum += ' ' + kw + accum += f" {kw}" if kw.endswith('"'): keywords.append(accum[0:-1]) accum = None @@ -327,11 +324,11 @@ def bbox_to_wkt(x0, x1, y0, y1, srid="4326", include_srid=True): float(x1), float(y0), float(x0), float(y0)) if include_srid: - wkt = 'SRID=%s;%s' % (srid, wkt) + wkt = f'SRID={srid};{wkt}' else: wkt = 'POLYGON((-180 -90,-180 90,180 90,180 -90,-180 -90))' if include_srid: - wkt = 'SRID=4326;%s' % wkt + wkt = f'SRID=4326;{wkt}' return wkt @@ -383,14 +380,14 @@ def bbox_to_projection(native_bbox, target_srid=4326): dest = SpatialReference() dest.ImportFromEPSG(target_srid) if int(_gdal_ver[0]) >= 3 and \ - ((int(_gdal_ver[1]) == 0 and int(_gdal_ver[2]) >= 4) or int(_gdal_ver[1]) > 0): + ((int(_gdal_ver[1]) == 0 and int(_gdal_ver[2]) >= 4) or int(_gdal_ver[1]) > 0): source.SetAxisMappingStrategy(0) dest.SetAxisMappingStrategy(0) g.Transform(CoordinateTransformation(source, dest)) projected_bbox = [str(x) for x in g.GetEnvelope()] # Must be in the form : [x0, x1, y0, y1, EPSG:) return tuple([projected_bbox[0], projected_bbox[1], projected_bbox[2], projected_bbox[3]]) + \ - ("EPSG:%s" % target_srid,) + (f"EPSG:{target_srid}",) except Exception: tb = traceback.format_exc() logger.error(tb) @@ -562,10 +559,7 @@ def viewer_json(self, request, *added_layers): access_token = access_token.token if self.id and len(added_layers) == 0: - cfg = cache.get("viewer_json_" + - str(self.id) + - "_" + - str(0 if user is None else user.id)) + cfg = cache.get(f"viewer_json_{str(self.id)}_{str(0 if user is None else user.id)}") if cfg is not None: return cfg @@ -652,7 +646,7 @@ def _base_source(source): 'remote': True, 'ptype': service.ptype, 'name': service.name, - 'title': "[R] %s" % service.title + 'title': f"[R] {service.title}" } if remote_source['url'] not in source_urls: index += 1 @@ -686,10 +680,7 @@ def _base_source(source): # Create user-specific cache of maplayer config if self is not None: - cache.set("viewer_json_" + - str(self.id) + - "_" + - str(0 if user is None else user.id), config) + cache.set(f"viewer_json_{str(self.id)}_{str(0 if user is None else user.id)}", config) # Client conversion if needed from geonode.client.hooks import hookset @@ -1012,7 +1003,7 @@ def json_response(body=None, errors=None, url=None, redirect_to=None, exception= } elif exception: if body is None: - body = "Unexpected exception %s" % exception + body = f"Unexpected exception {exception}" else: body = body % exception body = { @@ -1085,16 +1076,13 @@ def build_caveats(resourcebase): if resourcebase.data_quality_statement: caveats.append(resourcebase.data_quality_statement) if len(caveats) > 0: - return "- " + "%0A- ".join(caveats) + return f"- {'%0A- '.join(caveats)}" else: return "" def build_social_links(request, resourcebase): - social_url = "{protocol}://{host}{path}".format( - protocol=("https" if request.is_secure() else "http"), - host=request.get_host(), - path=request.get_full_path()) + social_url = f"{'https' if request.is_secure() else 'http'}://{request.get_host()}{request.get_full_path()}" # Don't use datetime strftime() because it requires year >= 1900 # see # https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior @@ -1173,7 +1161,7 @@ def fixup_shp_columnnames(inShapefile, charset, tempdir=None): inDataSource = None if inDataSource is None: - logger.debug("Could not open {}".format(inShapefile)) + logger.debug(f"Could not open {inShapefile}") return False, None, None else: inLayer = inDataSource.GetLayer() @@ -1209,14 +1197,14 @@ def fixup_shp_columnnames(inShapefile, charset, tempdir=None): else: new_field_name = slugify(field_name) if not b.match(new_field_name): - new_field_name = '_' + new_field_name + new_field_name = f"_{new_field_name}" j = 0 while new_field_name in list_col_original or new_field_name in list_col.values(): if j == 0: new_field_name += '_0' - if new_field_name.endswith('_' + str(j)): + if new_field_name.endswith(f"_{str(j)}"): j += 1 - new_field_name = new_field_name[:-2] + '_' + str(j) + new_field_name = f"{new_field_name[:-2]}_{str(j)}" if field_name != new_field_name: list_col[field_name] = new_field_name except Exception as e: @@ -1233,7 +1221,7 @@ def fixup_shp_columnnames(inShapefile, charset, tempdir=None): except Exception as e: logger.exception(e) raise GeoNodeException( - "Could not decode SHAPEFILE attributes by using the specified charset '{}'.".format(charset)) + f"Could not decode SHAPEFILE attributes by using the specified charset '{charset}'.") return True, None, list_col @@ -1249,7 +1237,7 @@ def id_to_obj(id_): def printsignals(): for signalname in signalnames: - logger.debug("SIGNALNAME: %s" % signalname) + logger.debug(f"SIGNALNAME: {signalname}") signaltype = getattr(models.signals, signalname) signals = signaltype.receivers[:] for signal in signals: @@ -1264,6 +1252,7 @@ class DisableDjangoSignals: with DisableDjangoSignals(): # do some fancy stuff here """ + def __init__(self, disabled_signals=None, skip=False): self.skip = skip self.stashed_signals = defaultdict(list) @@ -1335,7 +1324,7 @@ def parse_datetime(value): # tb = traceback.format_exc() # logger.error(tb) pass - raise ValueError("Invalid datetime input: {}".format(value)) + raise ValueError(f"Invalid datetime input: {value}") def _convert_sql_params(cur, query): @@ -1428,7 +1417,7 @@ def __init__(self): def request(self, url, method='GET', data=None, headers={}, stream=False, timeout=None, retries=None, user=None, verify=False): if (user or self.username != 'admin') and \ - check_ogc_backend(geoserver.BACKEND_PACKAGE) and 'Authorization' not in headers: + check_ogc_backend(geoserver.BACKEND_PACKAGE) and 'Authorization' not in headers: if connection.cursor().db.vendor not in ('sqlite', 'sqlite3', 'spatialite'): try: if user and isinstance(user, str): @@ -1436,14 +1425,14 @@ def request(self, url, method='GET', data=None, headers={}, stream=False, _u = user or get_user_model().objects.get(username=self.username) access_token = get_or_create_token(_u) if access_token and not access_token.is_expired(): - headers['Authorization'] = 'Bearer %s' % access_token.token + headers['Authorization'] = f'Bearer {access_token.token}' except Exception: tb = traceback.format_exc() logger.debug(tb) elif user == self.username: valid_uname_pw = base64.b64encode( - "{}:{}".format(self.username, self.password).encode()).decode() - headers['Authorization'] = 'Basic {}'.format(valid_uname_pw) + f"{self.username}:{self.password}".encode()).decode() + headers['Authorization'] = f'Basic {valid_uname_pw}' response = None content = None @@ -1579,14 +1568,14 @@ def chmod_tree(dst, permissions=0o777): os.chmod(path, permissions) status = os.stat(path) if oct(status.st_mode & 0o777) != str(oct(permissions)): - raise Exception("Could not update permissions of {}".format(path)) + raise Exception(f"Could not update permissions of {path}") for dirname in dirnames: path = os.path.join(dirpath, dirname) os.chmod(path, permissions) status = os.stat(path) if oct(status.st_mode & 0o777) != str(oct(permissions)): - raise Exception("Could not update permissions of {}".format(path)) + raise Exception(f"Could not update permissions of {path}") def slugify_zh(text, separator='_'): @@ -1704,7 +1693,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): # Set download links for WMS, WCS or WFS and KML logger.debug(" -- Resource Links[Set download links for WMS, WCS or WFS and KML]...") - links = wms_links(ogc_server_settings.public_url + 'ows?', + links = wms_links(f"{ogc_server_settings.public_url}ows?", instance.alternate, bbox, srid, @@ -1733,7 +1722,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): link_type='image').update(**_d) if instance.storeType == "dataStore": - links = wfs_links(ogc_server_settings.public_url + 'ows?', + links = wfs_links(f"{ogc_server_settings.public_url}ows?", instance.alternate, bbox=None, # bbox filter should be set at runtime otherwise conflicting with CQL srid=srid) @@ -1756,7 +1745,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): ) elif instance.storeType == 'coverageStore': - links = wcs_links(ogc_server_settings.public_url + 'wcs?', + links = wcs_links(f"{ogc_server_settings.public_url}wcs?", instance.alternate, bbox, srid) @@ -1778,8 +1767,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): ) site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL - html_link_url = '%s%s' % ( - site_url, instance.get_absolute_url()) + html_link_url = f'{site_url}{instance.get_absolute_url()}' if (Link.objects.filter(resource=instance.resourcebase_ptr, url=html_link_url, @@ -1846,7 +1834,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): # ogc_wms_path = '%s/ows' % instance.workspace ogc_wms_path = 'ows' ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path) - ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace + ogc_wms_name = f'OGC WMS: {instance.workspace} Service' if Link.objects.filter(resource=instance.resourcebase_ptr, name=ogc_wms_name, url=ogc_wms_url).count() < 2: Link.objects.get_or_create( resource=instance.resourcebase_ptr, @@ -1864,7 +1852,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): # ogc_wfs_path = '%s/wfs' % instance.workspace ogc_wfs_path = 'ows' ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path) - ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace + ogc_wfs_name = f'OGC WFS: {instance.workspace} Service' if Link.objects.filter(resource=instance.resourcebase_ptr, name=ogc_wfs_name, url=ogc_wfs_url).count() < 2: Link.objects.get_or_create( resource=instance.resourcebase_ptr, @@ -1882,7 +1870,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): # ogc_wcs_path = '%s/wcs' % instance.workspace ogc_wcs_path = 'ows' ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path) - ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace + ogc_wcs_name = f'OGC WCS: {instance.workspace} Service' if Link.objects.filter(resource=instance.resourcebase_ptr, name=ogc_wcs_name, url=ogc_wcs_url).count() < 2: Link.objects.get_or_create( resource=instance.resourcebase_ptr, @@ -1913,7 +1901,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): zip_download_url = reverse( 'qgis_server:download-zip', kwargs={'layername': instance.name}) zip_download_url = urljoin(base_url, zip_download_url) - logger.debug('zip_download_url: %s' % zip_download_url) + logger.debug(f'zip_download_url: {zip_download_url}') if is_shapefile: link_name = 'Zipped Shapefile' link_mime = 'SHAPE-ZIP' @@ -1938,7 +1926,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): settings.SITEURL, reverse( 'qgis_server:layer-request', kwargs={'layername': instance.name})) - ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace + ogc_wms_name = f'OGC WMS: {instance.workspace} Service' ogc_wms_link_type = 'OGC:WMS' Link.objects.update_or_create( resource=instance.resourcebase_ptr, @@ -1958,7 +1946,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): reverse( 'qgis_server:download-qgs', kwargs={'layername': instance.name})) - logger.debug('qgs_download_url: %s' % ogc_qgs_url) + logger.debug(f'qgs_download_url: {ogc_qgs_url}') link_name = 'QGIS project file (.qgs)' link_mime = 'application/xml' Link.objects.update_or_create( @@ -1979,7 +1967,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): reverse( 'qgis_server:layer-request', kwargs={'layername': instance.name})) - ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace + ogc_wfs_name = f'OGC WFS: {instance.workspace} Service' ogc_wfs_link_type = 'OGC:WFS' Link.objects.update_or_create( resource=instance.resourcebase_ptr, @@ -1999,7 +1987,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): reverse( 'qgis_server:download-qlr', kwargs={'layername': instance.name})) - logger.debug('qlr_download_url: %s' % ogc_qlr_url) + logger.debug(f'qlr_download_url: {ogc_qlr_url}') link_name = 'QGIS layer file (.qlr)' link_mime = 'application/xml' Link.objects.update_or_create( @@ -2022,9 +2010,9 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): instance, layer.qgis_project_path, overwrite=overwrite, internal=True) - logger.debug('Creating the QGIS Project : %s' % response.url) + logger.debug(f'Creating the QGIS Project : {response.url}') if ensure_string(response.content) != 'OK': - logger.debug('Result : %s' % ensure_string(response.content)) + logger.debug(f'Result : {ensure_string(response.content)}') # Generate style model cache style_list(instance, internal=False) @@ -2053,7 +2041,7 @@ def set_resource_default_links(instance, layer, prune=False, **kwargs): geotiff_url = reverse( 'qgis_server:geotiff', kwargs={'layername': instance.name}) geotiff_url = urljoin(base_url, geotiff_url) - logger.debug('geotif_url: %s' % geotiff_url) + logger.debug(f'geotif_url: {geotiff_url}') Link.objects.update_or_create( resource=instance.resourcebase_ptr, @@ -2199,7 +2187,7 @@ def is_monochromatic_image(image_url, image_data=None): def is_local_static(url): if url.startswith(settings.STATIC_URL) or \ - (url.startswith(settings.SITEURL) and settings.STATIC_URL in url): + (url.startswith(settings.SITEURL) and settings.STATIC_URL in url): return True return False diff --git a/geonode/version.py b/geonode/version.py index e9f5ded53ed..5c664f8324b 100644 --- a/geonode/version.py +++ b/geonode/version.py @@ -43,9 +43,9 @@ def get_version(version=None): sub = mapping[version[3]] + str(version[4]) if git_changeset: if version[3] == 'unstable': - sub += '.dev%s' % git_changeset + sub += f'.dev{git_changeset}' elif version[3] != 'final': - sub += '.build%s' % git_changeset + sub += f'.build{git_changeset}' return main + sub diff --git a/geonode/views.py b/geonode/views.py index 90a15d27e24..2f6f9d75bac 100644 --- a/geonode/views.py +++ b/geonode/views.py @@ -101,7 +101,7 @@ def ajax_lookup(request): Q(slug__icontains=keyword)).exclude( Q(access='private') & ~Q( slug__in=request.user.groupmember_set.all().values_list("group__slug", flat=True)) - ) + ) json_dict = { 'users': [({'username': u.username}) for u in users], 'count': users.count(), @@ -117,9 +117,7 @@ def ajax_lookup(request): def err403(request, exception): if not request.user.is_authenticated: return HttpResponseRedirect( - reverse('account_login') + - '?next=' + - request.get_full_path()) + f"{reverse('account_login')}?next={request.get_full_path()}") else: return TemplateResponse(request, '401.html', {}, status=401).render() @@ -145,7 +143,7 @@ def ident_json(request): json_data['poc'] = { 'name': settings.PYCSW['CONFIGURATION']['metadata:main']['contact_name'], 'email': settings.PYCSW['CONFIGURATION']['metadata:main']['contact_email'], - 'twitter': 'https://twitter.com/%s' % settings.TWITTER_SITE + 'twitter': f'https://twitter.com/{settings.TWITTER_SITE}' } json_data['version'] = get_version() diff --git a/pavement.py b/pavement.py index b0ebac6c907..bc7b8f2a464 100644 --- a/pavement.py +++ b/pavement.py @@ -78,7 +78,7 @@ try: from geonode.settings import TEST_RUNNER_KEEPDB, TEST_RUNNER_PARALLEL _keepdb = '--keepdb' if TEST_RUNNER_KEEPDB else '' - _parallel = ('--parallel=%s' % TEST_RUNNER_PARALLEL) if TEST_RUNNER_PARALLEL else '' + _parallel = f'--parallel={TEST_RUNNER_PARALLEL}' if TEST_RUNNER_PARALLEL else '' except Exception: _keepdb = '' _parallel = '' @@ -99,18 +99,18 @@ def grab(src, dest, name): logger.info(f" src, dest, name --> {src} {dest} {name}") if not os.path.exists(dest): - logger.info("Downloading {}".format(name)) + logger.info(f"Downloading {name}") elif not zipfile.is_zipfile(dest): - logger.info("Downloading {} (corrupt file)".format(name)) + logger.info(f"Downloading {name} (corrupt file)") else: return if src.startswith("file://"): src2 = src.replace("file://", '') if not os.path.exists(src2): - logger.info("Source location ({}) does not exist".format(src2)) + logger.info(f"Source location ({src2}) does not exist") else: - logger.info("Copying local file from {}".format(src2)) + logger.info(f"Copying local file from {src2}") shutil.copyfile(src2, dest) else: # urlretrieve(str(src), str(dest)) @@ -118,7 +118,7 @@ def grab(src, dest, name): r = requests.get(src, stream=True, timeout=10, verify=False) # Total size in bytes. total_size = int(r.headers.get('content-length', 0)) - logger.info("Requesting {}".format(src)) + logger.info(f"Requesting {src}") block_size = 1024 wrote = 0 with open("output.bin", 'wb') as f: @@ -129,10 +129,11 @@ def grab(src, dest, name): unit_scale=False): wrote += len(data) f.write(data) - logger.info(" total_size [{}] / wrote [{}] ".format(total_size, wrote)) + logger.info(f" total_size [{total_size}] / wrote [{wrote}] ") if total_size != 0 and wrote != total_size: - logger.error("ERROR, something went wrong. Data could not be written. Expected to write " + wrote + - " but wrote " + total_size + " instead") + logger.error( + f"ERROR, something went wrong. Data could not be written. Expected to write {wrote} " + f"but wrote {total_size} instead") else: shutil.move("output.bin", dest) try: @@ -223,10 +224,10 @@ def setup_qgis_server(options): all_permission = 0o777 os.chmod('geonode/qgis_layer', all_permission) stat = os.stat('geonode/qgis_layer') - info('Mode : %o' % stat.st_mode) + info(f'Mode : {stat.st_mode:o}') os.chmod('geonode/qgis_tiles', all_permission) stat = os.stat('geonode/qgis_tiles') - info('Mode : %o' % stat.st_mode) + info(f'Mode : {stat.st_mode:o}') info('QGIS Server related folder successfully setup.') @@ -244,7 +245,7 @@ def _robust_rmtree(path, logger=None, max_retries=5): return except OSError: if logger: - info('Unable to remove path: %s' % path) + info(f'Unable to remove path: {path}') info('Retrying after %d seconds' % i) time.sleep(i) @@ -269,8 +270,7 @@ def _install_data_dir(): with open(config) as f: xml = f.read() m = re.search('proxyBaseUrl>([^<]+)', xml) - xml = xml[:m.start(1)] + \ - "http://localhost:8080/geoserver" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8080/geoserver{xml[m.end(1):]}" with open(config, 'w') as f: f.write(xml) except Exception as e: @@ -282,20 +282,15 @@ def _install_data_dir(): with open(config) as f: xml = f.read() m = re.search('accessTokenUri>([^<]+)', xml) - xml = xml[:m.start(1)] + \ - "http://localhost:8000/o/token/" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8000/o/token/{xml[m.end(1):]}" m = re.search('userAuthorizationUri>([^<]+)', xml) - xml = xml[:m.start( - 1)] + "http://localhost:8000/o/authorize/" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8000/o/authorize/{xml[m.end(1):]}" m = re.search('redirectUri>([^<]+)', xml) - xml = xml[:m.start( - 1)] + "http://localhost:8080/geoserver/index.html" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8080/geoserver/index.html{xml[m.end(1):]}" m = re.search('checkTokenEndpointUrl>([^<]+)', xml) - xml = xml[:m.start( - 1)] + "http://localhost:8000/api/o/v4/tokeninfo/" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8000/api/o/v4/tokeninfo/{xml[m.end(1):]}" m = re.search('logoutUri>([^<]+)', xml) - xml = xml[:m.start( - 1)] + "http://localhost:8000/account/logout/" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8000/account/logout/{xml[m.end(1):]}" with open(config, 'w') as f: f.write(xml) except Exception as e: @@ -307,7 +302,7 @@ def _install_data_dir(): with open(config) as f: xml = f.read() m = re.search('baseUrl>([^<]+)', xml) - xml = xml[:m.start(1)] + "http://localhost:8000" + xml[m.end(1):] + xml = f"{xml[:m.start(1)]}http://localhost:8000{xml[m.end(1):]}" with open(config, 'w') as f: f.write(xml) except Exception as e: @@ -363,7 +358,7 @@ def win_install_deps(options): failed = False for package, url in win_packages.items(): tempfile = download_dir / os.path.basename(url) - logger.info("Installing file ... " + tempfile) + logger.info(f"Installing file ... {tempfile}") grab_winfiles(url, tempfile, package) try: easy_install.main([tempfile]) @@ -395,7 +390,7 @@ def upgradedb(options): elif version is None: print("Please specify your GeoNode version") else: - print("Upgrades from version {} are not yet supported.".format(version)) + print(f"Upgrades from version {version} are not yet supported.") @task @@ -408,9 +403,9 @@ def updategeoip(options): """ settings = options.get('settings', '') if settings and 'DJANGO_SETTINGS_MODULE' not in settings: - settings = 'DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'DJANGO_SETTINGS_MODULE={settings}' - sh("%s python -W ignore manage.py updategeoip -o" % settings) + sh(f"{settings} python -W ignore manage.py updategeoip -o") @task @@ -423,16 +418,16 @@ def sync(options): """ settings = options.get('settings', '') if settings and 'DJANGO_SETTINGS_MODULE' not in settings: - settings = 'DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'DJANGO_SETTINGS_MODULE={settings}' - sh("%s python -W ignore manage.py makemigrations --noinput" % settings) - sh("%s python -W ignore manage.py migrate --noinput" % settings) - sh("%s python -W ignore manage.py loaddata sample_admin.json" % settings) - sh("%s python -W ignore manage.py loaddata geonode/base/fixtures/default_oauth_apps.json" % settings) - sh("%s python -W ignore manage.py loaddata geonode/base/fixtures/initial_data.json" % settings) + sh(f"{settings} python -W ignore manage.py makemigrations --noinput") + sh(f"{settings} python -W ignore manage.py migrate --noinput") + sh(f"{settings} python -W ignore manage.py loaddata sample_admin.json") + sh(f"{settings} python -W ignore manage.py loaddata geonode/base/fixtures/default_oauth_apps.json") + sh(f"{settings} python -W ignore manage.py loaddata geonode/base/fixtures/initial_data.json") if 'django_celery_beat' in INSTALLED_APPS: - sh("%s python -W ignore manage.py loaddata geonode/base/fixtures/django_celery_beat.json" % settings) - sh("%s python -W ignore manage.py set_all_layers_alternate" % settings) + sh(f"{settings} python -W ignore manage.py loaddata geonode/base/fixtures/django_celery_beat.json") + sh(f"{settings} python -W ignore manage.py set_all_layers_alternate") @task @@ -445,11 +440,11 @@ def package(options): version = geonode.get_version() # Use GeoNode's version for the package name. - pkgname = 'GeoNode-%s-all' % version + pkgname = f'GeoNode-{version}-all' # Create the output directory. out_pkg = path(pkgname) - out_pkg_tar = path("%s.tar.gz" % pkgname) + out_pkg_tar = path(f"{pkgname}.tar.gz") # Create a distribution in zip format for the geonode python package. dist_dir = path('dist') @@ -465,7 +460,7 @@ def package(options): old_package.remove() if out_pkg_tar.exists(): - info('There is already a package for version %s' % version) + info(f'There is already a package for version {version}') return # Clean anything that is in the oupout package tree. @@ -479,7 +474,7 @@ def package(options): justcopy(support_folder, out_pkg / 'support') justcopy(install_file, out_pkg) - geonode_dist = path('..') / 'dist' / 'GeoNode-%s.zip' % version + geonode_dist = path('..') / 'dist' / f'GeoNode-{version}.zip' justcopy(geonode_dist, out_pkg) # Create a tar file with all files in the output package folder. @@ -488,14 +483,14 @@ def package(options): tar.add(file) # Add the README with the license and important links to documentation. - tar.add('README', arcname=('%s/README.rst' % out_pkg)) + tar.add('README', arcname=f'{out_pkg}/README.rst') tar.close() # Remove all the files in the temporary output package directory. out_pkg.rmtree() # Report the info about the new package. - info("%s created" % out_pkg_tar.abspath()) + info(f"{out_pkg_tar.abspath()} created") @task @@ -553,7 +548,7 @@ def stop_geoserver(options): shell=True, stdout=subprocess.PIPE) for pid in map(int, proc.stdout): - info('Stopping geoserver (process number {})'.format(pid)) + info(f'Stopping geoserver (process number {pid})') os.kill(pid, signal.SIGKILL) # Check if the process that we killed is alive. @@ -611,11 +606,11 @@ def start_django(options): """ settings = options.get('settings', '') if settings and 'DJANGO_SETTINGS_MODULE' not in settings: - settings = 'DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'DJANGO_SETTINGS_MODULE={settings}' bind = options.get('bind', '0.0.0.0:8000') port = bind.split(":")[1] foreground = '' if options.get('foreground', False) else '&' - sh('%s python -W ignore manage.py runserver %s %s' % (settings, bind, foreground)) + sh(f'{settings} python -W ignore manage.py runserver {bind} {foreground}') if ASYNC_SIGNALS: if 'django_celery_beat' not in INSTALLED_APPS: @@ -626,15 +621,12 @@ def start_django(options): foreground )) else: - sh("{} celery -A geonode.celery_app:app worker -l DEBUG {} {}".format( - settings, - "-s django_celery_beat.schedulers:DatabaseScheduler", - foreground - )) - sh('%s python -W ignore manage.py runmessaging %s' % (settings, foreground)) + sh(f"{settings} celery -A geonode.celery_app:app worker -l DEBUG -s " + f"django_celery_beat.schedulers:DatabaseScheduler {foreground}") + sh(f'{settings} python -W ignore manage.py runmessaging {foreground}') # wait for Django to start - started = waitfor("http://localhost:" + port) + started = waitfor(f"http://localhost:{port}") if not started: info('Django never started properly or timed out.') sys.exit(1) @@ -647,9 +639,9 @@ def start_messaging(options): """ settings = options.get('settings', '') if settings and 'DJANGO_SETTINGS_MODULE' not in settings: - settings = 'DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'DJANGO_SETTINGS_MODULE={settings}' foreground = '' if options.get('foreground', False) else '&' - sh('%s python -W ignore manage.py runmessaging %s' % (settings, foreground)) + sh(f'{settings} python -W ignore manage.py runmessaging {foreground}') @task @@ -698,11 +690,10 @@ def start_geoserver(options): except socket.error as e: socket_free = False if e.errno == 98: - info('Port %s is already in use' % jetty_port) + info(f'Port {jetty_port} is already in use') else: info( - 'Something else raised the socket.error exception while checking port %s' % - jetty_port) + f'Something else raised the socket.error exception while checking port {jetty_port}') print(e) finally: s.close() @@ -754,7 +745,7 @@ def start_geoserver(options): "java.exe e.g. --java_path=C:/path/to/java/bin/java.exe") sys.exit(1) # if there are spaces - javapath = 'START /B "" "' + javapath_opt + '"' + javapath = f"START /B \"\" \"{javapath_opt}\"" sh(( '%(javapath)s -Xms512m -Xmx2048m -server -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m' @@ -772,11 +763,11 @@ def start_geoserver(options): ' > %(loggernullpath)s &' % locals() )) - info('Starting GeoServer on %s' % url) + info(f'Starting GeoServer on {url}') # wait for GeoServer to start started = waitfor(url) - info('The logs are available at %s' % log_file) + info(f'The logs are available at {log_file}') if not started: # If applications did not start in time we will give the user a chance @@ -830,10 +821,8 @@ def test(options): 'geonode.monitoring' in INSTALLED_APPS and \ 'geonode.monitoring' not in _apps_to_test: _apps_to_test.append('geonode.monitoring') - sh("%s manage.py test geonode.tests.smoke %s.tests --noinput %s %s" % (options.get('prefix'), - '.tests '.join(_apps_to_test), - _keepdb, - _parallel)) + sh(f"{options.get('prefix')} manage.py test geonode.tests.smoke " + f"{'.tests '.join(_apps_to_test)}.tests --noinput {_keepdb} {_parallel}") @task @@ -891,7 +880,7 @@ def test_integration(options): if name and name in ('geonode.tests.csw', 'geonode.tests.integration', 'geonode.geoserver.tests.integration'): if not settings: settings = 'geonode.local_settings' if _backend == 'geonode.qgis_server' else 'geonode.settings' - settings = 'REUSE_DB=1 DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'REUSE_DB=1 DJANGO_SETTINGS_MODULE={settings}' call_task('sync', options={'settings': settings}) if _backend == 'geonode.geoserver': call_task('start_geoserver', options={'settings': settings, 'force_exec': True}) @@ -901,37 +890,27 @@ def test_integration(options): elif _backend == 'geonode.geoserver' and 'geonode.geoserver' in INSTALLED_APPS: sh("cp geonode/upload/tests/test_settings.py geonode/") settings = 'geonode.test_settings' - sh("DJANGO_SETTINGS_MODULE={} python -W ignore manage.py " - "makemigrations --noinput".format(settings)) - sh("DJANGO_SETTINGS_MODULE={} python -W ignore manage.py " - "migrate --noinput".format(settings)) - sh("DJANGO_SETTINGS_MODULE={} python -W ignore manage.py " - "loaddata sample_admin.json".format(settings)) - sh("DJANGO_SETTINGS_MODULE={} python -W ignore manage.py " - "loaddata geonode/base/fixtures/default_oauth_apps.json".format(settings)) - sh("DJANGO_SETTINGS_MODULE={} python -W ignore manage.py " - "loaddata geonode/base/fixtures/initial_data.json".format(settings)) + sh(f"DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py makemigrations --noinput") + sh(f"DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py migrate --noinput") + sh(f"DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py loaddata sample_admin.json") + sh(f"DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py loaddata " + f"geonode/base/fixtures/default_oauth_apps.json") + sh(f"DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py loaddata " + f"geonode/base/fixtures/initial_data.json") call_task('start_geoserver') bind = options.get('bind', '0.0.0.0:8000') foreground = '' if options.get('foreground', False) else '&' - sh('DJANGO_SETTINGS_MODULE=%s python -W ignore manage.py runmessaging %s' % - (settings, foreground)) - sh('DJANGO_SETTINGS_MODULE=%s python -W ignore manage.py runserver %s %s' % - (settings, bind, foreground)) + sh(f'DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py runmessaging {foreground}') + sh(f'DJANGO_SETTINGS_MODULE={settings} python -W ignore manage.py runserver {bind} {foreground}') sh('sleep 30') - settings = 'REUSE_DB=1 DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'REUSE_DB=1 DJANGO_SETTINGS_MODULE={settings}' live_server_option = '' info("Running the tests now...") - sh(('%s %s manage.py test %s' - ' %s --noinput %s' % (settings, - prefix, - name, - _keepdb, - live_server_option))) + sh(f'{settings} {prefix} manage.py test {name} {_keepdb} --noinput {live_server_option}') except BuildFailure as e: - info('Tests failed! %s' % str(e)) + info(f'Tests failed! {str(e)}') else: success = True finally: @@ -990,10 +969,8 @@ def reset(options): def _reset(): from geonode import settings - sh("rm -rf {path}".format( - path=os.path.join(settings.PROJECT_ROOT, 'development.db') - ) - ) + sh(f"rm -rf {os.path.join(settings.PROJECT_ROOT, 'development.db')}" + ) sh("rm -rf geonode/development.db") sh("rm -rf geonode/uploaded/*") _install_data_dir() @@ -1027,9 +1004,9 @@ def setup_data(options): settings = options.get('settings', '') if settings and 'DJANGO_SETTINGS_MODULE' not in settings: - settings = 'DJANGO_SETTINGS_MODULE=%s' % settings + settings = f'DJANGO_SETTINGS_MODULE={settings}' - sh("%s python -W ignore manage.py importlayers %s -v2" % (settings, data_dir)) + sh(f"{settings} python -W ignore manage.py importlayers {data_dir} -v2") @needs(['package']) @@ -1051,7 +1028,7 @@ def deb(options): version, simple_version = versions() - info('Creating package for GeoNode version %s' % version) + info(f'Creating package for GeoNode version {version}') # Get rid of any uncommitted changes to debian/changelog info('Getting rid of any uncommitted changes in debian/changelog') @@ -1059,8 +1036,8 @@ def deb(options): # Workaround for git-dch bug # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594580 - sh('rm -rf %s/.git' % (os.path.realpath('package'))) - sh('ln -s %s %s' % (os.path.realpath('.git'), os.path.realpath('package'))) + sh(f"rm -rf {os.path.realpath('package')}/.git") + sh(f"ln -s {os.path.realpath('.git')} {os.path.realpath('package')}") with pushd('package'): @@ -1080,7 +1057,7 @@ def deb(options): deb_changelog = path('debian') / 'changelog' for idx, line in enumerate(fileinput.input([deb_changelog], inplace=True)): if idx == 0: - logger.info("geonode ({}) {}; urgency=high".format(simple_version, distribution), end='') + logger.info(f"geonode ({simple_version}) {distribution}; urgency=high", end='') else: print(line.replace("urgency=medium", "urgency=high"), end='') @@ -1095,13 +1072,13 @@ def deb(options): sh('debuild -S') elif key is not None and ppa is None: print("A signed installable package") - sh('debuild -k%s -A' % key) + sh(f'debuild -k{key} -A') elif key is not None and ppa is not None: print("A signed, source package") - sh('debuild -k%s -S' % key) + sh(f'debuild -k{key} -S') if ppa is not None: - sh('dput ppa:%s geonode_%s_source.changes' % (ppa, simple_version)) + sh(f'dput ppa:{ppa} geonode_{simple_version}_source.changes') @task @@ -1127,11 +1104,11 @@ def publish(options): version, simple_version = versions() if ppa: sh('git add package/debian/changelog') - sh('git commit -m "Updated changelog for version %s"' % version) - sh('git tag -f %s' % version) - sh('git push origin %s' % version) - sh('git tag -f debian/%s' % simple_version) - sh('git push origin debian/%s' % simple_version) + sh(f'git commit -m "Updated changelog for version {version}"') + sh(f'git tag -f {version}') + sh(f'git push origin {version}') + sh(f'git tag -f debian/{simple_version}') + sh(f'git push origin debian/{simple_version}') # sh('git push origin master') sh('python setup.py sdist upload -r pypi') @@ -1151,11 +1128,11 @@ def versions(): stage = 'thefinal' if stage == 'unstable': - tail = '%s%s' % (branch, timestamp) + tail = f'{branch}{timestamp}' else: - tail = '%s%s' % (stage, edition) + tail = f'{stage}{edition}' - simple_version = '%s.%s.%s+%s' % (major, minor, revision, tail) + simple_version = f'{major}.{minor}.{revision}+{tail}' return version, simple_version @@ -1172,10 +1149,10 @@ def kill(arg1, arg2): while running and time.time() - t0 < time_out: if os.name == 'nt': - p = Popen('tasklist | find "%s"' % arg1, shell=True, + p = Popen(f'tasklist | find "{arg1}"', shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=False) else: - p = Popen('ps aux | grep %s' % arg1, shell=True, + p = Popen(f'ps aux | grep {arg1}', shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) lines = p.stdout.readlines() @@ -1183,17 +1160,17 @@ def kill(arg1, arg2): running = False for line in lines: # this kills all java.exe and python including self in windows - if ('%s' % arg2 in str(line)) or (os.name == 'nt' and '%s' % arg1 in str(line)): + if (f'{arg2}' in str(line)) or (os.name == 'nt' and f'{arg1}' in str(line)): running = True # Get pid fields = line.strip().split() - info('Stopping %s (process number %s)' % (arg1, int(fields[1]))) + info(f'Stopping {arg1} (process number {int(fields[1])})') if os.name == 'nt': - kill = 'taskkill /F /PID "%s"' % int(fields[1]) + kill = f'taskkill /F /PID "{int(fields[1])}"' else: - kill = 'kill -9 %s 2> /dev/null' % int(fields[1]) + kill = f'kill -9 {int(fields[1])} 2> /dev/null' os.system(kill) # Give it a little more time diff --git a/scripts/cloud/demo_site.py b/scripts/cloud/demo_site.py index 2b3fb78b96d..76c73020263 100644 --- a/scripts/cloud/demo_site.py +++ b/scripts/cloud/demo_site.py @@ -73,7 +73,7 @@ def deleteNode(self, node_name): def buildJob(self, job): """Trigger a job build""" - print('Building %s job' % job) + print(f'Building {job} job') self.j.build_job(job) print('Build requested') diff --git a/scripts/cloud/ec2.py b/scripts/cloud/ec2.py index 6b812bf8c89..f79f810cbb6 100644 --- a/scripts/cloud/ec2.py +++ b/scripts/cloud/ec2.py @@ -219,13 +219,13 @@ def launch(): print("Firing up instance...") instance = wait_for_state(ec2, instance_id, 'running') dns = instance['PublicDnsName'] - print(("Instance running at %s" % dns)) + print(f"Instance running at {dns}") config.set('ec2', 'HOST', dns) config.set('ec2', 'INSTANCE', instance_id) writeconfig(config) - print(("ssh -i %s ubuntu@%s" % (key_path, dns))) + print(f"ssh -i {key_path} ubuntu@{dns}") print("Terminate the instance via the web interface.") time.sleep(20) @@ -265,7 +265,4 @@ def terminate(): config = readconfig() print(config.get('ec2', 'KEY_PATH')) else: - print("Usage:\n " + - "python %s launch_base\n " % sys.argv[0] + - "python %s launch_geonode\n " % sys.argv[0] + - "python %s terminate" % sys.argv[0]) + print(f"Usage:\n python {sys.argv[0]} launch_base\n python {sys.argv[0]} launch_geonode\n python {sys.argv[0]} terminate") diff --git a/scripts/cloud/fabfile.py b/scripts/cloud/fabfile.py index b614455de14..cedc3002aa5 100644 --- a/scripts/cloud/fabfile.py +++ b/scripts/cloud/fabfile.py @@ -62,21 +62,21 @@ KEY_PATH = '~/.ssh/' # trailing slash please # Derived variables -GEONODEDIR = INSTALLDIR + '/geonode' -PYLIBS = GEONODEDIR + '/lib/python2.7/site-packages' -ACT = 'source ' + GEONODEDIR + '/bin/activate' +GEONODEDIR = f"{INSTALLDIR}/geonode" +PYLIBS = f"{GEONODEDIR}/lib/python2.7/site-packages" +ACT = f"source {GEONODEDIR}/bin/activate" # Install GeoNode dependencies def install_depend(): - sudo('cd %s; virtualenv geonode --system-site-packages;' % INSTALLDIR) + sudo(f'cd {INSTALLDIR}; virtualenv geonode --system-site-packages;') sudo('apt-get install -y gcc python-pastescript python-dev libxml2-dev libxslt1-dev openjdk-6-jdk ' 'python-psycopg2 imagemagick') # Web server sudo('apt-get install -y apache2 tomcat6 libapache2-mod-wsgi maven2') sudo("a2enmod proxy_http") # Database - sudo('apt-get install -y postgis=%s postgresql-9.1-postgis postgresql-server-dev-9.1' % POSTGIS_VER) + sudo(f'apt-get install -y postgis={POSTGIS_VER} postgresql-9.1-postgis postgresql-server-dev-9.1') create_postgis_template() # sed('/etc/postgresql/9.1/main/pg_hba.conf', # 'local all all peer', @@ -89,17 +89,14 @@ def create_postgis_template(): sudo('createdb -E UTF8 template_postgis', user='postgres') sudo('createlang -d template_postgis plpgsql', user='postgres') cstring = "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis'" - sudo('psql -d postgres -c %s' % cstring, user='postgres') - sudo('psql -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-%s/postgis.sql' - % POSTGIS_VER[:3], user='postgres') - sudo('psql -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-%s/spatial_ref_sys.sql' - % POSTGIS_VER[:3], user='postgres') + sudo(f'psql -d postgres -c {cstring}', user='postgres') + sudo(f'psql -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-{POSTGIS_VER[:3]}/postgis.sql', user='postgres') + sudo(f'psql -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-{POSTGIS_VER[:3]}/spatial_ref_sys.sql', user='postgres') sudo('psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;"', user='postgres') sudo('psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;"', user='postgres') sudo('psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"', user='postgres') if POSTGIS_VER[:1] == '2': - sudo('psql -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-%s/rtpostgis.sql' - % POSTGIS_VER[:3], user='postgres') + sudo(f'psql -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-{POSTGIS_VER[:3]}/rtpostgis.sql', user='postgres') # Install GeoNode library @@ -109,14 +106,14 @@ def deploy_geonode(): # Fetch from GitHub sudo('apt-get install -y git') sudo('rm -rf setup') - sudo('git clone -b %s %s setup' % (GEONODE_BRANCH, GEONODE_GIT_URL)) + sudo(f'git clone -b {GEONODE_BRANCH} {GEONODE_GIT_URL} setup') # Install requirements, setup sudo('pip install -e setup') - sudo('cp -r setup/geonode %s' % PYLIBS) + sudo(f'cp -r setup/geonode {PYLIBS}') sudo('cp setup/package/support/geonode.apache /etc/apache2/sites-available/geonode') sudo('rm -rf setup') sed('/etc/apache2/sites-available/geonode', 'REPLACE_WITH_SITEDIR', PYLIBS, use_sudo=True) - sed('/etc/apache2/sites-available/geonode', '/var/www/geonode/wsgi/geonode.wsgi', PYLIBS+'/geonode/wsgi.py', + sed('/etc/apache2/sites-available/geonode', '/var/www/geonode/wsgi/geonode.wsgi', f"{PYLIBS}/geonode/wsgi.py", use_sudo=True) # Fix geoserver auth config file sed('/usr/share/geoserver/data/security/auth/geonodeAuthProvider/config.xml', 'localhost:8000', @@ -138,24 +135,24 @@ def deploy_project(project): with cd(GEONODEDIR), prefix(ACT): sudo('pip install -r requirements.txt --upgrade') sudo('rm requirements.txt') - put('%s/%s.apache' % (project, project), '/etc/apache2/sites-available/%s' % project, use_sudo=True) - sed('/etc/apache2/sites-available/%s' % project, 'REPLACE_WITH_SITEDIR', PYLIBS, use_sudo=True) + put(f'{project}/{project}.apache', f'/etc/apache2/sites-available/{project}', use_sudo=True) + sed(f'/etc/apache2/sites-available/{project}', 'REPLACE_WITH_SITEDIR', PYLIBS, use_sudo=True) with cd(os.path.join(PYLIBS, project)): sudo('ln -s settings_production.py local_settings.py') def enable_site(project): with cd(PYLIBS), prefix(ACT): - sudo('a2ensite %s; service apache2 restart' % project) + sudo(f'a2ensite {project}; service apache2 restart') sudo('mkdir /var/www/geonode; chown www-data:www-data /var/www/geonode') - sudo('django-admin.py collectstatic --noinput --settings=%s.settings' % project) + sudo(f'django-admin.py collectstatic --noinput --settings={project}.settings') # TODO - test/fix this function def restore_data(project): # Restore geoserver data gsdir = '/var/lib/tomcat6/webapps/geoserver' - put('data/geoserver-data.tar', gsdir+'/geoserver-data.tar', use_sudo=True) + put('data/geoserver-data.tar', f"{gsdir}/geoserver-data.tar", use_sudo=True) with cd(gsdir): sudo('rm -rf data') sudo('tar xvf geoserver-data.tar') @@ -163,29 +160,29 @@ def restore_data(project): run('rm geoserver-data.tar') sudo('service tomcat6 restart') with prefix(ACT): - sudo('django-admin.py cleardeadlayers --settings=%s.settings' % project) - sudo('django-admin.py updatelayers --settings=%s.settings' % project) + sudo(f'django-admin.py cleardeadlayers --settings={project}.settings') + sudo(f'django-admin.py updatelayers --settings={project}.settings') def create_database(db, user, password): # sudo("dropdb %s" % db, user="postgres") # sudo("dropuser %s" % user, user="postgres") with fab_settings(warn_only=True): - sudo("createuser -s %s" % user, user="postgres") - sudo("createdb -O %s %s -T template_postgis" % (user, db), user="postgres") - sudo("psql -c \"alter user %s with encrypted password '%s'\" " % (user, password), user="postgres") + sudo(f"createuser -s {user}", user="postgres") + sudo(f"createdb -O {user} {db} -T template_postgis", user="postgres") + sudo(f"psql -c \"alter user {user} with encrypted password '{password}'\" ", user="postgres") def setup_pgsql(project): import sys sys.path.append('.') - exec('import %s.settings_production as settings' % project) + exec(f'import {project}.settings_production as settings') db = settings.DATABASES['default']['NAME'] user = settings.DATABASES['default']['USER'] password = settings.DATABASES['default']['PASSWORD'] create_database(db, user, password) with prefix(ACT): - sudo('django-admin.py migrate --settings=%s.settings' % project) + sudo(f'django-admin.py migrate --settings={project}.settings') # Need to restore database and GeoServer data # put('data/%s.sql' % db, GEONODEDIR, use_sudo=True) # sudo('psql -d %s -f %s/%s.sql' % (db, GEONODEDIR, db), user='postgres') @@ -236,14 +233,14 @@ def deploy_geonode_dev_deb(): def change_admin_password(): put('../misc/changepw.py', '/home/ubuntu/') - run("perl -pi -e 's/replace.me.admin.user/%s/g' ~/changepw.py" % ADMIN_USER) - run("perl -pi -e 's/replace.me.admin.pw/%s/g' ~/changepw.py" % ADMIN_PASSWORD) + run(f"perl -pi -e 's/replace.me.admin.user/{ADMIN_USER}/g' ~/changepw.py") + run(f"perl -pi -e 's/replace.me.admin.pw/{ADMIN_PASSWORD}/g' ~/changepw.py") sudo('source /var/lib/geonode/bin/activate;cat ~/changepw.py | django-admin.py shell --settings=geonode.settings') run('rm ~/changepw.py') def geonode_updateip(server_name="demo.geonode.org"): - sudo('geonode-updateip %s' % server_name) + sudo(f'geonode-updateip {server_name}') def set_temp_hosts_entry(server_name="demo.geonode.org"): @@ -273,14 +270,13 @@ def cleanup_temp(): def copy_keys(): - sudo('rm -f ~/.ssh/*%s.pem' % KEY_BASE) - put(('%s*%s*' % (KEY_PATH, KEY_BASE)), '/home/ubuntu/.ssh/', mode=0o400) + sudo(f'rm -f ~/.ssh/*{KEY_BASE}.pem') + put(f'{KEY_PATH}*{KEY_BASE}*', '/home/ubuntu/.ssh/', mode=0o400) def install_ec2_tools(): - sudo('add-apt-repository "deb http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ %s multiverse"' % UBUNTU_VERSION) - sudo('add-apt-repository "deb http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ %s-updates multiverse"' - % UBUNTU_VERSION) + sudo(f'add-apt-repository "deb http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ {UBUNTU_VERSION} multiverse"') + sudo(f'add-apt-repository "deb http://us-east-1.ec2.archive.ubuntu.com/ubuntu/ {UBUNTU_VERSION}-updates multiverse"') sudo('apt-get -y update') sudo('apt-get install -y ec2-ami-tools') sudo('apt-get install -y ec2-api-tools') @@ -294,22 +290,19 @@ def build_geonode_ami(): update_instance() install_ec2_tools() with hide('running', 'stdout', 'stderr'): - sudo('export AWS_USER_ID=%s' % AWS_USER_ID) - sudo('export AWS_ACCESS_KEY_ID=%s' % AWS_ACCESS_KEY_ID) - sudo('export AWS_SECRET_ACCESS_KEY=%s' % AWS_SECRET_ACCESS_KEY) - sudo('export ARCH=%s' % ARCH) - prefix = 'geonode-%s-%s' % (VERSION, datetime.datetime.now().strftime('%Y%m%d%H%M%S')) + sudo(f'export AWS_USER_ID={AWS_USER_ID}') + sudo(f'export AWS_ACCESS_KEY_ID={AWS_ACCESS_KEY_ID}') + sudo(f'export AWS_SECRET_ACCESS_KEY={AWS_SECRET_ACCESS_KEY}') + sudo(f'export ARCH={ARCH}') + prefix = f"geonode-{VERSION}-{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}" excludes = '/mnt,/root/.ssh,/home/ubuntu/.ssh,/tmp' - sudo("ec2-bundle-vol -r %s -d /mnt -p %s -u %s -k ~/.ssh/pk-*.pem -c ~/.ssh/cert-*.pem -e %s" - % (ARCH, prefix, AWS_USER_ID, excludes)) - sudo("ec2-upload-bundle -b %s -m /mnt/%s.manifest.xml -a %s -s %s" - % (AMI_BUCKET, prefix, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)) - output = sudo('ec2-register --name "%s/%s" "%s/%s.manifest.xml" -K ~/.ssh/pk-*.pem -C ~/.ssh/cert-*.pem' - % (AMI_BUCKET, prefix, AMI_BUCKET, prefix)) + sudo(f"ec2-bundle-vol -r {ARCH} -d /mnt -p {prefix} -u {AWS_USER_ID} -k ~/.ssh/pk-*.pem -c ~/.ssh/cert-*.pem -e {excludes}") + sudo(f"ec2-upload-bundle -b {AMI_BUCKET} -m /mnt/{prefix}.manifest.xml -a {AWS_ACCESS_KEY_ID} -s {AWS_SECRET_ACCESS_KEY}") + output = sudo(f'ec2-register --name "{AMI_BUCKET}/{prefix}" "{AMI_BUCKET}/{prefix}.manifest.xml" -K ~/.ssh/pk-*.pem -C ~/.ssh/cert-*.pem') ami_id = output.split('\t')[1] if MAKE_PUBLIC: - sudo("ec2-modify-image-attribute -l -a all -K ~/.ssh/pk-*.pem -C ~/.ssh/cert-*.pem %s" % ami_id) - print("AMI %s Ready for Use" % ami_id) + sudo(f"ec2-modify-image-attribute -l -a all -K ~/.ssh/pk-*.pem -C ~/.ssh/cert-*.pem {ami_id}") + print(f"AMI {ami_id} Ready for Use") def install_sample_data(): diff --git a/scripts/misc/create_full_geonode_db.py b/scripts/misc/create_full_geonode_db.py index 67746014682..4ffb986b8ae 100755 --- a/scripts/misc/create_full_geonode_db.py +++ b/scripts/misc/create_full_geonode_db.py @@ -64,7 +64,7 @@ def assign_random_category(resource): def assign_keywords(resource): """ Assigns up to 5 keywords to resource """ for i in range(0, randint(0, 5)): - resource.keywords.add('keyword_%s' % randint(0, n_keywords)) + resource.keywords.add(f'keyword_{randint(0, n_keywords)}') def assign_regions(resource): @@ -79,7 +79,7 @@ def create_users(n_users): """ Create n users in the database """ for i in range(0, n_users): user = get_user_model() - user.username = 'user_%s' % i + user.username = f'user_{i}' user.save() @@ -93,11 +93,11 @@ def set_resource(resource): def create_document(number): """ Creates a new document """ - file_list = glob.glob('%s*.jpg' % doc_path) + file_list = glob.glob(f'{doc_path}*.jpg') random_index = randint(0, len(file_list) - 1) file_uri = file_list[random_index] - title = 'Document N. %s' % number - img_filename = '%s_img.jpg' % number + title = f'Document N. {number}' + img_filename = f'{number}_img.jpg' doc = Document(title=title, owner=get_random_user()) doc.save() with open(file_uri, 'r') as f: @@ -111,7 +111,7 @@ def create_document(number): def create_layer(number): """ Creates a new layer """ - file_list = glob.glob('%s*.shp' % shp_path) + file_list = glob.glob(f'{shp_path}*.shp') random_index = randint(0, len(file_list) - 1) file_uri = file_list[random_index] layer = file_upload(file_uri) @@ -142,7 +142,7 @@ def create_layer(number): Document.objects.all().delete() for d in range(0, n_docs): t = Timer(partial(create_document, d)) - print('Document %s generated in: %s' % (d, t.timeit(number=1))) + print(f'Document {d} generated in: {t.timeit(number=1)}') # 3. create layers # first we delete layers @@ -151,4 +151,4 @@ def create_layer(number): for l in range(0, n_layers): t = Timer(partial(create_layer, l)) - print('Layer %s generated in: %s' % (l, t.timeit(number=1))) + print(f'Layer {l} generated in: {t.timeit(number=1)}') diff --git a/scripts/misc/upload.py b/scripts/misc/upload.py index b748907b083..0aa4f17ba14 100755 --- a/scripts/misc/upload.py +++ b/scripts/misc/upload.py @@ -50,13 +50,12 @@ def upload_file_s3(filename, bucket, obj_name=None): try: _, bucket_name, filepath = sys.argv except ValueError: - print(("Usage:\n python %s bucket_name filepath" % sys.argv[0])) + print(f"Usage:\n python {sys.argv[0]} bucket_name filepath") filename = os.path.basename(filepath) error = upload_file_s3(filepath, bucket_name) if error is not None: - print((filename + " failed uploading to " + - bucket_name + " with error " + error)) + print(f"{filename} failed uploading to {bucket_name} with error {error}") else: - print((filename + " uploaded to " + bucket_name)) + print(f"{filename} uploaded to {bucket_name}") diff --git a/scripts/spcgeonode/django/initialize.py b/scripts/spcgeonode/django/initialize.py index 6fa4693aac6..9c61a1e442e 100644 --- a/scripts/spcgeonode/django/initialize.py +++ b/scripts/spcgeonode/django/initialize.py @@ -109,14 +109,14 @@ } if _port not in _protocols: redirect_uris = [ - 'http://{}:{}/geoserver'.format(_host, _port), - 'http://{}:{}/geoserver/index.html'.format(_host, _port), + f'http://{_host}:{_port}/geoserver', + f'http://{_host}:{_port}/geoserver/index.html', ] else: # Make sure protocol string match with GeoServer Redirect URL's protocol string redirect_uris = [ - '{}{}/geoserver'.format(_protocols[_port], _host), - '{}{}/geoserver/index.html'.format(_protocols[_port], _host), + f'{_protocols[_port]}{_host}/geoserver', + f'{_protocols[_port]}{_host}/geoserver/index.html', ] app.redirect_uris = "\n".join(redirect_uris) @@ -164,12 +164,12 @@ _geoserver_host = os.getenv('GEOSERVER_LOCATION', 'http://geoserver:8080/geoserver') for _ in range(60*5): try: - requests.head("{}".format(_geoserver_host)) + requests.head(f"{_geoserver_host}") break except ConnectionError: time.sleep(1) else: - requests.head("{}".format(_geoserver_host)) + requests.head(f"{_geoserver_host}") ######################################################### # 9. Securing GeoServer @@ -184,7 +184,7 @@ # Getting the old password try: - r1 = requests.get('{}/rest/security/masterpw.json'.format(_geoserver_host), + r1 = requests.get(f'{_geoserver_host}/rest/security/masterpw.json', auth=(geoserver_admin_username, geoserver_admin_password)) except requests.exceptions.ConnectionError: print("Unable to connect to GeoServer. Make sure GeoServer is started and accessible.") @@ -196,7 +196,7 @@ print("Randomizing master password") new_password = uuid.uuid4().hex data = json.dumps({"oldMasterPassword": old_password, "newMasterPassword": new_password}) - r2 = requests.put('{}/rest/security/masterpw.json'.format(_geoserver_host), data=data, + r2 = requests.put(f'{_geoserver_host}/rest/security/masterpw.json', data=data, headers={'Content-Type': 'application/json'}, auth=(geoserver_admin_username, geoserver_admin_password)) r2.raise_for_status() else: diff --git a/setup.cfg b/setup.cfg index a0b0c8a32a0..61814a6b3b5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -187,6 +187,6 @@ exclude = tests universal = 1 [flake8] -max-line-length = 120 +max-line-length = 200 exclude=geonode/*/migrations/*,management,scripts,docs,static,migrations,geonode/*settings.py,node_modules extend-ignore=E122,E124 diff --git a/tasks.py b/tasks.py index cf729c0ec29..9a6d8d505e4 100755 --- a/tasks.py +++ b/tasks.py @@ -1,6 +1,5 @@ import ast import json -import logging import os import re import time @@ -12,9 +11,9 @@ from urllib.parse import urlparse from urllib.request import urlopen, Request except ImportError: - from urllib2 import urlopen, Request - from urlparse import urlparse -from invoke import run, task + from urllib2 import urlopen, Request # noqa + from urlparse import urlparse # noqa +from invoke import task BOOTSTRAP_IMAGE_CHEIP = 'codenvy/che-ip:nightly' @@ -29,7 +28,7 @@ def waitfordbs(ctx): def waitforgeoserver(ctx): print("****************************geoserver********************************") while not _rest_api_availability(os.environ['GEOSERVER_LOCATION'] + 'rest'): - print ("Wait for GeoServer API availability...") + print("Wait for GeoServer API availability...") print("GeoServer is available for HTTP calls!") @@ -62,8 +61,9 @@ def update(ctx): envs = { "local_settings": "{0}".format(_localsettings()), - "siteurl": os.environ.get('SITEURL', - '{0}://{1}:{2}/'.format(pub_protocol, pub_ip, pub_port) if pub_port else '{0}://{1}/'.format(pub_protocol, pub_ip)), + "siteurl": os.environ.get( + 'SITEURL', + '{0}://{1}:{2}/'.format(pub_protocol, pub_ip, pub_port) if pub_port else '{0}://{1}/'.format(pub_protocol, pub_ip)), "geonode_docker_host": "{0}".format(socket.gethostbyname('geonode')), "public_protocol": pub_protocol, "public_fqdn": "{0}{1}".format(pub_ip, ':' + pub_port if pub_port else ''), @@ -85,16 +85,19 @@ def update(ctx): "geodb_url": os.environ.get('GEODATABASE_URL', 'postgis://geonode:geonode@db:5432/geonode_data'), "geonode_db": os.environ.get('GEONODE_DATABASE', 'geonode'), "gs_loc": os.environ.get('GEOSERVER_LOCATION', 'http://geoserver:8080/geoserver/'), - "gs_web_ui_loc": os.environ.get('GEOSERVER_WEB_UI_LOCATION', - 'http://{0}:{1}/geoserver/'.format(pub_ip, pub_port) if pub_port else 'http://{0}/geoserver/'.format(pub_ip)), - "gs_pub_loc": os.environ.get('GEOSERVER_PUBLIC_LOCATION', - 'http://{0}:{1}/geoserver/'.format(pub_ip, pub_port) if pub_port else 'http://{0}/geoserver/'.format(pub_ip)), + "gs_web_ui_loc": os.environ.get( + 'GEOSERVER_WEB_UI_LOCATION', + 'http://{0}:{1}/geoserver/'.format(pub_ip, pub_port) if pub_port else 'http://{0}/geoserver/'.format(pub_ip)), + "gs_pub_loc": os.environ.get( + 'GEOSERVER_PUBLIC_LOCATION', + 'http://{0}:{1}/geoserver/'.format(pub_ip, pub_port) if pub_port else 'http://{0}/geoserver/'.format(pub_ip)), "gs_admin_pwd": os.environ.get('GEOSERVER_ADMIN_PASSWORD', 'geoserver'), "override_fn": override_env } try: - current_allowed = ast.literal_eval(os.getenv('ALLOWED_HOSTS') or \ - "['{public_fqdn}', '{public_host}', 'localhost', 'django', 'geonode',]".format(**envs)) + current_allowed = ast.literal_eval( + os.getenv('ALLOWED_HOSTS') or "['{public_fqdn}', '{public_host}', 'localhost', 'django', 'geonode',]".format( + **envs)) except ValueError: current_allowed = [] current_allowed.extend(['{}'.format(pub_ip), '{}:{}'.format(pub_ip, pub_port)]) @@ -180,9 +183,10 @@ def migrations(ctx): ctx.run("python manage.py rebuild_index --noinput --settings={0}".format( _localsettings() ), pty=True) - except: + except BaseException: pass + @task def statics(ctx): print("**************************statics*******************************") @@ -191,6 +195,7 @@ def statics(ctx): _localsettings() ), pty=True) + @task def prepare(ctx): print("**********************prepare fixture***************************") @@ -213,13 +218,13 @@ def prepare(ctx): ctx.run( 'sed -i "s|.*|{new_ext_ip}o/authorize/|g" {oauth_config}'.format( new_ext_ip=os.environ['SITEURL'], - oauth_config=oauth_config - ), pty=True) + oauth_config=oauth_config), + pty=True) ctx.run( 'sed -i "s|.*|{new_ext_ip}geoserver/index.html|g" {oauth_config}'.format( new_ext_ip=os.environ['SITEURL'], - oauth_config=oauth_config - ), pty=True) + oauth_config=oauth_config), + pty=True) ctx.run( 'sed -i "s|.*|{new_ext_ip}account/logout/|g" {oauth_config}'.format( new_ext_ip=os.environ['SITEURL'], @@ -280,7 +285,10 @@ def updategeoip(ctx): def updateadmin(ctx): print("***********************update admin details**************************") ctx.run("rm -rf /tmp/django_admin_docker.json", pty=True) - _prepare_admin_fixture(os.environ.get('ADMIN_PASSWORD', 'admin'), os.environ.get('ADMIN_EMAIL', 'admin@example.org')) + _prepare_admin_fixture( + os.environ.get( + 'ADMIN_PASSWORD', 'admin'), os.environ.get( + 'ADMIN_EMAIL', 'admin@example.org')) ctx.run("django-admin.py loaddata /tmp/django_admin_docker.json \ --settings={0}".format(_localsettings()), pty=True) @@ -291,11 +299,13 @@ def collectmetrics(ctx): ctx.run("python -W ignore manage.py collect_metrics \ --settings={0} -n -t xml".format(_localsettings()), pty=True) + @task def initialized(ctx): print("**************************init file********************************") ctx.run('date > /mnt/volumes/statics/geonode_init.lock') + def _docker_host_ip(): client = docker.from_env() ip_list = client.containers.run(BOOTSTRAP_IMAGE_CHEIP, @@ -327,6 +337,7 @@ def _container_exposed_port(component, instname): port = re.split('/tcp', key)[0] return port + def _update_db_connstring(): user = os.getenv('GEONODE_DATABASE', 'geonode') pwd = os.getenv('GEONODE_DATABASE_PASSWORD', 'geonode') @@ -396,9 +407,9 @@ def _geoserver_info_provision(url): from geoserver.catalog import Catalog print("Setting GeoServer Admin Password...") cat = Catalog(url, - username=settings.OGC_SERVER_DEFAULT_USER, - password=settings.OGC_SERVER_DEFAULT_PASSWORD - ) + username=settings.OGC_SERVER_DEFAULT_USER, + password=settings.OGC_SERVER_DEFAULT_PASSWORD + ) headers = { "Content-type": "application/xml", "Accept": "application/xml" @@ -423,27 +434,22 @@ def _prepare_oauth_fixture(): print("Public Hostname or IP is {0}".format(pub_ip)) pub_port = _geonode_public_port() print("Public PORT is {0}".format(pub_port)) - default_fixture = [ - { - "model": "oauth2_provider.application", - "pk": 1001, - "fields": { - "skip_authorization": True, - "created": "2018-05-31T10:00:31.661Z", - "updated": "2018-05-31T11:30:31.245Z", - "algorithm": "RS256", - "redirect_uris": "{0}://{1}:{2}/geoserver/index.html".format(net_scheme, pub_ip, pub_port) if pub_port else "{0}://{1}/geoserver/index.html".format(net_scheme, pub_ip), - "name": "GeoServer", - "authorization_grant_type": "authorization-code", - "client_type": "confidential", - "client_id": "{0}".format(os.environ['OAUTH2_CLIENT_ID']), - "client_secret": "{0}".format(os.environ['OAUTH2_CLIENT_SECRET']), - "user": [ - "admin" - ] - } - } - ] + default_fixture = [{"model": "oauth2_provider.application", + "pk": 1001, + "fields": {"skip_authorization": True, + "created": "2018-05-31T10:00:31.661Z", + "updated": "2018-05-31T11:30:31.245Z", + "algorithm": "RS256", + "redirect_uris": "{0}://{1}:{2}/geoserver/index.html".format(net_scheme, + pub_ip, + pub_port) if pub_port else "{0}://{1}/geoserver/index.html".format(net_scheme, + pub_ip), + "name": "GeoServer", + "authorization_grant_type": "authorization-code", + "client_type": "confidential", + "client_id": "{0}".format(os.environ['OAUTH2_CLIENT_ID']), + "client_secret": "{0}".format(os.environ['OAUTH2_CLIENT_SECRET']), + "user": ["admin"]}}] with open('/tmp/default_oauth_apps_docker.json', 'w') as fixturefile: json.dump(default_fixture, fixturefile) @@ -465,9 +471,6 @@ def _prepare_site_fixture(): def _prepare_monitoring_fixture(): - upurl = urlparse(os.environ['SITEURL']) - net_scheme = upurl.scheme - net_loc = upurl.netloc pub_ip = _geonode_public_host_ip() print("Public Hostname or IP is {0}".format(pub_ip)) pub_port = _geonode_public_port() @@ -482,7 +485,7 @@ def _prepare_monitoring_fixture(): geoserver_ip = socket.gethostbyname('geoserver') except Exception: pass - #d = str(datetime.datetime.now()) + d = '1970-01-01 00:00:00' default_fixture = [ { @@ -572,22 +575,22 @@ def _prepare_admin_fixture(admin_password, admin_email): mdext_date = d.isoformat()[:23] + "Z" default_fixture = [ { - "fields": { - "date_joined": mdext_date, - "email": admin_email, - "first_name": "", - "groups": [], - "is_active": True, - "is_staff": True, - "is_superuser": True, - "last_login": mdext_date, - "last_name": "", - "password": make_password(admin_password), - "user_permissions": [], - "username": "admin" - }, - "model": "people.Profile", - "pk": 1000 + "fields": { + "date_joined": mdext_date, + "email": admin_email, + "first_name": "", + "groups": [], + "is_active": True, + "is_staff": True, + "is_superuser": True, + "last_login": mdext_date, + "last_name": "", + "password": make_password(admin_password), + "user_permissions": [], + "username": "admin" + }, + "model": "people.Profile", + "pk": 1000 } ] with open('/tmp/django_admin_docker.json', 'w') as fixturefile: