Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for renaming plugin package_name #271

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion qgis-app/plugins/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from django.contrib import admin
from plugins.models import Plugin, PluginVersion # , PluginCrashReport
from plugins.models import (
Plugin, PluginVersion,
PluginLegacyName# , PluginCrashReport
)


class PluginAdmin(admin.ModelAdmin):
Expand All @@ -26,12 +29,28 @@ class PluginVersionAdmin(admin.ModelAdmin):
"created_on",
"downloads",
)
search_fields = (
'plugin__name',
)


# class PluginCrashReportAdmin(admin.ModelAdmin):
# pass


class PluginLegacyNameAdmin(admin.ModelAdmin):
list_display = (
'plugin',
'package_name',
'created_on'
)
readonly_fields = (
'created_on',
'package_name'
)


admin.site.register(Plugin, PluginAdmin)
admin.site.register(PluginVersion, PluginVersionAdmin)
admin.site.register(PluginLegacyName, PluginLegacyNameAdmin)
# admin.site.register(PluginCrashReport, PluginCrashReportAdmin)
4 changes: 4 additions & 0 deletions qgis-app/plugins/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ def plugin_upload(package, **kwargs):
}

# Gets existing plugin
if Plugin.objects.filter(
name__iexact=plugin_data['name']
).exclude(package_name__iexact=plugin_data['package_name']).count():
raise Fault(1, 'Error: The package name for this plugin has changed.')
try:
plugin = Plugin.objects.get(package_name=plugin_data["package_name"])
# Apply new values
Expand Down
28 changes: 28 additions & 0 deletions qgis-app/plugins/migrations/0002_auto_20230314_0341.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 2.2.25 on 2023-03-14 03:41

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('plugins', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='plugin',
name='package_name',
field=models.CharField(help_text="This is the plugin's internal name, equals to the main folder name. Must start with an ASCII letter and can contain only ASCII letters, digits and the - and _ signs.", max_length=256, unique=True, verbose_name='Package Name'),
),
migrations.CreateModel(
name='PluginLegacyName',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_on', models.DateTimeField(auto_now_add=True, verbose_name='Created on')),
('package_name', models.CharField(blank=True, editable=False, help_text="This is the plugin's internal name, equals to the main folder name", max_length=256, null=True, verbose_name='Package Name')),
('plugin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='plugins.Plugin')),
],
),
]
59 changes: 55 additions & 4 deletions qgis-app/plugins/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.db.models import Q
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from djangoratings.fields import AnonymousRatingField
Expand Down Expand Up @@ -309,11 +310,12 @@ class Plugin(models.Model):
package_name = models.CharField(
_("Package Name"),
help_text=_(
"This is the plugin's internal name, equals to the main folder name"
"This is the plugin's internal name, equals to the main folder name. "
"Must start with an ASCII letter and can contain only ASCII letters, digits and the - and _ signs."
),
max_length=256,
unique=True,
editable=False,
editable=True,
)
name = models.CharField(
_("Name"), help_text=_("Must be unique"), max_length=256, unique=True
Expand Down Expand Up @@ -471,11 +473,16 @@ def clean(self):
)

