!INFO: tried to move to postgreSQL did not work

fix: fixed bumping, fixed banning from Reports Menu
feat: improved homepage, finilized comments and posts, moved version from nav menu to sidebar

Signed-off-by: limited_dev <loginakkisativ@gmail.com>
This commit is contained in:
limited_dev 2023-06-13 23:34:16 +02:00
parent 7bd31ea7b5
commit 73be698399
12 changed files with 188 additions and 47 deletions

View file

@ -23,4 +23,5 @@
**/values.dev.yaml **/values.dev.yaml
LICENSE LICENSE
README.md README.md
**/creds.json **/creds.json
**/*.db

1
.gitignore vendored
View file

@ -7,6 +7,7 @@ ImageBoardServerApp/wwwroot/img/dynamic
*.db-wal *.db-wal
Migrations/ Migrations/
/ImageBoardServerApp/Data/creds.json /ImageBoardServerApp/Data/creds.json
/ImageBoardServerApp/Data/AppDbContext.cs
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.

View file

@ -14,7 +14,7 @@ public static class UsersRepository
.Include(user => user.Posts) .Include(user => user.Posts)
.ToListAsync(); .ToListAsync();
} }
public static async Task<UserData> getUserByIdAsync(int userId) public static async Task<UserData> getUserByIdAsync(int userId)
{ {
await using var db = new AppDBContext(); await using var db = new AppDBContext();
@ -27,6 +27,14 @@ public static class UsersRepository
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
public static async Task<UserData> getUserByIdLiteAsync(int userId)
{
await using var db = new AppDBContext();
return await db.Users
.Where(x => x.UserID == userId)
.FirstOrDefaultAsync();
}
public static async Task<UserData> getUserByEmailRawAsync(string email) public static async Task<UserData> getUserByEmailRawAsync(string email)
{ {
await using var db = new AppDBContext(); await using var db = new AppDBContext();
@ -34,7 +42,7 @@ public static class UsersRepository
.Where(user => user.Email == email) .Where(user => user.Email == email)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
public static async Task<UserData> getUserByEmailAsync(string email) public static async Task<UserData> getUserByEmailAsync(string email)
{ {
await using var db = new AppDBContext(); await using var db = new AppDBContext();
@ -59,14 +67,14 @@ public static class UsersRepository
return -1; return -1;
} }
public static async Task<bool> updateUserAsync(UserData userToUpdate) public static async Task<bool> updateUserAsync(UserData userToUpdate)
{ {
await using var db = new AppDBContext(); await using var db = new AppDBContext();
db.Users.Update(userToUpdate); db.Users.Update(userToUpdate);
return await db.SaveChangesAsync() >= 1; return await db.SaveChangesAsync() >= 1;
} }
public static async Task<bool> deleteUserAsync(int userId) public static async Task<bool> deleteUserAsync(int userId)
{ {
await using var db = new AppDBContext(); await using var db = new AppDBContext();

View file

@ -16,12 +16,13 @@
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.13" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.13" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.8"/>
<PackageReference Include="Radzen.Blazor" Version="4.10.4" /> <PackageReference Include="Radzen.Blazor" Version="4.10.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Data\Migrations\"/> <Folder Include="Data\Migrations\"/>
<Folder Include="wwwroot\img\dynamic\comment\au" /> <Folder Include="wwwroot\img\dynamic\comment\au" />
<Folder Include="wwwroot\img\dynamic\comment\e\" /> <Folder Include="wwwroot\img\dynamic\comment\e\" />
<Folder Include="wwwroot\img\dynamic\comment\tec" /> <Folder Include="wwwroot\img\dynamic\comment\tec" />

View file

@ -1,8 +1,9 @@
@page "/" @page "/"
@using ImageBoardServerApp.Util
@using ImageBoardServerApp.Data.Repository @using ImageBoardServerApp.Data.Repository
@inject AuthenticationStateProvider authStateProvider @inject AuthenticationStateProvider authStateProvider
<h1>BulletBoard</h1> <h1>BulletBoard @ver</h1>
<p> <p>
This is a simple <a href="https://en.wiktionary.org/wiki/imageboard">imageboard</a> made in <a href="https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor">Razor Server</a>. This is a simple <a href="https://en.wiktionary.org/wiki/imageboard">imageboard</a> made in <a href="https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor">Razor Server</a>.
<br/> <br/>
@ -12,7 +13,9 @@
<br/> <br/>
Click <a href="https://www.gnu.org/philosophy/free-sw.en.html">here</a> to learn more about free software. Click <a href="https://www.gnu.org/philosophy/free-sw.en.html">here</a> to learn more about free software.
<br/> <br/>
Check out the project on <a href="https://git.limited-dev.de/eric/imageboard">Gitlab</a>.
<br> <br>
<br/>
We're currently @amountOfUsers User(s), viewing @amountOfPosts Post(s) with @amountOfComments Comment(s). We're currently @amountOfUsers User(s), viewing @amountOfPosts Post(s) with @amountOfComments Comment(s).
<br/> <br/>
Click here to: Click here to:
@ -36,6 +39,8 @@
private int amountOfComments = -1; private int amountOfComments = -1;
private int amountOfUsers = -1; private int amountOfUsers = -1;
public string ver { get; set; } = TheManager.version;
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
var posts = await PostsRepository.getPostsAsync(); var posts = await PostsRepository.getPostsAsync();

View file

@ -55,6 +55,8 @@
{ {
if (selectedItem == null || selectedItem == "none") if (selectedItem == null || selectedItem == "none")
return; return;
if (explaination == null)
return;
var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider;
var user = await cauthStateProvder.GetAuthenticationStateAsync(); var user = await cauthStateProvder.GetAuthenticationStateAsync();
var usr = user.User; var usr = user.User;
@ -94,10 +96,13 @@
}; };
List<ReportData> submittedReports = foundusr.RecivedReports; List<ReportData> submittedReports = foundusr.RecivedReports;
foreach (var r in submittedReports) if (foundusr.RecivedReports != null)
{ {
if (r.ReportedPostID == reportData.ReportedPostID && r.ReportedCommentID == reportData.ReportedCommentID) foreach (var r in submittedReports)
return; {
if (r.ReportedPostID == reportData.ReportedPostID && r.ReportedCommentID == reportData.ReportedCommentID)
return;
}
} }
await ReportsRepository.createReportAsync(reportData); await ReportsRepository.createReportAsync(reportData);

View file

@ -1,10 +1,53 @@
@page "/sys/modtools/{targetuserid}/{type}/{targetid}" @page "/sys/modtools/banandordel/{targetuserid}/{board}/{type}/{threadid}/{targetid}"
@using ImageBoardServerApp.Data.Repository
@using System.ComponentModel.DataAnnotations @using System.ComponentModel.DataAnnotations
@inject NavigationManager navManager
@inject IJSRuntime js
<AuthorizeView Roles="Admin,Mod"> <AuthorizeView Roles="Admin,Mod">
<Authorized> <Authorized>
<div> <div>
<UserEntry user="user"></UserEntry>
<p>
<a href="/@board/thread/@threadid">[View Thread]</a>
</p>
<div>
<br/>
@if (type == "op")
{
<Post post="post" showOpenThread="true"/>
}
else if (type == "comment")
{
<Comment comment="comment"/>
}
else
{
<p>This is not a valid type.</p>
}
</div>
<div>
<form>
<RadzenFormField Text="Reason" Variant="Variant.Outlined">
<RadzenTextBox @bind-Value="@reason"/>
</RadzenFormField>
<br/>
<br/>
<span>Ban User: </span>
<a @onclick="() => banTarget(1)" href="javascript:void(0)">1h</a>
<span> </span>
<a @onclick="() => banTarget(2)" href="javascript:void(0)">2h</a>
<span> </span>
<a @onclick="() => banTarget(1 * 24)" href="javascript:void(0)">1d</a>
<span> </span>
<a @onclick="() => banTarget(7 * 24)" href="javascript:void(0)">1w</a>
<span> </span>
<a @onclick="() => banTarget(31 * 24)" href="javascript:void(0)">1m</a>
<span> </span>
<a @onclick="() => banTarget(365 * 24)" href="javascript:void(0)">1yr</a>
<span> </span>
</form>
</div>
</div> </div>
</Authorized> </Authorized>
<NotAuthorized> <NotAuthorized>
@ -14,14 +57,82 @@
@code { @code {
public string timetoBan { get; set; }
public string reason { get; set; }
public UserData user { get; set; }
public PostData post { get; set; }
public CommentData comment { get; set; }
private async Task banTarget(int hours)
{
UserData ud = await UsersRepository.getUserByIdAsync(int.Parse(targetuserid));
ud.TimeBanned = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (hours * 3600000);
if (reason == "")
{
reason = "not specified";
}
ud.BanReason = reason;
await UsersRepository.updateUserAsync(ud);
navManager.NavigateTo("/@board/", true, true);
}
protected override async Task OnParametersSetAsync()
{
if (!int.TryParse(targetid, out _) || !int.TryParse(targetuserid, out _))
{
navManager.NavigateTo("/sys/dead", true);
return;
}
var targeti = int.Parse(targetid);
var targetuseri = int.Parse(targetuserid);
var u = await UsersRepository.getUserByIdAsync(targetuseri);
if (u == null)
{
navManager.NavigateTo("/sys/dead", true);
return;
}
if (targetuseri != u.UserID)
{
navManager.NavigateTo("/sys/dead", true);
return;
}
user = u;
var isPost = type == "op";
if (isPost)
{
post = await PostsRepository.getPostByIdAsync(targeti);
}
else
{
comment = await CommentsRepository.getCommentByIdAsync(targeti);
}
await base.OnParametersSetAsync();
}
[Parameter] [Parameter]
[Required] [Required]
public string targetuserid { get; set; } public string targetuserid { get; set; }
[Parameter]
[Required]
public string threadid { get; set; }
[Parameter] [Parameter]
[Required] [Required]
public string type { get; set; } public string type { get; set; }
[Parameter]
[Required]
public string board { get; set; }
[Parameter] [Parameter]
[Required] [Required]
public string targetid { get; set; } public string targetid { get; set; }

View file

@ -118,7 +118,7 @@
return; return;
} }
int userID = foundusr.UserID; int userID = foundusr.UserID;
if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - foundusr.TimeBanned < 0) if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - foundusr.TimeBanned > 0)
{ {
foundusr.TimeBanned = -1; foundusr.TimeBanned = -1;
} }
@ -127,7 +127,7 @@
{ {
var dt = TheManager.ConvertToDateTime(foundusr.TimeBanned); var dt = TheManager.ConvertToDateTime(foundusr.TimeBanned);
hasErr = true; hasErr = true;
postErr = "You are banned for " + foundusr.BanReason + " and may not comment until " + dt.Year + "." + dt.Month + "." + dt.Day + " " + dt.Hour + ":" + dt.Minute + "::" + dt.Second; postErr = "You are banned for \"" + foundusr.BanReason + "\" and may not comment until " + dt.Year + "." + dt.Month + "." + dt.Day + " " + dt.Hour + ":" + dt.Minute + "::" + dt.Second;
return; return;
} }
foundusr.lastActionTimeStamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); foundusr.lastActionTimeStamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();

View file

@ -124,7 +124,7 @@
return; return;
} }
int userID = foundusr.UserID; int userID = foundusr.UserID;
if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - foundusr.TimeBanned < 0) if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - foundusr.TimeBanned > 0)
{ {
foundusr.TimeBanned = -1; foundusr.TimeBanned = -1;
} }
@ -133,7 +133,7 @@
{ {
var dt = TheManager.ConvertToDateTime(foundusr.TimeBanned); var dt = TheManager.ConvertToDateTime(foundusr.TimeBanned);
hasErr = true; hasErr = true;
postErr = "You are banned for " + foundusr.BanReason + " and may not post until " + dt.Year + "." + dt.Month + "." + dt.Day + " " + dt.Hour + ":" + dt.Minute + "::" + dt.Second; postErr = "You are banned for \"" + foundusr.BanReason + "\" and may not post until " + dt.Year + "." + dt.Month + "." + dt.Day + " " + dt.Hour + ":" + dt.Minute + "::" + dt.Second;
return; return;
} }
@ -153,7 +153,6 @@
foundusr.LastUsedName = postUsername; foundusr.LastUsedName = postUsername;
await UsersRepository.updateUserAsync(foundusr); await UsersRepository.updateUserAsync(foundusr);
//TODO Add check if data is image //TODO Add check if data is image
if (selectedFile == null || selectedFile.Size >= 512000 * 2 * 10) if (selectedFile == null || selectedFile.Size >= 512000 * 2 * 10)
@ -198,11 +197,11 @@
shouldAnon = postAnon shouldAnon = postAnon
}; };
int postId = await PostsRepository.createPostAsync(postToPost); int postId = await PostsRepository.createPostAsync(postToPost);
await TheManager.bumpThreads(board);
if (postId != -1) if (postId != -1)
{ {
//Open post successfull //Open post successfull
NavigationManager.NavigateTo($"/{board.Tag}/thread/{postId}", true, true); NavigationManager.NavigateTo($"/{board.Tag}/thread/{postId}", true, true);
await TheManager.bumpThreads(board);
Console.WriteLine("Post created"); Console.WriteLine("Post created");
} }
else else

View file

@ -18,28 +18,34 @@
<span>Explaination: @report.ReportExlaination</span> <span>Explaination: @report.ReportExlaination</span>
<br/> <br/>
<span>Ban User: </span> <span>Ban User: </span>
<a @onclick="() => banTarget(1)" href="javascript:void(0)">1d</a> <a @onclick="() => banTarget(1)" href="javascript:void(0)">1h</a>
<span> </span> <span> </span>
<a @onclick="() => banTarget(7)" href="javascript:void(0)">1w</a> <a @onclick="() => banTarget(2)" href="javascript:void(0)">2h</a>
<span> </span> <span> </span>
<a @onclick="() => banTarget(31)" href="javascript:void(0)">1m</a> <a @onclick="() => banTarget(1 * 24)" href="javascript:void(0)">1d</a>
<span> </span> <span> </span>
<a @onclick="() => banTarget(365)" href="javascript:void(0)">1yr</a> <a @onclick="() => banTarget(7 * 24)" href="javascript:void(0)">1w</a>
<span> </span>
<a @onclick="() => banTarget(31 * 24)" href="javascript:void(0)">1m</a>
<span> </span>
<a @onclick="() => banTarget(365 * 24)" href="javascript:void(0)">1yr</a>
<span> </span> <span> </span>
<a @onclick="() => banTarget(99999999)" href="javascript:void(0)">273,972.6 yrs</a>
<br/> <br/>
<span>Ban Reporter: </span> <span>Ban Reporter: </span>
<a @onclick="() => banReporter(1)" href="javascript:void(0)">1d</a> <a @onclick="() => banReporter(1)" href="javascript:void(0)">1h</a>
<span> </span> <span> </span>
<a @onclick="() => banReporter(7)" href="javascript:void(0)">1w</a> <a @onclick="() => banReporter(2)" href="javascript:void(0)">2h</a>
<span> </span> <span> </span>
<a @onclick="() => banReporter(31)" href="javascript:void(0)">1m</a> <a @onclick="() => banReporter(1 * 24)" href="javascript:void(0)">1d</a>
<span> </span> <span> </span>
<a @onclick="() => banReporter(365)" href="javascript:void(0)">1yr</a> <a @onclick="() => banReporter(7 * 24)" href="javascript:void(0)">1w</a>
<span> </span>
<a @onclick="() => banReporter(31 * 24)" href="javascript:void(0)">1m</a>
<span> </span>
<a @onclick="() => banReporter(365 * 24)" href="javascript:void(0)">1yr</a>
<span> </span> <span> </span>
<a @onclick="() => banReporter(99999999)" href="javascript:void(0)">273,972.6 yrs</a>
<br/> <br/>
<a @onclick="@removeReport" href="javascript:void(0)" >Done</a> <a @onclick="@removeReport" href="javascript:void(0)">Done</a>
<br/> <br/>
@if (report.Type == "op") @if (report.Type == "op")
{ {
@ -52,23 +58,26 @@
</div> </div>
@code { @code {
[Parameter] [Parameter]
[Required] [Required]
public ReportData report { get; set; } public ReportData report { get; set; }
private async Task banTarget(int days) private async Task banTarget(int days)
{ {
UserData user = report.UserReported; UserData user = report.UserReported;
user.TimeBanned = DateTimeOffset.Now.AddDays(days).ToUnixTimeMilliseconds(); user.TimeBanned = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (days * 3600000);
user.BanReason = report.ReportReason;
await UsersRepository.updateUserAsync(user); await UsersRepository.updateUserAsync(user);
await removeReport(); await removeReport();
} }
private async Task banReporter(int days) private async Task banReporter(int days)
{ {
UserData user = report.UserReporter; UserData user = report.UserReporter;
user.TimeBanned = DateTimeOffset.Now.AddDays(days).ToUnixTimeMilliseconds(); user.TimeBanned = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (days * 3600000);
user.BanReason = "misuse of the report system";
await UsersRepository.updateUserAsync(user); await UsersRepository.updateUserAsync(user);
await removeReport(); await removeReport();
} }
@ -76,6 +85,7 @@
private async Task removeReport() private async Task removeReport()
{ {
await ReportsRepository.deleteReportAsync(report.ReportID); await ReportsRepository.deleteReportAsync(report.ReportID);
navigationManager.NavigateTo("/sys/reports", true, true); navigationManager.NavigateTo("/sys/click/red/_sys_modmenu_reports", true, true);
} }
} }

View file

@ -1,5 +1,4 @@
@using ImageBoardServerApp.Util @using ImageBoardServerApp.Data.Repository
@using ImageBoardServerApp.Data.Repository
@inject AuthenticationStateProvider authStateProvider @inject AuthenticationStateProvider authStateProvider
@inject NavigationManager navManager @inject NavigationManager navManager
@ -9,7 +8,7 @@
</button> </button>
<div class="container-fluid" id="maintitle" href="/"> <div class="container-fluid" id="maintitle" href="/">
<img src="img/static/logo_trans.png" width="32" height="32" alt="Logo"/> <img src="img/static/logo_trans.png" width="32" height="32" alt="Logo"/>
<a class="navbar-brand" id="logo" href="/">BulletBoard @ver</a> <a class="navbar-brand" id="logo" href="/">BulletBoard</a>
</div> </div>
</div> </div>
@ -68,8 +67,6 @@
</div> </div>
@code { @code {
public string ver { get; set; } = TheManager.version;
private bool collapseNavMenu = true; private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

View file

@ -6,7 +6,7 @@ namespace ImageBoardServerApp.Util;
public class TheManager public class TheManager
{ {
public static string version = "1.0.0-c1"; public static string version = "v1.0.0-rc1";
private static long getDiff(PostData post) private static long getDiff(PostData post)
{ {
@ -38,14 +38,17 @@ public class TheManager
public static async Task bumpThreads(BoardData board) public static async Task bumpThreads(BoardData board)
{ {
Console.WriteLine("Bumping..");
List<PostData> sortedThreads = await getPostList(board.Tag); List<PostData> sortedThreads = await getPostList(board.Tag);
if (sortedThreads.Count > board.maxThreads + 1) if (sortedThreads.Count > board.maxThreads + 1)
{ {
for (int i = board.maxThreads + 1; i >= sortedThreads.Count; ++i) Console.WriteLine("Pruning..");
foreach (var pd in sortedThreads.TakeLast(sortedThreads.Count() - board.maxThreads))
{ {
if (sortedThreads[i].IsSticky) if (pd.IsSticky)
continue; continue;
await deleteThread(sortedThreads[i]); Console.WriteLine($"Removing Post{pd.PostID}");
await deleteThread(pd);
} }
} }
} }
@ -111,8 +114,8 @@ public class TheManager
public static DateTime ConvertToDateTime(long timestamp) public static DateTime ConvertToDateTime(long timestamp)
{ {
DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
DateTime date = unixEpoch.AddSeconds(timestamp); dateTime = dateTime.AddMilliseconds(timestamp).ToLocalTime();
return date; return dateTime;
} }
} }