From 81c8b06f885b6ef159a49d1bd30b75592b281aa4 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 5 Nov 2024 20:22:24 +0100 Subject: [PATCH 1/8] Addons: API response for tooltips Initial `addons.tooltips` object with basic data for testing purposes. --- readthedocs/proxito/views/hosting.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readthedocs/proxito/views/hosting.py b/readthedocs/proxito/views/hosting.py index dc6a89110bb..ca88635399b 100644 --- a/readthedocs/proxito/views/hosting.py +++ b/readthedocs/proxito/views/hosting.py @@ -510,6 +510,14 @@ def _v1(self, project, version, build, filename, url, request): if version else None, }, + "tooltips": { + "enabled": True, + "css_selector": "[role=main] a.internal", + "doctool": { + "name": "sphinx", + "version": "8.0.3", + }, + }, "hotkeys": { "enabled": project.addons.hotkeys_enabled, "doc_diff": { From 33dc2ab465805723ebda0dc62378a918f519a9c6 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 6 Nov 2024 10:21:58 +0100 Subject: [PATCH 2/8] Add model fields for tooltips --- .../migrations/0131_addons_tooltips_fields.py | 55 +++++++++++++++++++ readthedocs/projects/models.py | 7 +++ readthedocs/proxito/views/hosting.py | 9 +-- 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 readthedocs/projects/migrations/0131_addons_tooltips_fields.py diff --git a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py new file mode 100644 index 00000000000..76f3e639974 --- /dev/null +++ b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py @@ -0,0 +1,55 @@ +# Generated by Django 4.2.16 on 2024-11-06 09:18 + +from django.db import migrations, models +from django_safemigrate import Safe + + +class Migration(migrations.Migration): + safe = Safe.before_deploy + + dependencies = [ + ('projects', '0130_addons_remove_old_fields'), + ] + + operations = [ + migrations.AddField( + model_name='addonsconfig', + name='tooltips_doctool_name', + field=models.CharField(blank=True, max_length=128, null=True), + ), + migrations.AddField( + model_name='addonsconfig', + name='tooltips_doctool_version', + field=models.CharField(blank=True, max_length=128, null=True), + ), + migrations.AddField( + model_name='addonsconfig', + name='tooltips_enabled', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='addonsconfig', + name='tooltips_root_selector', + field=models.CharField(blank=True, max_length=128, null=True), + ), + migrations.AddField( + model_name='historicaladdonsconfig', + name='tooltips_doctool_name', + field=models.CharField(blank=True, max_length=128, null=True), + ), + migrations.AddField( + model_name='historicaladdonsconfig', + name='tooltips_doctool_version', + field=models.CharField(blank=True, max_length=128, null=True), + ), + migrations.AddField( + model_name='historicaladdonsconfig', + name='tooltips_enabled', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='historicaladdonsconfig', + name='tooltips_root_selector', + field=models.CharField(blank=True, max_length=128, null=True), + ), + ] diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index 66371a96845..7c734815ba4 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -144,6 +144,7 @@ class AddonsConfig(TimeStampedModel): """ DOC_DIFF_DEFAULT_ROOT_SELECTOR = "[role=main]" + TOOLTIPS_DEFAULT_ROOT_SELECTOR = "[role=main] a.internal" # Model history history = ExtraHistoricalRecords() @@ -218,6 +219,12 @@ class AddonsConfig(TimeStampedModel): notifications_show_on_non_stable = models.BooleanField(default=True) notifications_show_on_external = models.BooleanField(default=True) + # Tooltips + tooltips_enabled = models.BooleanField(default=False) + tooltips_root_selector = models.CharField(null=True, blank=True, max_length=128) + tooltips_doctool_name = models.CharField(null=True, blank=True, max_length=128) + tooltips_doctool_version = models.CharField(null=True, blank=True, max_length=128) + class AddonSearchFilter(TimeStampedModel): diff --git a/readthedocs/proxito/views/hosting.py b/readthedocs/proxito/views/hosting.py index ca88635399b..50664b03040 100644 --- a/readthedocs/proxito/views/hosting.py +++ b/readthedocs/proxito/views/hosting.py @@ -511,11 +511,12 @@ def _v1(self, project, version, build, filename, url, request): else None, }, "tooltips": { - "enabled": True, - "css_selector": "[role=main] a.internal", + "enabled": project.addons.tooltips_enabled, + "root_selector": project.addons.tooltips_root_selector + or project.addons.TOOLTIPS_DEFAULT_ROOT_SELECTOR, "doctool": { - "name": "sphinx", - "version": "8.0.3", + "name": project.addons.tooltips_doctool_name, + "version": project.addons.tooltips_doctool_version, }, }, "hotkeys": { From 68d25bc8bc49096824641e7c8908828166d88177 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 6 Nov 2024 10:36:39 +0100 Subject: [PATCH 3/8] Add tests for tooltips --- readthedocs/proxito/tests/responses/v1.json | 8 +++++ readthedocs/proxito/tests/test_hosting.py | 36 +++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/readthedocs/proxito/tests/responses/v1.json b/readthedocs/proxito/tests/responses/v1.json index 2fdeed829a5..bf168c8a0be 100644 --- a/readthedocs/proxito/tests/responses/v1.json +++ b/readthedocs/proxito/tests/responses/v1.json @@ -160,6 +160,14 @@ "enabled": true, "default_filter": "project:project/latest", "filters": [] + }, + "tooltips": { + "enabled": false, + "root_selector": "[role=main] a.internal", + "doctool": { + "name": null, + "version": null + } } } } diff --git a/readthedocs/proxito/tests/test_hosting.py b/readthedocs/proxito/tests/test_hosting.py index fc1e23c12f0..6570eb641ad 100644 --- a/readthedocs/proxito/tests/test_hosting.py +++ b/readthedocs/proxito/tests/test_hosting.py @@ -722,6 +722,42 @@ def test_custom_domain_url(self): == "https://docs.example.com/en/latest/" ) + def test_tooltips(self): + addons = fixture.get( + AddonsConfig, + project=self.project, + ) + + addons.tooltips_enabled = True + addons.tooltips_root_selector = "[role=main] a" + addons.tooltips_doctool_name = "sphinx" + addons.tooltips_doctool_version = "8.0.1" + addons.save() + + r = self.client.get( + reverse("proxito_readthedocs_docs_addons"), + { + "api-version": "1.0.0", + "client-version": "0.6.0", + "url": "https://project.dev.readthedocs.io/en/latest/", + }, + secure=True, + headers={ + "host": "project.dev.readthedocs.io", + }, + ) + expected = { + "enabled": True, + "root_selector": "[role=main] a", + "doctool": { + "name": "sphinx", + "version": "8.0.1", + }, + } + + assert r.status_code == 200 + assert r.json()["addons"]["tooltips"] == expected + def test_non_existent_project(self): r = self.client.get( reverse("proxito_readthedocs_docs_addons"), From 4d7e9e9a7d78df916406598d102a7371be7cffb6 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 6 Nov 2024 10:49:43 +0100 Subject: [PATCH 4/8] Form for tooltips addons --- readthedocs/projects/forms.py | 9 ++++++++- readthedocs/projects/models.py | 11 ++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/readthedocs/projects/forms.py b/readthedocs/projects/forms.py index 3a86a98197c..678a78abb46 100644 --- a/readthedocs/projects/forms.py +++ b/readthedocs/projects/forms.py @@ -660,6 +660,10 @@ class Meta: "flyout_sorting_custom_pattern", "hotkeys_enabled", "search_enabled", + "tooltips_enabled", + "tooltips_root_selector", + "tooltips_doctool_name", + "tooltips_doctool_version", "notifications_enabled", "notifications_show_on_latest", "notifications_show_on_non_stable", @@ -677,7 +681,10 @@ class Meta: } widgets = { "doc_diff_root_selector": forms.TextInput( - attrs={"placeholder": "[role=main]"} + attrs={"placeholder": AddonsConfig.DOC_DIFF_DEFAULT_ROOT_SELECTOR} + ), + "tooltips_root_selector": forms.TextInput( + attrs={"placeholder": AddonsConfig.TOOLTIPS_DEFAULT_ROOT_SELECTOR} ), } diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index 7c734815ba4..5b27015c882 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -145,6 +145,10 @@ class AddonsConfig(TimeStampedModel): DOC_DIFF_DEFAULT_ROOT_SELECTOR = "[role=main]" TOOLTIPS_DEFAULT_ROOT_SELECTOR = "[role=main] a.internal" + TOOLTIPS_DOCTOOL_NAME_CHOICES = ( + ("sphinx", "Sphinx"), + ("other", "Other"), + ) # Model history history = ExtraHistoricalRecords() @@ -222,7 +226,12 @@ class AddonsConfig(TimeStampedModel): # Tooltips tooltips_enabled = models.BooleanField(default=False) tooltips_root_selector = models.CharField(null=True, blank=True, max_length=128) - tooltips_doctool_name = models.CharField(null=True, blank=True, max_length=128) + tooltips_doctool_name = models.CharField( + choices=TOOLTIPS_DOCTOOL_NAME_CHOICES, + null=True, + blank=True, + max_length=128, + ) tooltips_doctool_version = models.CharField(null=True, blank=True, max_length=128) From 1cd0f69fc9ef05a7aa655022064307e545d15141 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 6 Nov 2024 10:54:37 +0100 Subject: [PATCH 5/8] Update charfield for choices --- .../projects/migrations/0131_addons_tooltips_fields.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py index 76f3e639974..fc7b2fc04de 100644 --- a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py +++ b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py @@ -12,10 +12,10 @@ class Migration(migrations.Migration): ] operations = [ - migrations.AddField( + migrations.AlterField( model_name='addonsconfig', name='tooltips_doctool_name', - field=models.CharField(blank=True, max_length=128, null=True), + field=models.CharField(blank=True, choices=[('sphinx', 'Sphinx'), ('other', 'Other')], max_length=128, null=True), ), migrations.AddField( model_name='addonsconfig', @@ -32,10 +32,10 @@ class Migration(migrations.Migration): name='tooltips_root_selector', field=models.CharField(blank=True, max_length=128, null=True), ), - migrations.AddField( + migrations.AlterField( model_name='historicaladdonsconfig', name='tooltips_doctool_name', - field=models.CharField(blank=True, max_length=128, null=True), + field=models.CharField(blank=True, choices=[('sphinx', 'Sphinx'), ('other', 'Other')], max_length=128, null=True), ), migrations.AddField( model_name='historicaladdonsconfig', From 7b33bc6cf2d3a7d1e864365efcd750d4103ca53c Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 7 Nov 2024 11:46:41 +0100 Subject: [PATCH 6/8] Typo --- readthedocs/projects/migrations/0131_addons_tooltips_fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py index fc7b2fc04de..2a360302965 100644 --- a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py +++ b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py @@ -12,7 +12,7 @@ class Migration(migrations.Migration): ] operations = [ - migrations.AlterField( + migrations.AddField( model_name='addonsconfig', name='tooltips_doctool_name', field=models.CharField(blank=True, choices=[('sphinx', 'Sphinx'), ('other', 'Other')], max_length=128, null=True), From 860676e4bc42f3a95c4c57697b98409a8277c4fd Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 7 Nov 2024 11:59:03 +0100 Subject: [PATCH 7/8] Meh, same typo --- readthedocs/projects/migrations/0131_addons_tooltips_fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py index 2a360302965..88dcbf955e1 100644 --- a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py +++ b/readthedocs/projects/migrations/0131_addons_tooltips_fields.py @@ -32,7 +32,7 @@ class Migration(migrations.Migration): name='tooltips_root_selector', field=models.CharField(blank=True, max_length=128, null=True), ), - migrations.AlterField( + migrations.AddField( model_name='historicaladdonsconfig', name='tooltips_doctool_name', field=models.CharField(blank=True, choices=[('sphinx', 'Sphinx'), ('other', 'Other')], max_length=128, null=True), From 1fbb5f1b66e5e63c013b4848212502b59610093c Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 12 Nov 2024 13:27:05 +0100 Subject: [PATCH 8/8] Rename "tooltips" by "link previews" --- readthedocs/projects/forms.py | 16 +++++++++------ ....py => 0131_addons_linkpreviews_fields.py} | 16 +++++++-------- readthedocs/projects/models.py | 20 +++++++++++-------- readthedocs/proxito/tests/responses/v1.json | 2 +- readthedocs/proxito/tests/test_hosting.py | 12 +++++------ readthedocs/proxito/views/hosting.py | 12 +++++------ 6 files changed, 43 insertions(+), 35 deletions(-) rename readthedocs/projects/migrations/{0131_addons_tooltips_fields.py => 0131_addons_linkpreviews_fields.py} (81%) diff --git a/readthedocs/projects/forms.py b/readthedocs/projects/forms.py index 678a78abb46..ca2c7b24455 100644 --- a/readthedocs/projects/forms.py +++ b/readthedocs/projects/forms.py @@ -660,10 +660,10 @@ class Meta: "flyout_sorting_custom_pattern", "hotkeys_enabled", "search_enabled", - "tooltips_enabled", - "tooltips_root_selector", - "tooltips_doctool_name", - "tooltips_doctool_version", + "linkpreviews_enabled", + "linkpreviews_root_selector", + "linkpreviews_doctool_name", + "linkpreviews_doctool_version", "notifications_enabled", "notifications_show_on_latest", "notifications_show_on_non_stable", @@ -678,13 +678,17 @@ class Meta: "Show a notification on non-stable versions" ), "notifications_show_on_latest": _("Show a notification on latest version"), + "linkpreviews_enabled": _("Enabled"), + "linkpreviews_root_selector": _("Root selector"), + "linkpreviews_doctool_name": _("Documentation tool name"), + "linkpreviews_doctool_version": _("Documentation tool version"), } widgets = { "doc_diff_root_selector": forms.TextInput( attrs={"placeholder": AddonsConfig.DOC_DIFF_DEFAULT_ROOT_SELECTOR} ), - "tooltips_root_selector": forms.TextInput( - attrs={"placeholder": AddonsConfig.TOOLTIPS_DEFAULT_ROOT_SELECTOR} + "linkpreviews_root_selector": forms.TextInput( + attrs={"placeholder": AddonsConfig.LINKPREVIEWS_DEFAULT_ROOT_SELECTOR} ), } diff --git a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py b/readthedocs/projects/migrations/0131_addons_linkpreviews_fields.py similarity index 81% rename from readthedocs/projects/migrations/0131_addons_tooltips_fields.py rename to readthedocs/projects/migrations/0131_addons_linkpreviews_fields.py index 88dcbf955e1..f19b9602677 100644 --- a/readthedocs/projects/migrations/0131_addons_tooltips_fields.py +++ b/readthedocs/projects/migrations/0131_addons_linkpreviews_fields.py @@ -14,42 +14,42 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( model_name='addonsconfig', - name='tooltips_doctool_name', + name='linkpreviews_doctool_name', field=models.CharField(blank=True, choices=[('sphinx', 'Sphinx'), ('other', 'Other')], max_length=128, null=True), ), migrations.AddField( model_name='addonsconfig', - name='tooltips_doctool_version', + name='linkpreviews_doctool_version', field=models.CharField(blank=True, max_length=128, null=True), ), migrations.AddField( model_name='addonsconfig', - name='tooltips_enabled', + name='linkpreviews_enabled', field=models.BooleanField(default=False), ), migrations.AddField( model_name='addonsconfig', - name='tooltips_root_selector', + name='linkpreviews_root_selector', field=models.CharField(blank=True, max_length=128, null=True), ), migrations.AddField( model_name='historicaladdonsconfig', - name='tooltips_doctool_name', + name='linkpreviews_doctool_name', field=models.CharField(blank=True, choices=[('sphinx', 'Sphinx'), ('other', 'Other')], max_length=128, null=True), ), migrations.AddField( model_name='historicaladdonsconfig', - name='tooltips_doctool_version', + name='linkpreviews_doctool_version', field=models.CharField(blank=True, max_length=128, null=True), ), migrations.AddField( model_name='historicaladdonsconfig', - name='tooltips_enabled', + name='linkpreviews_enabled', field=models.BooleanField(default=False), ), migrations.AddField( model_name='historicaladdonsconfig', - name='tooltips_root_selector', + name='linkpreviews_root_selector', field=models.CharField(blank=True, max_length=128, null=True), ), ] diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index 5b27015c882..a174d77c6e2 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -144,8 +144,8 @@ class AddonsConfig(TimeStampedModel): """ DOC_DIFF_DEFAULT_ROOT_SELECTOR = "[role=main]" - TOOLTIPS_DEFAULT_ROOT_SELECTOR = "[role=main] a.internal" - TOOLTIPS_DOCTOOL_NAME_CHOICES = ( + LINKPREVIEWS_DEFAULT_ROOT_SELECTOR = "[role=main] a.internal" + LINKPREVIEWS_DOCTOOL_NAME_CHOICES = ( ("sphinx", "Sphinx"), ("other", "Other"), ) @@ -223,16 +223,20 @@ class AddonsConfig(TimeStampedModel): notifications_show_on_non_stable = models.BooleanField(default=True) notifications_show_on_external = models.BooleanField(default=True) - # Tooltips - tooltips_enabled = models.BooleanField(default=False) - tooltips_root_selector = models.CharField(null=True, blank=True, max_length=128) - tooltips_doctool_name = models.CharField( - choices=TOOLTIPS_DOCTOOL_NAME_CHOICES, + # Link Previews + linkpreviews_enabled = models.BooleanField(default=False) + linkpreviews_root_selector = models.CharField(null=True, blank=True, max_length=128) + linkpreviews_doctool_name = models.CharField( + choices=LINKPREVIEWS_DOCTOOL_NAME_CHOICES, + null=True, + blank=True, + max_length=128, + ) + linkpreviews_doctool_version = models.CharField( null=True, blank=True, max_length=128, ) - tooltips_doctool_version = models.CharField(null=True, blank=True, max_length=128) class AddonSearchFilter(TimeStampedModel): diff --git a/readthedocs/proxito/tests/responses/v1.json b/readthedocs/proxito/tests/responses/v1.json index bf168c8a0be..70e6fa26556 100644 --- a/readthedocs/proxito/tests/responses/v1.json +++ b/readthedocs/proxito/tests/responses/v1.json @@ -161,7 +161,7 @@ "default_filter": "project:project/latest", "filters": [] }, - "tooltips": { + "linkpreviews": { "enabled": false, "root_selector": "[role=main] a.internal", "doctool": { diff --git a/readthedocs/proxito/tests/test_hosting.py b/readthedocs/proxito/tests/test_hosting.py index 6570eb641ad..ebfcb02f684 100644 --- a/readthedocs/proxito/tests/test_hosting.py +++ b/readthedocs/proxito/tests/test_hosting.py @@ -722,16 +722,16 @@ def test_custom_domain_url(self): == "https://docs.example.com/en/latest/" ) - def test_tooltips(self): + def test_linkpreviews(self): addons = fixture.get( AddonsConfig, project=self.project, ) - addons.tooltips_enabled = True - addons.tooltips_root_selector = "[role=main] a" - addons.tooltips_doctool_name = "sphinx" - addons.tooltips_doctool_version = "8.0.1" + addons.linkpreviews_enabled = True + addons.linkpreviews_root_selector = "[role=main] a" + addons.linkpreviews_doctool_name = "sphinx" + addons.linkpreviews_doctool_version = "8.0.1" addons.save() r = self.client.get( @@ -756,7 +756,7 @@ def test_tooltips(self): } assert r.status_code == 200 - assert r.json()["addons"]["tooltips"] == expected + assert r.json()["addons"]["linkpreviews"] == expected def test_non_existent_project(self): r = self.client.get( diff --git a/readthedocs/proxito/views/hosting.py b/readthedocs/proxito/views/hosting.py index 50664b03040..07b05864e0c 100644 --- a/readthedocs/proxito/views/hosting.py +++ b/readthedocs/proxito/views/hosting.py @@ -510,13 +510,13 @@ def _v1(self, project, version, build, filename, url, request): if version else None, }, - "tooltips": { - "enabled": project.addons.tooltips_enabled, - "root_selector": project.addons.tooltips_root_selector - or project.addons.TOOLTIPS_DEFAULT_ROOT_SELECTOR, + "linkpreviews": { + "enabled": project.addons.linkpreviews_enabled, + "root_selector": project.addons.linkpreviews_root_selector + or project.addons.LINKPREVIEWS_DEFAULT_ROOT_SELECTOR, "doctool": { - "name": project.addons.tooltips_doctool_name, - "version": project.addons.tooltips_doctool_version, + "name": project.addons.linkpreviews_doctool_name, + "version": project.addons.linkpreviews_doctool_version, }, }, "hotkeys": {