Skip to content

Commit

Permalink
Merge pull request #108 from NicolasConstant/develop
Browse files Browse the repository at this point in the history
0.17.0 PR
  • Loading branch information
NicolasConstant authored May 30, 2021
2 parents a2e5471 + e6bb9f1 commit 07dc912
Show file tree
Hide file tree
Showing 18 changed files with 1,023 additions and 111 deletions.
51 changes: 51 additions & 0 deletions BSLManager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# BSLManager

A CLI is provided in the Docker image so that admins can manage their instance.

## Access to the CLI

Since the CLI is packaged into the docker image, you'll have to open a shell from the container. To do so, list first your running containers:

```
docker ps
```

This should display you something equivalent to this:

```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3734c41af5a7 postgres:9.6 "docker-entrypoint.s…" 2 weeks ago Up 2 weeks 5432/tcp db_1
be6870fe103e nicolasconstant/birdsitelive:latest "dotnet BirdsiteLive…" 6 weeks ago Up 2 weeks 443/tcp, 0.0.0.0:5000->80/tcp birdsitelive
```

Find the BSL container and keep the ID, here it's `be6870fe103e`. And you only need the three first char to identify it, so we'll be using `be6`.

Then open a shell inside the container (change `be6` with your own id):

```
docker exec -it be6 /bin/bash
```

And you should now be inside the container, and all you have to do is calling the CLI:

```
./BSLManager
```

## Setting up the CLI

The manager will ask you to provide information about the database and the instance.
Those must be same than the ones in the `docker-compose.yml` file.
Provide the information, review it and validate it. Then the CLI UI should shows up.

## Using the CLI

You can navigate between the sections with the arrows and tab keys.

The **filter** permits to filter the list of users with a pattern.

All users have their followings count provided next to them.
You can select any user by using the up/down arrow keys and hitting the `Enter` key, this will display more information about the user.
You can also remove a user and all their followings by hitting the `Del` key. You will be prompted by a confirmation message, and you'll be able to remove this user.

