Support to export blocks/mutes as CSV files (#626)
This commit is contained in:
parent
4a9109271d
commit
67d755e6d3
|
@ -65,6 +65,16 @@ urlpatterns = [
|
|||
settings.CsvFollowers.as_view(),
|
||||
name="settings_export_followers_csv",
|
||||
),
|
||||
path(
|
||||
"@<handle>/settings/import_export/blocks.csv",
|
||||
settings.CsvBlocks.as_view(),
|
||||
name="settings_export_blocks_csv",
|
||||
),
|
||||
path(
|
||||
"@<handle>/settings/import_export/mutes.csv",
|
||||
settings.CsvMutes.as_view(),
|
||||
name="settings_export_mutes_csv",
|
||||
),
|
||||
path(
|
||||
"@<handle>/settings/migrate_in/",
|
||||
settings.MigrateInPage.as_view(),
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
<small>{{ numbers.blocks }} {{ numbers.blocks|pluralize:"people,people" }}</small>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<a href="{% url "settings_export_blocks_csv" handle=identity.handle %}">Download CSV</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -59,7 +59,7 @@
|
|||
<small>{{ numbers.mutes }} {{ numbers.mutes|pluralize:"people,people" }}</small>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<a href="{% url "settings_export_mutes_csv" handle=identity.handle %}">Download CSV</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -88,3 +88,92 @@ def test_export_followers(
|
|||
)
|
||||
assert response.status_code == 200
|
||||
assert response.content.strip() == b"Account address\r\ntest@example2.com"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_export_blocks(
|
||||
client_with_user: Client,
|
||||
identity: Identity,
|
||||
identity2: Identity,
|
||||
stator: StatorRunner,
|
||||
httpx_mock: HTTPXMock,
|
||||
):
|
||||
"""
|
||||
Validates the "export a CSV of blocked users" functionality works
|
||||
"""
|
||||
# Block remote_identity
|
||||
IdentityService(identity).block(identity2)
|
||||
|
||||
# Run stator to process it
|
||||
stator.run_single_cycle()
|
||||
|
||||
# Download the CSV
|
||||
response = client_with_user.get(
|
||||
f"/@{identity.handle}/settings/import_export/blocks.csv"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.content.strip() == b"Account address\r\ntest@example2.com"
|
||||
|
||||
# Unblock should clear the CSV content
|
||||
IdentityService(identity).unblock(identity2)
|
||||
|
||||
# Run stator to process it
|
||||
stator.run_single_cycle()
|
||||
|
||||
response = client_with_user.get(
|
||||
f"/@{identity.handle}/settings/import_export/blocks.csv"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.content.strip() == b"Account address"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_export_mutes(
|
||||
client_with_user: Client,
|
||||
identity: Identity,
|
||||
identity2: Identity,
|
||||
stator: StatorRunner,
|
||||
httpx_mock: HTTPXMock,
|
||||
):
|
||||
"""
|
||||
Validates the "export a CSV of muted users" functionality works
|
||||
"""
|
||||
# Mute remote_identity
|
||||
IdentityService(identity).mute(identity2)
|
||||
|
||||
# Run stator to process it
|
||||
stator.run_single_cycle()
|
||||
|
||||
# Download the CSV
|
||||
response = client_with_user.get(
|
||||
f"/@{identity.handle}/settings/import_export/mutes.csv"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert (
|
||||
response.content.strip()
|
||||
== b"Account address,Hide notifications\r\ntest@example2.com,false"
|
||||
)
|
||||
|
||||
# Mute remote_identity
|
||||
IdentityService(identity).mute(identity2, include_notifications=True)
|
||||
|
||||
# Run stator to process it
|
||||
stator.run_single_cycle()
|
||||
|
||||
# Download the CSV
|
||||
response = client_with_user.get(
|
||||
f"/@{identity.handle}/settings/import_export/mutes.csv"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert (
|
||||
response.content.strip()
|
||||
== b"Account address,Hide notifications\r\ntest@example2.com,true"
|
||||
)
|
||||
|
||||
# Unmute should clear the CSV content
|
||||
IdentityService(identity).unmute(identity2)
|
||||
response = client_with_user.get(
|
||||
f"/@{identity.handle}/settings/import_export/mutes.csv"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.content.strip() == b"Account address,Hide notifications"
|
||||
|
|
|
@ -6,8 +6,10 @@ from django.views.generic import View
|
|||
from users.views.settings.delete import DeleteIdentity # noqa
|
||||
from users.views.settings.follows import FollowsPage # noqa
|
||||
from users.views.settings.import_export import ( # noqa
|
||||
CsvBlocks,
|
||||
CsvFollowers,
|
||||
CsvFollowing,
|
||||
CsvMutes,
|
||||
ImportExportPage,
|
||||
)
|
||||
from users.views.settings.interface import InterfacePage # noqa
|
||||
|
|
|
@ -7,7 +7,7 @@ from django.shortcuts import redirect
|
|||
from django.utils.decorators import method_decorator
|
||||
from django.views.generic import FormView, View
|
||||
|
||||
from users.models import Follow, InboxMessage
|
||||
from users.models import Block, Follow, InboxMessage
|
||||
from users.views.base import IdentityViewMixin
|
||||
|
||||
|
||||
|
@ -147,3 +147,35 @@ class CsvFollowers(CsvView):
|
|||
|
||||
def get_handle(self, follow: Follow):
|
||||
return follow.source.handle
|
||||
|
||||
|
||||
class CsvBlocks(CsvView):
|
||||
columns = {
|
||||
"Account address": "get_handle",
|
||||
}
|
||||
|
||||
filename = "blocked_accounts.csv"
|
||||
|
||||
def get_queryset(self, request):
|
||||
return self.identity.outbound_blocks.active().filter(mute=False)
|
||||
|
||||
def get_handle(self, block: Block):
|
||||
return block.target.handle
|
||||
|
||||
|
||||
class CsvMutes(CsvView):
|
||||
columns = {
|
||||
"Account address": "get_handle",
|
||||
"Hide notifications": "get_notification",
|
||||
}
|
||||
|
||||
filename = "muted_accounts.csv"
|
||||
|
||||
def get_queryset(self, request):
|
||||
return self.identity.outbound_blocks.active().filter(mute=True)
|
||||
|
||||
def get_handle(self, mute: Block):
|
||||
return mute.target.handle
|
||||
|
||||
def get_notification(self, mute: Block):
|
||||
return mute.include_notifications
|
||||
|
|
Loading…
Reference in New Issue