diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 1ff0c42..0000000 --- a/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index 948c48d..d2d9315 100644 --- a/.gitignore +++ b/.gitignore @@ -1,343 +1 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -appsettings.json -src/config.lisp - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -/BantFlags/wwwroot/flags/*.png - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- Backup*.rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb +src/config.lisp \ No newline at end of file diff --git a/BantFlags.sln b/BantFlags.sln deleted file mode 100644 index 259451e..0000000 --- a/BantFlags.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29411.108 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BantFlags", "BantFlags\BantFlags.csproj", "{DDDE290B-44A9-485A-B0F4-E7D696EAFF8D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DDDE290B-44A9-485A-B0F4-E7D696EAFF8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DDDE290B-44A9-485A-B0F4-E7D696EAFF8D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DDDE290B-44A9-485A-B0F4-E7D696EAFF8D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DDDE290B-44A9-485A-B0F4-E7D696EAFF8D}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {252385AC-0BBA-43F2-858A-BA3877F33106} - EndGlobalSection -EndGlobal diff --git a/BantFlags/.config/dotnet-tools.json b/BantFlags/.config/dotnet-tools.json deleted file mode 100644 index 6b2cf2d..0000000 --- a/BantFlags/.config/dotnet-tools.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "dotnet-ef": { - "version": "3.1.0", - "commands": [ - "dotnet-ef" - ] - } - } -} \ No newline at end of file diff --git a/BantFlags/BantFlags.csproj b/BantFlags/BantFlags.csproj deleted file mode 100644 index 456cd21..0000000 --- a/BantFlags/BantFlags.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - netcoreapp3.1 - Manx - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - \ No newline at end of file diff --git a/BantFlags/Controllers/FlagsController.cs b/BantFlags/Controllers/FlagsController.cs deleted file mode 100644 index 05bacdc..0000000 --- a/BantFlags/Controllers/FlagsController.cs +++ /dev/null @@ -1,84 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using BantFlags.Data; -using BantFlags.Data.Database; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using System.Threading.Tasks; - -namespace BantFlags.Controllers -{ - [ApiController] - [Route("api")] - public class FlagsController : Controller - { - private DatabaseService Database { get; } - - public FlagsController(DatabaseService db) - { - Database = db; - } - - /// - /// Retrives flags from the database from the posts sent in post_nrs - /// - /// The comma seperated list of post numbers from the thread. - /// Currently should only be /bant/. Not checked here because we don't need to care what they send. - /// The version of the userscript. - [HttpPost] - [Route("get")] - [Consumes("application/x-www-form-urlencoded")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task Get([FromForm]string post_nrs, [FromForm]string board, [FromForm]int? version) - { - int ver = version ?? 0; - - if (ver > 1) - { - // Improved data structuring, see Docs/get - return Json(await Database.GetPosts_V2(post_nrs, board)); - } - - return Json(await Database.GetPosts_V1(post_nrs, board)); - } - - /// - /// Posts flags in the database. - /// - /// The post number to associate the flags to. - /// Currently should only be /bant/. - /// List of flags to associate with the post. Split by "||" in API V1 and "," in V2. - /// The version of the userscript. - [HttpPost] - [Route("post")] - [Consumes("application/x-www-form-urlencoded")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task Post([FromForm]string post_nr, [FromForm]string board, [FromForm]string regions, [FromForm]int? version) - { - string splitFlag = (version ?? 0) > 1 ? "," : "||"; // comma for v2+, else || for backwards compatibility. - - (PostModel flag, string error) = PostModel.Create(post_nr, board, regions, splitFlag, Database.KnownFlags, Database.Boards); - - if (flag is null) - { - return Problem(error, statusCode: StatusCodes.Status400BadRequest); - } - - await Database.InsertPost(flag); - - return Ok(flag); - } - - /// - /// Gets the list of supported flags. - /// - [HttpGet] - [Route("flags")] - [ProducesResponseType(StatusCodes.Status200OK)] - public IActionResult Flags() => Ok(Database.FlagList); - } -} \ No newline at end of file diff --git a/BantFlags/Data/Database/DatabaseService.cs b/BantFlags/Data/Database/DatabaseService.cs deleted file mode 100644 index c141770..0000000 --- a/BantFlags/Data/Database/DatabaseService.cs +++ /dev/null @@ -1,115 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Threading.Tasks; - -namespace BantFlags.Data.Database -{ - /// - /// Functions for interacting with the database. - /// - public partial class DatabaseService - { - private MySqlConnectionPool ConnectionPool { get; } - - public string FlagList { get; private set; } - - public HashSet KnownFlags { get; private set; } - - public HashSet Boards { get; private set; } - - public DatabaseService(DatabaseServiceConfig dbConfig) - { - ConnectionPool = new MySqlConnectionPool(dbConfig.ConnectionString, dbConfig.PoolSize); - - Boards = dbConfig.Boards; - - UpdateKnownFlags().Wait(); // It's okay to deadlock here since it's only initialised at startup. - } - - public async Task UpdateKnownFlags() - { - var flags = await GetFlags(); - flags.Remove("empty, or there were errors. Re-set your flags."); // So users can't select this. - - FlagList = string.Join("\n", flags); - KnownFlags = flags.ToHashSet(); - } - - public async Task InsertPost(PostModel post) - { - using (var rentedConnection = await ConnectionPool.RentConnectionAsync()) - { - await rentedConnection.Object.UseStoredProcedure("insert_post") - .SetParam("@post_nr", post.PostNumber) - .SetParam("@board", post.Board) - .ExecuteNonQueryAsync(); - - using (var query = rentedConnection.Object.UseStoredProcedure("insert_post_flags")) - { - query.SetParam("@post_nr", post.PostNumber); - - post.Flags.ForEach(async f => - await query.SetParam("@flag", f) - .ExecuteNonQueryAsync(reuse: true)); - } - } - } - - /// - /// Returns all of the flags that we support. - /// - public async Task> GetFlags() - { - using var rentedConnected = await ConnectionPool.RentConnectionAsync(); - - DataTable table = await rentedConnected.Object.CreateQuery("SELECT flags.flag FROM flags") - .ExecuteTableAsync(); - - return table.AsEnumerable() - .Select(x => x.GetValue("flag")) - .ToList(); - } - - public async Task InsertFlagAsync(Flag flag) - { - using var rentedConnection = await ConnectionPool.RentConnectionAsync(); - await rentedConnection.Object.UseStoredProcedure("insert_flag") - .SetParam("@flag", flag.Name) - .ExecuteNonQueryAsync(); - } - - public async Task RenameFlagAsync(Flag flag) - { - using var rentedConnection = await ConnectionPool.RentConnectionAsync(); - await rentedConnection.Object.UseStoredProcedure("rename_flag") - .SetParam("@old", flag.OldName) - .SetParam("@new", flag.Name) - .ExecuteNonQueryAsync(); - } - - public async Task DeleteFlagAsync(Flag flag) - { - using var rentedConnection = await ConnectionPool.RentConnectionAsync(); - await rentedConnection.Object.UseStoredProcedure("delete_flag") - .SetParam("@flag", flag.Name) - .ExecuteNonQueryAsync(); - } - } - - /// - /// Configuration data passed by appsettings. - /// - public class DatabaseServiceConfig - { - public string ConnectionString { get; set; } - - public int PoolSize { get; set; } - - public HashSet Boards { get; set; } - } -} \ No newline at end of file diff --git a/BantFlags/Data/Database/GetPosts.cs b/BantFlags/Data/Database/GetPosts.cs deleted file mode 100644 index d4cb5e9..0000000 --- a/BantFlags/Data/Database/GetPosts.cs +++ /dev/null @@ -1,58 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Threading.Tasks; - -namespace BantFlags.Data.Database -{ - public partial class DatabaseService - { - // Maybe this could be better but I don't know SQL lol - private readonly string GetPostsQuery = @"SELECT posts.post_nr, flags.flag FROM flags LEFT JOIN (postflags) ON (postflags.flag = flags.id) LEFT JOIN (posts) ON (postflags.post_nr = posts.id) WHERE FIND_IN_SET(posts.post_nr, (@posts)) AND posts.board = @board"; - - /// - /// Returns the post numbers and their flags from the post numbers in the input. - /// - /// List of post numbers on the page. - public async Task>> GetPosts(string post_nr, string board) - { - using var rentedConnection = await ConnectionPool.RentConnectionAsync(); - - DataTable table = await rentedConnection.Object.CreateQuery(GetPostsQuery) - .SetParam("@posts", post_nr) - .SetParam("@board", board) - .ExecuteTableAsync(); - - return table.AsEnumerable() - .GroupBy(x => x.GetValue("post_nr")); - } - - public async Task>> GetPosts_V1(string post_nr, string board) - { - List> posts = new List>(); - - var x = await GetPosts(post_nr, board); - x.ForEach(x => posts.Add(new Dictionary - { - {"post_nr", x.Key.ToString() }, - {"region", string.Join("||", x.AsEnumerable().Select(y => y.GetValue("flag")))} - })); - - return posts; - } - - public async Task>> GetPosts_V2(string post_nr, string board) - { - var posts = await GetPosts(post_nr, board); - return posts - .ToDictionary( - x => x.Key, - x => x.AsEnumerable().Select(x => x.GetValue("flag")) - ); - } - } -} \ No newline at end of file diff --git a/BantFlags/Data/IEnumerableExtensions.cs b/BantFlags/Data/IEnumerableExtensions.cs deleted file mode 100644 index fade987..0000000 --- a/BantFlags/Data/IEnumerableExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using System; -using System.Collections.Generic; - -namespace BantFlags.Data -{ - public static class IEnumerableExtensions - { - public static void ForEach(this IEnumerable enumeration, Action action) - { - foreach (T item in enumeration) - { - action(item); - } - } - } -} \ No newline at end of file diff --git a/BantFlags/Data/MySqlConnectionPool.cs b/BantFlags/Data/MySqlConnectionPool.cs deleted file mode 100644 index b1f6aa8..0000000 --- a/BantFlags/Data/MySqlConnectionPool.cs +++ /dev/null @@ -1,61 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using MySql.Data.MySqlClient; -using Nito.AsyncEx; -using System; -using System.Data; -using System.Threading.Tasks; - -namespace BantFlags.Data -{ - public class MySqlConnectionPool : IDisposable - { - public AsyncCollection Connections { get; } - - protected string ConnectionString { get; } - - protected int PoolSize { get; } - - public MySqlConnectionPool(string connectionString, int poolSize) - { - PoolSize = poolSize; - ConnectionString = connectionString; - - Connections = new AsyncCollection(poolSize); - - for (int i = 0; i < poolSize; i++) - { - var connection = new MySqlConnection(connectionString); - - connection.Open(); - - Connections.Add(connection); - } - } - - public async Task> RentConnectionAsync() - { - return new PoolObject(await Connections.TakeAsync(), obj => - { - if (obj.State != ConnectionState.Open) - { - obj.Open(); - } - - Connections.Add(obj); - }); - } - - public void Dispose() - { - for (int i = 0; i < PoolSize; i++) - { - var connection = Connections.Take(); - - connection.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/BantFlags/Data/MySqlExtensions.cs b/BantFlags/Data/MySqlExtensions.cs deleted file mode 100644 index b6372ae..0000000 --- a/BantFlags/Data/MySqlExtensions.cs +++ /dev/null @@ -1,48 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using MySql.Data.MySqlClient; -using System; -using System.Data; - -namespace BantFlags.Data -{ - public static class MySqlExtensions - { - public static Query CreateQuery(this MySqlConnection connection, string sql) - { - connection.EnsureConnectionIsOpen(); - - return new Query(new MySqlCommand(sql, connection)); - } - - public static Query UseStoredProcedure(this MySqlConnection connection, string sql) - { - connection.EnsureConnectionIsOpen(); - - return new Query(new MySqlCommand(sql, connection) - { - CommandType = CommandType.StoredProcedure - }); - } - - public static T GetValue(this DataRow row, string column) - { - object value = row[column]; - - if (value == null || value == DBNull.Value) - return default; - - return (T)value; - } - - private static void EnsureConnectionIsOpen(this MySqlConnection connection) - { - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - } - } -} \ No newline at end of file diff --git a/BantFlags/Data/Pool.cs b/BantFlags/Data/Pool.cs deleted file mode 100644 index f4f7fc2..0000000 --- a/BantFlags/Data/Pool.cs +++ /dev/null @@ -1,29 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using System; - -namespace BantFlags.Data -{ - public class PoolObject : IDisposable - { - public T Object { get; } - - private Action ReturnAction { get; } - - public PoolObject(T o, Action returnAction) - { - Object = o; - ReturnAction = returnAction; - } - - public void Dispose() - { - ReturnAction(Object); - } - - public static implicit operator T(PoolObject poolObject) - => poolObject.Object; - } -} \ No newline at end of file diff --git a/BantFlags/Data/PostModel.cs b/BantFlags/Data/PostModel.cs deleted file mode 100644 index a301b89..0000000 --- a/BantFlags/Data/PostModel.cs +++ /dev/null @@ -1,52 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using System.Collections.Generic; -using System.Linq; - -namespace BantFlags.Data -{ - public class PostModel - { - public int PostNumber { get; private set; } - - public string Board { get; private set; } - - public string[] Flags { get; private set; } - - private PostModel(int post_nr, string board, string[] flags) - { - PostNumber = post_nr; - Board = board; - Flags = flags; - } - - public static (PostModel, string) Create(string post_nr, string board, string regions, string splitFlag, HashSet knownFlags, HashSet boards) - { - string[] empty = { "empty, or there were errors. Re-set your flags." }; - - if (!int.TryParse(post_nr, out int postNumber)) - return (default, "Invalid post number."); - - if (!boards.Contains(board)) - return (default, "Invalid board parameter."); - - if (regions == null) - return (new PostModel(postNumber, board, empty), default); - - var flags = regions.Split(splitFlag); - - if (flags.Count() > 30) - return (default, "Too many flags."); - - foreach (string flag in flags) - { - if (!knownFlags.Contains(flag)) // Not ideal but it's better than doing it in the controller or passing the database here. - return (new PostModel(postNumber, board, empty), default); - } - - return (new PostModel(postNumber, board, flags), default); - } - } -} \ No newline at end of file diff --git a/BantFlags/Data/Query.cs b/BantFlags/Data/Query.cs deleted file mode 100644 index da24360..0000000 --- a/BantFlags/Data/Query.cs +++ /dev/null @@ -1,65 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using MySql.Data.MySqlClient; -using System; -using System.Data; -using System.Threading.Tasks; - -namespace BantFlags.Data -{ - /// - /// Succinct methods for creating and executing database queries - /// - public class Query : IDisposable - { - private MySqlCommand Command { get; } - - public Query(MySqlCommand cmd) - { - Command = cmd; - } - - public async Task ExecuteTableAsync() - { - using (var reader = await Command.ExecuteReaderAsync()) - { - DataTable table = new DataTable(); - table.Load(reader); - - return table; - } - } - - public async Task ExecuteNonQueryAsync(bool reuse = false) - { - await Command.ExecuteNonQueryAsync(); - - if (!reuse) - { - Dispose(); - } - } - - public Query SetParam(string parameter, object value) - { - // When we reuse a query, we write over the parameter. - if (Command.Parameters.Contains(parameter)) - { - Command.Parameters[parameter].Value = value; - } - else - { - Command.Parameters.AddWithValue(parameter, value); - } - - return this; - } - - public void Dispose() - { - Command.Dispose(); - } - } -} \ No newline at end of file diff --git a/BantFlags/Data/Staging.cs b/BantFlags/Data/Staging.cs deleted file mode 100644 index 73f0001..0000000 --- a/BantFlags/Data/Staging.cs +++ /dev/null @@ -1,150 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using ImageMagick; -using Microsoft.AspNetCore.Http; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace BantFlags.Data -{ - public class Staging - { - public List Flags { get; set; } - public string Password { get; } - - public HashSet Names { get; set; } - - public Staging(string password) - { - Flags = new List(); - Password = password; - } - - public void Clear() - { - Flags = new List(); - } - } - - public enum Method - { - Add = 0, - - Delete = 1, - - Rename = 2 - } - - public class Flag - { - public string Name { get; set; } - - public string OldName { get; set; } - - public bool IsChecked { get; set; } - - public Method FlagMethod { get; set; } - - // This is bad but we need it so Flags can be generated by the input tag helper - public Flag() - { - } - - private Flag(string name, Method method) - { - Name = name; - FlagMethod = method; - } - - private Flag(string name, string oldName, Method method) - { - Name = name; - OldName = oldName; - FlagMethod = method; - } - - public static Flag CreateFromDelete(string name) => new Flag(name, Method.Delete); // We don't need any validation for deleted flags. - - public static (Flag, string) CreateFromRename(string oldName, string newName, HashSet names) - { - (bool valid, string error) = ValidateFileName(newName, names); - - if (!valid) - { - return (default, error); - } - - return (new Flag(newName, oldName, Method.Rename), default); - } - - public static async Task<(Flag, string)> CreateFromFile(IFormFile upload, HashSet names) - { - byte[] PNGHeader = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; - - if (upload.ContentType.ToLower() != "image/png") - return (default, "Image must be a png."); - - if (upload.Length > 15 * 1024) - return (default, "File too big. Max size is 15kb."); - - var name = Path.GetFileNameWithoutExtension(upload.FileName); - - (bool valid, string error) = ValidateFileName(name, names); - - if (!valid) - return (default, error); - - using (var memoryStream = new MemoryStream()) - { - await upload.CopyToAsync(memoryStream); - memoryStream.Position = 0; - - using (var image = new MagickImage(memoryStream)) - { - if (image.Width != 16 || image.Height != 11) - return (default, "Invalid image dimensions. Flags should be 16px by 11px."); - } - - using (var reader = new BinaryReader(memoryStream)) - { - reader.BaseStream.Position = 0; - - if (!reader.ReadBytes(PNGHeader.Length).SequenceEqual(PNGHeader)) - return (default, "Invalid png header."); - } - } - - return (new Flag(name, Method.Add), default); - } - - /// - /// Filters file names created by users. - /// - /// The file name to validate. - /// The list of current file names. - private static (bool, string) ValidateFileName(string name, HashSet names) - { - if (string.IsNullOrWhiteSpace(name)) - return (false, "Flag name can't be empty."); - - if (name.Length > 100) - return (false, "Flag name too long."); - - if (name == "empty, or there were errors. Re - set your flags.") - return (false, "Invalid flag name."); - - if (name.Contains("||") || name.Contains(",")) - return (false, "Flag name contains invalid characters. You can't use \"||\" or \",\"."); - - if (names.Contains(name)) - return (false, "A flag with that name already exists."); - - return (true, name); - } - } -} \ No newline at end of file diff --git a/BantFlags/Pages/Index.cshtml b/BantFlags/Pages/Index.cshtml deleted file mode 100644 index 5289356..0000000 --- a/BantFlags/Pages/Index.cshtml +++ /dev/null @@ -1,21 +0,0 @@ -@* (C) Copyright 2019 C-xC-c - This file is part of BantFlags. - BantFlags is licensed under the GNU AGPL Version 3.0 or later. - see the LICENSE file or *@ -@page -@model BantFlags.Pages.IndexModel -@{ - ViewData["Title"] = "BantFlags"; - Layout = "~/Pages/Shared/_Layout.cshtml"; -} - -

/bant/ Flags

-

Eメール: boku (at) plum (dot) moe

- -Install Bantflags -
-
-Official Thread -
-
-Upload Flags \ No newline at end of file diff --git a/BantFlags/Pages/Index.cshtml.cs b/BantFlags/Pages/Index.cshtml.cs deleted file mode 100644 index eb61acc..0000000 --- a/BantFlags/Pages/Index.cshtml.cs +++ /dev/null @@ -1,15 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace BantFlags.Pages -{ - public class IndexModel : PageModel - { - public void OnGet() - { - } - } -} \ No newline at end of file diff --git a/BantFlags/Pages/Shared/_Layout.cshtml b/BantFlags/Pages/Shared/_Layout.cshtml deleted file mode 100644 index a82306c..0000000 --- a/BantFlags/Pages/Shared/_Layout.cshtml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - @ViewData["Title"] - @RenderSection("Head", required: false) - - - @RenderBody() - @RenderSection("Scripts", required: false) - - \ No newline at end of file diff --git a/BantFlags/Pages/Upload.cshtml b/BantFlags/Pages/Upload.cshtml deleted file mode 100644 index f459d41..0000000 --- a/BantFlags/Pages/Upload.cshtml +++ /dev/null @@ -1,123 +0,0 @@ -@* (C) Copyright 2019 C-xC-c - This file is part of BantFlags. - BantFlags is licensed under the GNU AGPL Version 3.0 or later. - see the LICENSE file or *@ -@page -@using BantFlags.Data -@model BantFlags.UploadModel -@{ -ViewData["Title"] = "Upload"; -Layout = "~/Pages/Shared/_Layout.cshtml"; -} - -

Upload

- -

@Model.Message

-

Add a Flag

-
- - Apply Gloss? -
-
- -
- -

Manage Existing Flags

-
- - -
-
- - -
- -

Commit Changes

-
- - -
-
- -
- -@if (Model.StagedFlags.Flags.Any()) -{ -

Pending Changes

-
- -
-
- -

Deleted Flags

- @for (int i = 0; i < Model.StagedFlags.Flags.Count(); i++) - { - if (Model.StagedFlags.Flags[i].FlagMethod == Method.Delete) - { -
- - - - - - -
- } - - } - -

Renamed Flags

- @for (int i = 0; i < Model.StagedFlags.Flags.Count(); i++) - { - if (Model.StagedFlags.Flags[i].FlagMethod == Method.Rename) - { -
- - - - - -
- } - - } - -

Added Flags

- @for (int i = 0; i < Model.StagedFlags.Flags.Count(); i++) - { - if (Model.StagedFlags.Flags[i].FlagMethod == Method.Add) - { -
- - - - - -
- } - - } -
-} - -@section Head { - -} - -@section Scripts { - @* Place flag image inside the