[extensions-web/wip/visual-tag: 1/2] extensions: improved metadata's session_modes handling
- From: Yuri Konotopov <ykonotopov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [extensions-web/wip/visual-tag: 1/2] extensions: improved metadata's session_modes handling
- Date: Mon, 9 May 2022 17:45:43 +0000 (UTC)
commit 370a2364b03e9028a8114cf4410a6fcbed62dbe5
Author: Yuri Konotopov <ykonotopov gnome org>
Date: Sun Apr 24 21:03:27 2022 +0400
extensions: improved metadata's session_modes handling
1. Save all session_modes with extension version
2. Pre-populate session_modes property for existent extensions
3. Added tests
.../0010_extension_session_unlock_dialog.py | 18 --------
.../extensions/migrations/0010_session_modes.py | 53 ++++++++++++++++++++++
sweettooth/extensions/models.py | 38 ++++++++++++----
.../extensions/templates/extensions/detail.html | 4 +-
sweettooth/extensions/tests.py | 50 +++++++++++++++++++-
sweettooth/extensions/views.py | 1 +
6 files changed, 135 insertions(+), 29 deletions(-)
---
diff --git a/sweettooth/extensions/migrations/0010_session_modes.py
b/sweettooth/extensions/migrations/0010_session_modes.py
new file mode 100644
index 0000000..f2c4459
--- /dev/null
+++ b/sweettooth/extensions/migrations/0010_session_modes.py
@@ -0,0 +1,53 @@
+import json
+
+from django.db import migrations, models
+from django.apps.registry import Apps
+from sweettooth.extensions.models import (
+ ExtensionVersion as ExtensionVersionModel,
+ SessionMode as SessionModeModel,
+)
+
+
+def apply(apps: Apps, schema_editor):
+ ExtensionVersion: ExtensionVersionModel = apps.get_model("extensions", "ExtensionVersion")
+ SessionMode: SessionModeModel = apps.get_model("extensions", "SessionMode")
+
+ for mode in SessionModeModel.SessionModes.values:
+ SessionMode.objects.create(mode=mode)
+
+ for version in ExtensionVersion.objects.all():
+ metadata = json.loads(version.extra_json_fields)
+ session_modes = [
+ SessionMode.objects.get(pk=mode)
+ for mode in metadata.get('session-modes', [])
+ ]
+
+ if session_modes:
+ version.session_modes.set(session_modes)
+ version.save()
+
+
+def revert(apps: Apps, schema_editor):
+ pass
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('extensions', '0009_shell40_minor_version'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='SessionMode',
+ fields=[
+ ('mode', models.CharField(choices=[('user', 'User'), ('unlock-dialog', 'Unlock Dialog'),
('gdm', 'Gdm')], max_length=16, primary_key=True, serialize=False)),
+ ],
+ ),
+ migrations.AddField(
+ model_name='extensionversion',
+ name='session_modes',
+ field=models.ManyToManyField(to='extensions.SessionMode'),
+ ),
+ migrations.RunPython(apply, revert),
+ ]
diff --git a/sweettooth/extensions/models.py b/sweettooth/extensions/models.py
index 1f11a30..c9b89ad 100644
--- a/sweettooth/extensions/models.py
+++ b/sweettooth/extensions/models.py
@@ -10,6 +10,7 @@
(at your option) any later version.
"""
+from typing import Any
import autoslug
import json
import os
@@ -104,6 +105,19 @@ def make_icon_filename(obj, filename=None):
return "icons/icon_%d%s" % (obj.pk, ext)
+class SessionMode(models.Model):
+ class SessionModes(models.TextChoices):
+ USER = 'user'
+ UNLOCK_DIALOG = 'unlock-dialog'
+ GDM = 'gdm'
+
+ mode = models.CharField(
+ primary_key=True,
+ max_length=16,
+ choices=SessionModes.choices,
+ )
+
+
class Extension(models.Model):
name = models.CharField(max_length=200)
uuid = models.CharField(max_length=200, unique=True, db_index=True)
@@ -111,7 +125,6 @@ class Extension(models.Model):
creator = models.ForeignKey(settings.AUTH_USER_MODEL, db_index=True, on_delete=models.PROTECT)
description = models.TextField(blank=True)
url = HttpURLField(blank=True)
- session_unlock_dialog = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
downloads = models.PositiveIntegerField(default=0)
popularity = models.IntegerField(default=0)
@@ -134,12 +147,6 @@ class Extension(models.Model):
self.description = metadata.pop('description', "")
self.url = metadata.pop('url', "")
self.uuid = metadata['uuid']
- try:
- session_info = metadata.pop('session-modes', "")
- if "unlock-dialog" in session_info or session_info is "unlock-dialog":
- self.session_unlock_dialog = True
- except:
- pass
def clean(self):
from django.core.exceptions import ValidationError
@@ -169,6 +176,14 @@ class Extension(models.Model):
return True
return False
+ def uses_session_mode(self, mode: str):
+ return any(
+ session_mode
+ for version in self.visible_versions.order_by('-pk')
+ for session_mode in version.session_modes.all()
+ if session_mode.mode == mode
+ )
+
@property
def first_line_of_description(self):
if not self.description:
@@ -358,6 +373,7 @@ class ExtensionVersion(models.Model):
extra_json_fields = models.TextField()
status = models.PositiveIntegerField(choices=STATUSES.items())
shell_versions = models.ManyToManyField(ShellVersion)
+ session_modes = models.ManyToManyField(SessionMode)
class Meta:
unique_together = ('extension', 'version'),
@@ -443,7 +459,7 @@ class ExtensionVersion(models.Model):
super().save(*args, **kwargs)
- def parse_metadata_json(self, metadata):
+ def parse_metadata_json(self, metadata: dict[str, Any]):
"""
Given the contents of a metadata.json file, fill in the fields
of the version and associated extension.
@@ -464,6 +480,12 @@ class ExtensionVersion(models.Model):
else:
self.shell_versions.add(sv)
+ if 'session-modes' in metadata:
+ self.session_modes.set([
+ SessionMode.objects.get(mode=mode)
+ for mode in metadata['session-modes']
+ ])
+
def get_absolute_url(self):
return self.extension.get_absolute_url()
diff --git a/sweettooth/extensions/templates/extensions/detail.html
b/sweettooth/extensions/templates/extensions/detail.html
index 65de4d2..2433e30 100644
--- a/sweettooth/extensions/templates/extensions/detail.html
+++ b/sweettooth/extensions/templates/extensions/detail.html
@@ -54,12 +54,12 @@
<dd><a href="{{ extension.url }}" id="extension_url">{{ extension.url }}</a></dd>
{% endif %}
</dl>
+ {% if extension_uses_unlock_dialog %}
<dl>
- {% if extension.session_unlock_dialog %}
<dt>{% trans "Session Mode(s)" %}</dt>
<dd><button type="disabled" class="btn btn-info btn-sm" title="{% trans "This extension will
run while the screen is locked" %}">{% trans "Unlock Dialog" %}</button></dd>
- {% endif %}
</dl>
+ {% endif %}
<dl>
<dt>{% trans "Download" %}</dt>
<dd class="extension-download">
diff --git a/sweettooth/extensions/tests.py b/sweettooth/extensions/tests.py
index 5bd3c46..309050f 100644
--- a/sweettooth/extensions/tests.py
+++ b/sweettooth/extensions/tests.py
@@ -2,7 +2,6 @@
import os.path
import json
import tempfile
-import unittest
from io import BytesIO
from uuid import uuid4
from zipfile import ZipFile
@@ -78,6 +77,55 @@ class ExtensionPropertiesTest(BasicUserTestCase, TestCase):
self.assertEqual(version.shell_versions_json, '["3.2", "3.2.1"]')
+ def test_session_mode(self):
+ metadata = {"uuid": "something1 example com",
+ "name": "Test Metadata",
+ "shell-version": ["42"],
+ "session-modes": [
+ 'forbidden'
+ ]}
+
+ extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
+ version = models.ExtensionVersion.objects.create(extension=extension,
+ status=models.STATUS_UNREVIEWED)
+ with self.assertRaises(models.SessionMode.DoesNotExist):
+ version.parse_metadata_json(metadata)
+
+ metadata = {"uuid": "something2 example com",
+ "name": "Test Metadata",
+ "session-modes": [
+ 'unlock-dialog'
+ ]}
+ extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
+ version = models.ExtensionVersion.objects.create(extension=extension,
+ status=models.STATUS_UNREVIEWED)
+ version.parse_metadata_json(metadata)
+ version.save()
+
+ self.assertEqual([mode.mode for mode in version.session_modes.all()], ['unlock-dialog'])
+ self.assertFalse(extension.uses_session_mode('unlock-dialog'))
+
+ version.status = models.STATUS_ACTIVE
+ version.save()
+ self.assertTrue(extension.uses_session_mode('unlock-dialog'))
+
+ metadata = {"uuid": "something3 example com",
+ "name": "Test Metadata",
+ "session-modes": [
+ 'gdm',
+ 'unlock-dialog'
+ ]}
+ extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
+ version = models.ExtensionVersion.objects.create(extension=extension,
+ status=models.STATUS_ACTIVE)
+ version.parse_metadata_json(metadata)
+ version.save()
+
+ self.assertEqual([mode.mode for mode in version.session_modes.all()], ['gdm', 'unlock-dialog'])
+ self.assertTrue(extension.uses_session_mode('gdm'))
+ self.assertTrue(extension.uses_session_mode('unlock-dialog'))
+ self.assertFalse(extension.uses_session_mode('user'))
+
class ParseZipfileTest(BasicUserTestCase, TestCase):
def test_simple_metadata(self):
metadata = {"uuid": "test-metadata mecheye net",
diff --git a/sweettooth/extensions/views.py b/sweettooth/extensions/views.py
index 005a1ef..1594ec8 100644
--- a/sweettooth/extensions/views.py
+++ b/sweettooth/extensions/views.py
@@ -308,6 +308,7 @@ def extension_view(request, obj, **kwargs):
context = dict(shell_version_map = json.dumps(extension.visible_shell_version_map),
extension = extension,
+ extension_uses_unlock_dialog = extension.uses_session_mode('unlock-dialog'),
all_versions = extension.versions.order_by('-version'),
visible_versions=json.dumps(extension.visible_shell_version_array),
is_visible = extension.latest_version is not None,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]