Deleting users having a lots of followings can take some time: after the prompt has closed the process is still running and will update the list after that. Let the software do its thing and it will go through.
9 changes: 2 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
FROM mcr.microsoft.com/dotnet/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
FROM mcr.microsoft.com/dotnet/sdk:3.1-buster AS publish
COPY ./src/ ./src/
RUN dotnet restore "/src/BirdsiteLive/BirdsiteLive.csproj"
RUN dotnet restore "/src/BSLManager/BSLManager.csproj"
RUN dotnet build "/src/BirdsiteLive/BirdsiteLive.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "/src/BirdsiteLive/BirdsiteLive.csproj" -c Release -o /app/publish
RUN dotnet publish "/src/BSLManager/BSLManager.csproj" -r linux-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -c Release -o /app/publish

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ You can find an official (and temporary) instance here: [beta.birdsite.live](htt

I'm providing a [docker build](https://hub.docker.com/r/nicolasconstant/birdsitelive). To install it on your own server, please follow [those instructions](https://github.com/NicolasConstant/BirdsiteLive/blob/master/INSTALLATION.md). More [options](https://github.com/NicolasConstant/BirdsiteLive/blob/master/VARIABLES.md) are also available.

Also a [CLI](https://github.com/NicolasConstant/BirdsiteLive/blob/master/BSLManager.md) is available for adminitrative tasks.

## License

This project is licensed under the AGPLv3 License - see [LICENSE](https://github.com/NicolasConstant/BirdsiteLive/blob/master/LICENSE) for details.
Expand Down
244 changes: 244 additions & 0 deletions src/BSLManager/App.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.DAL.Models;
using BirdsiteLive.Moderation.Actions;
using BSLManager.Domain;
using BSLManager.Tools;
using Terminal.Gui;

namespace BSLManager
{
public class App
{
private readonly IFollowersDal _followersDal;
private readonly IRemoveFollowerAction _removeFollowerAction;

private readonly FollowersListState _state = new FollowersListState();

#region Ctor
public App(IFollowersDal followersDal, IRemoveFollowerAction removeFollowerAction)
{
_followersDal = followersDal;
_removeFollowerAction = removeFollowerAction;
}
#endregion

public void Run()
{
Application.Init();
var top = Application.Top;

// Creates the top-level window to show
var win = new Window("BSL Manager")
{
X = 0,
Y = 1, // Leave one row for the toplevel menu

// By using Dim.Fill(), it will automatically resize without manual intervention
Width = Dim.Fill(),
Height = Dim.Fill()
};

top.Add(win);

// Creates a menubar, the item "New" has a help menu.
var menu = new MenuBar(new MenuBarItem[]
{
new MenuBarItem("_File", new MenuItem[]
{
new MenuItem("_Quit", "", () =>
{
if (Quit()) top.Running = false;
})
}),
//new MenuBarItem ("_Edit", new MenuItem [] {
// new MenuItem ("_Copy", "", null),
// new MenuItem ("C_ut", "", null),
// new MenuItem ("_Paste", "", null)
//})
});
top.Add(menu);

static bool Quit()
{
var n = MessageBox.Query(50, 7, "Quit BSL Manager", "Are you sure you want to quit?", "Yes", "No");
return n == 0;
}

RetrieveUserList();

var list = new ListView(_state.GetDisplayableList())
{
X = 1,
Y = 3,
Width = Dim.Fill(),
Height = Dim.Fill()
};

list.KeyDown += _ =>
{
if (_.KeyEvent.Key == Key.Enter)
{
OpenFollowerDialog(list.SelectedItem);
}
else if (_.KeyEvent.Key == Key.Delete
|| _.KeyEvent.Key == Key.DeleteChar
|| _.KeyEvent.Key == Key.Backspace
|| _.KeyEvent.Key == Key.D)
{
OpenDeleteDialog(list.SelectedItem);
}
};

var listingFollowersLabel = new Label(1, 0, "Listing followers");
var filterLabel = new Label("Filter: ") { X = 1, Y = 1 };
var filterText = new TextField("")
{
X = Pos.Right(filterLabel),
Y = 1,
Width = 40
};

filterText.KeyDown += _ =>
{
var text = filterText.Text.ToString();
if (_.KeyEvent.Key == Key.Enter && !string.IsNullOrWhiteSpace(text))
{
_state.FilterBy(text);
ConsoleGui.RefreshUI();
}
};

win.Add(
listingFollowersLabel,
filterLabel,
filterText,
list
);

Application.Run();
}

private void OpenFollowerDialog(int selectedIndex)
{
var close = new Button(3, 14, "Close");
close.Clicked += () => Application.RequestStop();

var dialog = new Dialog("Info", 60, 18, close);

var follower = _state.GetElementAt(selectedIndex);

var name = new Label($"User: @{follower.Acct}@{follower.Host}")
{
X = 1,
Y = 1,
Width = Dim.Fill(),
Height = 1
};
var following = new Label($"Following Count: {follower.Followings.Count}")
{
X = 1,
Y = 3,
Width = Dim.Fill(),
Height = 1
};
var inbox = new Label($"Inbox: {follower.InboxRoute}")
{
X = 1,
Y = 4,
Width = Dim.Fill(),
Height = 1
};
var sharedInbox = new Label($"Shared Inbox: {follower.SharedInboxRoute}")
{
X = 1,
Y = 5,
Width = Dim.Fill(),
Height = 1
};

dialog.Add(name);
dialog.Add(following);
dialog.Add(inbox);
dialog.Add(sharedInbox);
dialog.Add(close);
Application.Run(dialog);
}

private void OpenDeleteDialog(int selectedIndex)
{
bool okpressed = false;
var ok = new Button(10, 14, "Yes");
ok.Clicked += () =>
{
Application.RequestStop();
okpressed = true;
};

var cancel = new Button(3, 14, "No");
cancel.Clicked += () => Application.RequestStop();

var dialog = new Dialog("Delete", 60, 18, cancel, ok);

var follower = _state.GetElementAt(selectedIndex);
var name = new Label($"User: @{follower.Acct}@{follower.Host}")
{
X = 1,
Y = 1,
Width = Dim.Fill(),
Height = 1
};
var entry = new Label("Delete user and remove all their followings?")
{
X = 1,
Y = 3,
Width = Dim.Fill(),
Height = 1
};
dialog.Add(name);
dialog.Add(entry);
Application.Run(dialog);

if (okpressed)
{
DeleteAndRemoveUser(selectedIndex);
}
}

private void DeleteAndRemoveUser(int el)
{
Application.MainLoop.Invoke(async () =>
{
try
{
var userToDelete = _state.GetElementAt(el);

BasicLogger.Log($"Delete {userToDelete.Acct}@{userToDelete.Host}");
await _removeFollowerAction.ProcessAsync(userToDelete);
BasicLogger.Log($"Remove user from list");
_state.RemoveAt(el);
}
catch (Exception e)
{
BasicLogger.Log(e.Message);
}

ConsoleGui.RefreshUI();
});
}

private void RetrieveUserList()
{
Application.MainLoop.Invoke(async () =>
{
var followers = await _followersDal.GetAllFollowersAsync();
_state.Load(followers.ToList());
ConsoleGui.RefreshUI();
});
}
}
}
18 changes: 17 additions & 1 deletion src/BSLManager/BSLManager.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Lamar" Version="5.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
<PackageReference Include="Terminal.Gui" Version="1.0.0-beta.11" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BirdsiteLive.Common\BirdsiteLive.Common.csproj" />
<ProjectReference Include="..\BirdsiteLive.Moderation\BirdsiteLive.Moderation.csproj" />
<ProjectReference Include="..\DataAccessLayers\BirdsiteLive.DAL.Postgres\BirdsiteLive.DAL.Postgres.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="key.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading

0 comments on commit 07dc912

Please sign in to comment.