if self.pk:
qs = Plugin.objects.filter(package_name__iexact=self.package_name).exclude(
qs = Plugin.objects.filter(
Q(package_name__iexact=self.package_name) |
Q(pluginlegacyname__package_name__iexact=self.package_name)
).exclude(
pk=self.pk
)
else:
qs = Plugin.objects.filter(package_name__iexact=self.package_name)
qs = Plugin.objects.filter(
Q(package_name__iexact=self.package_name) |
Q(pluginlegacyname__package_name__iexact=self.package_name))
if qs.count():
raise ValidationError(
_(
Expand Down Expand Up @@ -768,6 +775,30 @@ def __str__(self):
return self.__unicode__()


class PluginLegacyName(models.Model):
plugin = models.ForeignKey(
Plugin,
on_delete=models.CASCADE)

created_on = models.DateTimeField(
_("Created on"),
auto_now_add=True,
editable=False
)

# name, desc etc.
package_name = models.CharField(
_("Package Name"),
help_text=_(
"This is the plugin's internal name, equals to the main folder name"
),
null=True,
blank=True,
max_length=256,
editable=False,
)


def delete_version_package(sender, instance, **kw):
"""
Removes the zip package
Expand All @@ -788,5 +819,25 @@ def delete_plugin_icon(sender, instance, **kw):
pass


def plugin_rename(sender, instance, **kwargs):
"""
Add old plugin name to plugin_legacy_name
"""
if not PluginVersion.objects.filter(
plugin=instance
).exists():
return None
try:
old_instance = Plugin.objects.get(id=instance.id)
if old_instance.package_name != instance.package_name:
PluginLegacyName.objects.get_or_create(
plugin=instance,
package_name=old_instance.package_name
)
except Plugin.DoesNotExist:
return None


models.signals.post_delete.connect(delete_version_package, sender=PluginVersion)
models.signals.post_delete.connect(delete_plugin_icon, sender=Plugin)
models.signals.pre_save.connect(plugin_rename, sender=Plugin)
4 changes: 1 addition & 3 deletions qgis-app/plugins/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,7 @@
urlpatterns += [
url(
r"^(?P<package_name>[A-Za-z][A-Za-z0-9-_]+)/$",
PluginDetailView.as_view(
slug_url_kwarg="package_name", slug_field="package_name"
),
PluginDetailView.as_view(),
name="plugin_detail",
),
]
44 changes: 39 additions & 5 deletions qgis-app/plugins/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@
from plugins.tasks.generate_plugins_xml import generate_plugins_xml


def get_plugin(package_name: str) -> Plugin:
"""Get the plugin from package_name"""
try:
return Plugin.objects.get(
Q(package_name=package_name) |
Q(pluginlegacyname__package_name=package_name)
)
except Plugin.DoesNotExist:
raise Http404()


def send_mail_wrapper(subject, message, mail_from, recipients, fail_silently=True):
if settings.DEBUG:
logging.debug("Mail not sent (DEBUG=True)")
Expand Down Expand Up @@ -297,6 +308,7 @@ def plugin_upload(request):
"""
if request.method == "POST":
form = PackageUploadForm(request.POST, request.FILES)
plugin = None
if form.is_valid():
try:
plugin_data = {
Expand All @@ -306,11 +318,20 @@ def plugin_upload(request):
"created_by": request.user,
"author": form.cleaned_data["author"],
"email": form.cleaned_data["email"],
"created_by": request.user,
"icon": form.cleaned_data["icon_file"],
}

# Gets existing plugin
if Plugin.objects.filter(
name__iexact=plugin_data['name']
).exclude(
package_name__iexact=plugin_data['package_name']
).count():
raise ValidationError(
_(
'Error: The package name for this plugin has changed.'
)
)
try:
plugin = Plugin.objects.get(
package_name=plugin_data["package_name"]
Expand Down Expand Up @@ -381,7 +402,7 @@ def plugin_upload(request):
# Takes care of tags
if form.cleaned_data.get("tags"):
plugin.tags.set(
*[
[
t.strip().lower()
for t in form.cleaned_data.get("tags").split(",")
]
Expand Down Expand Up @@ -434,7 +455,7 @@ def plugin_upload(request):
except (IntegrityError, ValidationError, DjangoUnicodeDecodeError) as e:
connection.close()
messages.error(request, e, fail_silently=True)
if not plugin.pk:
if not plugin or not plugin.pk:
return render(request, "plugins/plugin_upload.html", {"form": form})
return HttpResponseRedirect(plugin.get_absolute_url())
else:
Expand All @@ -447,6 +468,19 @@ class PluginDetailView(DetailView):
model = Plugin
queryset = Plugin.objects.all()

def get_object(self, queryset=None):
if queryset is None:
queryset = self.get_queryset()
package_name = self.kwargs.get('package_name')
try:
return queryset.get(
Q(package_name__iexact=package_name) |
Q(pluginlegacyname__package_name__iexact=package_name)
)
except Plugin.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})

@method_decorator(ensure_csrf_cookie)
def dispatch(self, *args, **kwargs):
return super(PluginDetailView, self).dispatch(*args, **kwargs)
Expand Down Expand Up @@ -1022,7 +1056,7 @@ def version_download(request, package_name, version):
"""
Update download counter(s)
"""
plugin = get_object_or_404(Plugin, package_name=package_name)
plugin = get_plugin(package_name)
version = get_object_or_404(PluginVersion, plugin=plugin, version=version)
version.downloads = version.downloads + 1
version.save()
Expand All @@ -1045,7 +1079,7 @@ def version_detail(request, package_name, version):
"""
Show version details
"""
plugin = get_object_or_404(Plugin, package_name=package_name)
plugin = get_plugin(package_name)
version = get_object_or_404(PluginVersion, plugin=plugin, version=version)
return render(request, "plugins/version_detail.html", {"version": version})

Expand Down
18 changes: 18 additions & 0 deletions qgis-app/static/style/new/basic.css
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,21 @@ div.sphinxsidebar, div.related, div.footer, #top-link {
display: none;
}
}

.navbar-search {
display: flex;
flex-direction: row;
align-items: center;
}

.navbar-search #id_q {
border-radius: 12px 0 0 12px;
color: black;
}

.btn-search {
width: fit-content !important;
margin-top: 0 !important;
border-radius: 0 12px 12px 0 !important;
}

40 changes: 36 additions & 4 deletions qgis-app/static/style/new/qgis-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,16 @@ pre, code {
text-decoration:none !important;
}

.signin-wrapper {
height: 60px;
float: right !important;
display: flex;
align-items: center;
padding: 0 20px 0 20px;
}

.icon-signin {
color: #fff;
top: 100px !important;
float: right !important;
margin: 16px 0 0 20px !important;
text-decoration:none !important;
}

.navbar-inner > select body, .navbar-inner > select html {
Expand Down Expand Up @@ -770,3 +774,31 @@ section.sponsors {
height: 16px;
display:block;
}


@media (max-width: 500px) {
#page_bg {
width: 100%;
}
.navbar .brand {
background-size: 30px !important;
height: 30px;
width: 30px;
margin: 10px 0 0 0 !important;
}

.navbar-search {
margin: 10px 0 0 0 !important;
}

.signin-wrapper {
height: 100%;
margin-top: 3px;
}
}

@media (max-width: 375px) {
.navbar .brand {
display: none;
}
}
18 changes: 10 additions & 8 deletions qgis-app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,19 @@
<span class="icon-bar"></span>
</button>

<a class="brand" href="https://www.qgis.org">QGIS</a>
{% if user.is_authenticated %}
<a id="user-tooltip" href="{% if user.is_superuser %}{% url "admin:index" %}{% else %}{% url "logout" %}{% endif %}"
data-toggle="tooltip" data-placement="bottom" title="{{ user.username }}" style="float: right !important"><i class="icon-user icon-3x"></i></a>
{% else %}
<a href="{% url "login" %}"><i class="icon-signin icon-3x"></i></a>
{% endif %}
<a class="brand" href="https://www.qgis.org">QGIS</a>
{% if user.is_authenticated %}
<a id="user-tooltip" href="{% if user.is_superuser %}{% url "admin:index" %}{% else %}{% url "logout" %}{% endif %}"
data-toggle="tooltip" data-placement="bottom" title="{{ user.username }}" style="float: right !important"><i class="icon-user icon-3x"></i></a>
{% else %}
<div class="signin-wrapper">
<a href="{% url "login" %}"><i class="icon-signin icon-3x"></i></a>
</div>
{% endif %}

<form class="navbar-search" action="{% url "haystack_search" %}" method="get">
<input type="text" id="id_q" name="q" class="search-query" placeholder="Search" />
<input type="submit" class="btn" value="Search" />
<button type="submit" class="btn btn-search"><i class="icon-search" aria-hidden="true"></i></button>
</form>

{% get_namedmenu Navigation as menu %}
Expand Down