Compare commits

..

No commits in common. "3b9f1bb7074e67fb9ac4eeed8667f905959a7848" and "7cae2600ec06ee2da08fdca751cac9e414f908f5" have entirely different histories.

64 changed files with 538 additions and 1326 deletions

View File

@ -1,4 +1,3 @@
appsettings.json appsettings.json
**/bin/** **/bin/
**/obj/** **/obj/
**/efbundle

2
.gitignore vendored
View File

@ -4,8 +4,6 @@
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
seed.secrects.json seed.secrects.json
efbundle
efbundle.exe
out/ out/
#Docker Compose Secrets #Docker Compose Secrets

View File

@ -1,6 +1,6 @@
#FROM golang:latest as goose FROM golang:latest as goose
#RUN go install github.com/pressly/goose/v3/cmd/goose@latest RUN go install github.com/pressly/goose/v3/cmd/goose@latest
FROM mcr.microsoft.com/dotnet/sdk:7.0.103 as build FROM mcr.microsoft.com/dotnet/sdk:7.0.103 as build
@ -14,20 +14,21 @@ FROM build AS publish
RUN dotnet publish -c Release -o /app/publish RUN dotnet publish -c Release -o /app/publish
RUN dotnet publish -o build RUN dotnet publish -o build
#--self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true
RUN ls build RUN ls build
FROM build as ef
RUN dotnet tool install dotnet-ef --tool-path /usr/bin --version 7.0.8
RUN dotnet ef migrations bundle --project "Newsbot.Collector.Database" --force
FROM mcr.microsoft.com/dotnet/aspnet:7.0.3 as app FROM mcr.microsoft.com/dotnet/aspnet:7.0.3 as app
ENV ASPNETCORE_URLS=http://*:5000 ENV ASPNETCORE_URLS=http://*:5000
ENV DOTNET_URLS=http://*:5000 ENV DOTNET_URLS=http://*:5000
#RUN apt-get install chromium -y
WORKDIR /app WORKDIR /app
RUN mkdir /migrations
COPY --from=publish /app/build /app COPY --from=publish /app/build /app
COPY --from=ef /app/efbundle /app COPY --from=build ./app/Newsbot.Collector.Database/Migrations /app/migrations
COPY --from=goose /go/bin/goose /app
CMD [ "dotnet", "Newsbot.Collector.Api.dll" ] CMD [ "dotnet", "Newsbot.Collector.Api.dll" ]

View File

@ -43,7 +43,7 @@ public class ArticlesController : ControllerBase
public ArticleDetailsDto GetDetailsById(Guid id) public ArticleDetailsDto GetDetailsById(Guid id)
{ {
var item = _articles.GetById(id); var item = _articles.GetById(id);
var sourceItem = _sources.GetById(item.SourceId); var sourceItem = _sources.GetByID(item.SourceID);
return ArticleDetailsDto.Convert(item, sourceItem); return ArticleDetailsDto.Convert(item, sourceItem);
} }

View File

@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Dto; using Newsbot.Collector.Domain.Dto;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
@ -41,12 +40,12 @@ public class DiscordWebHookController : ControllerBase
{ {
var exists = _webhooks.GetByUrl(url); var exists = _webhooks.GetByUrl(url);
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (exists.Id != Guid.Empty) if (exists.ID != Guid.Empty)
{ {
return DiscordWebHookDto.Convert(exists); return DiscordWebHookDto.Convert(exists);
} }
var res = _webhooks.New(new DiscordWebhookEntity var res = _webhooks.New(new DiscordWebHookModel
{ {
Url = url, Url = url,
Server = server, Server = server,
@ -73,7 +72,7 @@ public class DiscordWebHookController : ControllerBase
[HttpGet("{id}")] [HttpGet("{id}")]
public DiscordWebHookDto GetById(Guid id) public DiscordWebHookDto GetById(Guid id)
{ {
var res = _webhooks.GetById(id); var res = _webhooks.GetByID(id);
return DiscordWebHookDto.Convert(res); return DiscordWebHookDto.Convert(res);
} }

View File

@ -3,7 +3,6 @@ using Microsoft.Extensions.Options;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Dto; using Newsbot.Collector.Domain.Dto;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Services.HtmlParser; using Newsbot.Collector.Services.HtmlParser;
@ -40,10 +39,10 @@ public class SourcesController : ControllerBase
} }
[HttpGet("by/type")] [HttpGet("by/type")]
public IEnumerable<SourceDto> GetByType(string type, int page) public IEnumerable<SourceDto> GetByType(string type)
{ {
var res = new List<SourceDto>(); var res = new List<SourceDto>();
var temp = _sources.ListByType(type, page); var temp = _sources.ListByType(type);
foreach (var item in temp) res.Add(SourceDto.Convert(item)); foreach (var item in temp) res.Add(SourceDto.Convert(item));
return res; return res;
} }
@ -52,7 +51,7 @@ public class SourcesController : ControllerBase
public SourceDto NewReddit(string name) public SourceDto NewReddit(string name)
{ {
var res = _sources.GetByNameAndType(name, SourceTypes.Reddit); var res = _sources.GetByNameAndType(name, SourceTypes.Reddit);
if (res.Id != Guid.Empty) return SourceDto.Convert(res); if (res.ID != Guid.Empty) return SourceDto.Convert(res);
var uri = new Uri($"https://reddit.com/r/{name}"); var uri = new Uri($"https://reddit.com/r/{name}");
@ -62,7 +61,7 @@ public class SourcesController : ControllerBase
}); });
pageReader.Parse(); pageReader.Parse();
var item = _sources.New(new SourceEntity var item = _sources.New(new SourceModel
{ {
Site = SourceTypes.Reddit, Site = SourceTypes.Reddit,
Name = name, Name = name,
@ -75,11 +74,11 @@ public class SourcesController : ControllerBase
// Not all subreddits have an Icon, so we only want to add a record when it has one. // Not all subreddits have an Icon, so we only want to add a record when it has one.
if (pageReader.Data.Header.Image != "") if (pageReader.Data.Header.Image != "")
_icons.New(new IconEntity() _icons.New(new IconModel
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
FileName = pageReader.Data.Header.Image, FileName = pageReader.Data.Header.Image,
SourceId = item.Id SourceId = item.ID
}); });
return SourceDto.Convert(item); return SourceDto.Convert(item);
} }
@ -88,9 +87,9 @@ public class SourcesController : ControllerBase
public SourceDto NewRss(string name, string url) public SourceDto NewRss(string name, string url)
{ {
var res = _sources.GetByNameAndType(name, SourceTypes.Rss); var res = _sources.GetByNameAndType(name, SourceTypes.Rss);
if (res.Id != Guid.Empty) return SourceDto.Convert(res); if (res.ID != Guid.Empty) return SourceDto.Convert(res);
var m = new SourceEntity var m = new SourceModel
{ {
Site = SourceTypes.Rss, Site = SourceTypes.Rss,
Name = name, Name = name,
@ -108,7 +107,7 @@ public class SourcesController : ControllerBase
public SourceDto NewYoutube(string url) public SourceDto NewYoutube(string url)
{ {
var res = _sources.GetByUrl(url); var res = _sources.GetByUrl(url);
if (res.Id != Guid.Empty) return SourceDto.Convert(res); if (res.ID != Guid.Empty) return SourceDto.Convert(res);
var htmlClient = new HtmlPageReader(new HtmlPageReaderOptions var htmlClient = new HtmlPageReader(new HtmlPageReaderOptions
{ {
@ -116,7 +115,7 @@ public class SourcesController : ControllerBase
}); });
htmlClient.Parse(); htmlClient.Parse();
var item = _sources.New(new SourceEntity var item = _sources.New(new SourceModel
{ {
Site = SourceTypes.YouTube, Site = SourceTypes.YouTube,
Type = SourceTypes.YouTube, Type = SourceTypes.YouTube,
@ -128,11 +127,11 @@ public class SourcesController : ControllerBase
YoutubeId = htmlClient.Data.Header.YoutubeChannelID ?? "" YoutubeId = htmlClient.Data.Header.YoutubeChannelID ?? ""
}); });
_icons.New(new IconEntity() _icons.New(new IconModel
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
FileName = htmlClient.Data.Header.Image, FileName = htmlClient.Data.Header.Image,
SourceId = item.Id SourceId = item.ID
}); });
return SourceDto.Convert(item); return SourceDto.Convert(item);
@ -142,9 +141,9 @@ public class SourcesController : ControllerBase
public SourceDto NewTwitch(string name) public SourceDto NewTwitch(string name)
{ {
var res = _sources.GetByNameAndType(name, SourceTypes.Twitch); var res = _sources.GetByNameAndType(name, SourceTypes.Twitch);
if (res.Id != Guid.Empty) return SourceDto.Convert(res); if (res.ID != Guid.Empty) return SourceDto.Convert(res);
var item = _sources.New(new SourceEntity var item = _sources.New(new SourceModel
{ {
Site = SourceTypes.Twitch, Site = SourceTypes.Twitch,
Type = SourceTypes.Twitch, Type = SourceTypes.Twitch,
@ -163,7 +162,7 @@ public class SourcesController : ControllerBase
//if (!url.Contains("github.com")) return new SourceDto(); //if (!url.Contains("github.com")) return new SourceDto();
var res = _sources.GetByUrl(url); var res = _sources.GetByUrl(url);
if (res.Id != Guid.Empty) return SourceDto.Convert(res); if (res.ID != Guid.Empty) return SourceDto.Convert(res);
var slice = url.Split('/'); var slice = url.Split('/');
@ -173,7 +172,7 @@ public class SourcesController : ControllerBase
}); });
pageReader.Parse(); pageReader.Parse();
var item = _sources.New(new SourceEntity var item = _sources.New(new SourceModel
{ {
Site = SourceTypes.CodeProject, Site = SourceTypes.CodeProject,
Type = SourceTypes.CodeProject, Type = SourceTypes.CodeProject,
@ -184,11 +183,11 @@ public class SourcesController : ControllerBase
Tags = $"{slice[2]},{slice[3]},{slice[4]}" Tags = $"{slice[2]},{slice[3]},{slice[4]}"
}); });
_icons.New(new IconEntity() _icons.New(new IconModel
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
FileName = pageReader.Data.Header.Image, FileName = pageReader.Data.Header.Image,
SourceId = item.Id SourceId = item.ID
}); });
return SourceDto.Convert(item); return SourceDto.Convert(item);
@ -197,7 +196,7 @@ public class SourcesController : ControllerBase
[HttpGet("{id}")] [HttpGet("{id}")]
public SourceDto GetById(Guid id) public SourceDto GetById(Guid id)
{ {
var item = _sources.GetById(id); var item = _sources.GetByID(id);
return SourceDto.Convert(item); return SourceDto.Convert(item);
} }

View File

@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Dto; using Newsbot.Collector.Domain.Dto;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
@ -44,8 +43,8 @@ public class SubscriptionsController : ControllerBase
public SubscriptionDetailsDto GetDetailsById(Guid id) public SubscriptionDetailsDto GetDetailsById(Guid id)
{ {
var sub = _subscription.GetById(id); var sub = _subscription.GetById(id);
var webhook = _discord.GetById(sub.DiscordWebHookId); var webhook = _discord.GetByID(sub.DiscordWebHookId);
var source = _sources.GetById(sub.SourceId); var source = _sources.GetByID(sub.SourceId);
return SubscriptionDetailsDto.Convert(sub, source, webhook); return SubscriptionDetailsDto.Convert(sub, source, webhook);
} }
@ -69,7 +68,7 @@ public class SubscriptionsController : ControllerBase
public IEnumerable<SubscriptionDto> GetBySourceId(Guid id) public IEnumerable<SubscriptionDto> GetBySourceId(Guid id)
{ {
var res = new List<SubscriptionDto>(); var res = new List<SubscriptionDto>();
var items = _subscription.ListBySourceId(id); var items = _subscription.ListBySourceID(id);
foreach (var item in items) res.Add(SubscriptionDto.Convert(item)); foreach (var item in items) res.Add(SubscriptionDto.Convert(item));
return res; return res;
} }
@ -83,13 +82,13 @@ public class SubscriptionsController : ControllerBase
var exists = _subscription.GetByWebhookAndSource(discordId, sourceId); var exists = _subscription.GetByWebhookAndSource(discordId, sourceId);
if (exists.Id != Guid.Empty) return SubscriptionDto.Convert(exists); if (exists.Id != Guid.Empty) return SubscriptionDto.Convert(exists);
var discord = _discord.GetById(discordId); var discord = _discord.GetByID(discordId);
if (discord.Id == Guid.Empty) return new BadRequestResult(); if (discord.ID == Guid.Empty) return new BadRequestResult();
var source = _sources.GetById(sourceId); var source = _sources.GetByID(sourceId);
if (source.Id == Guid.Empty) return new BadRequestResult(); if (source.ID == Guid.Empty) return new BadRequestResult();
var item = _subscription.New(new SubscriptionEntity var item = _subscription.New(new SubscriptionModel
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
SourceId = sourceId, SourceId = sourceId,
@ -111,13 +110,13 @@ public class SubscriptionsController : ControllerBase
var exists = _subscription.GetByWebhookAndSource(discordId, sourceId); var exists = _subscription.GetByWebhookAndSource(discordId, sourceId);
if (exists.Id != Guid.Empty) return SubscriptionDto.Convert(exists); if (exists.Id != Guid.Empty) return SubscriptionDto.Convert(exists);
var discord = _discord.GetById(discordId); var discord = _discord.GetByID(discordId);
if (discord.Id == Guid.Empty) return new BadRequestResult(); if (discord.ID == Guid.Empty) return new BadRequestResult();
var source = _sources.GetById(sourceId); var source = _sources.GetByID(sourceId);
if (source.Id == Guid.Empty) return new BadRequestResult(); if (source.ID == Guid.Empty) return new BadRequestResult();
var sub = _subscription.New(new SubscriptionEntity var sub = _subscription.New(new SubscriptionModel
{ {
DiscordWebHookId = discordId, DiscordWebHookId = discordId,
SourceId = sourceId, SourceId = sourceId,

View File

@ -14,11 +14,6 @@
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.33" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.7.33" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" /> <PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.4.0" /> <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.4.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.4.0" /> <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.4.0" />

View File

@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Newsbot.Collector.Api; using Newsbot.Collector.Api;
using Newsbot.Collector.Api.Authentication; using Newsbot.Collector.Api.Authentication;
using Newsbot.Collector.Database;
using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Domain.Models.Config; using Newsbot.Collector.Domain.Models.Config;
@ -72,8 +71,6 @@ builder.Services.AddSwaggerGen(cfg =>
cfg.AddSecurityRequirement(requirement); cfg.AddSecurityRequirement(requirement);
}); });
builder.Services.AddDbContext<DatabaseContext>();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

View File

@ -1,50 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Entities;
namespace Newsbot.Collector.Database;
public class DatabaseContext : DbContext
{
public DbSet<ArticlesEntity> Articles { get; set; } = null!;
public DbSet<DiscordQueueEntity> DiscordQueue { get; set; } = null!;
public DbSet<DiscordWebhookEntity> DiscordWebhooks { get; set; } = null!;
public DbSet<IconEntity> Icons { get; set; } = null!;
public DbSet<SourceEntity> Sources { get; set; } = null!;
public DbSet<SubscriptionEntity> Subscriptions { get; set; } = null!;
private string ConnectionString { get; set; }
public DatabaseContext(IConfiguration appsettings, string connectionString)
{
var connString = appsettings.GetConnectionString(ConfigConnectionStringConst.Database);
ConnectionString = connString ?? "";
}
public DatabaseContext(string connectionString)
{
ConnectionString = connectionString;
}
public DatabaseContext(DbContextOptions<DatabaseContext> connectionString)
{
ConnectionString = "";
}
public DatabaseContext()
{
ConnectionString = "";
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseNpgsql(ConnectionString);
}
public DatabaseContext(DbContextOptions<DatabaseContext> options, string connectionString)
: base(options)
{
ConnectionString = connectionString;
}
}

View File

@ -1,16 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
namespace Newsbot.Collector.Database;
public class DesignTimeContext :IDesignTimeDbContextFactory<DatabaseContext>
{
public DatabaseContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
// pass your design time connection string here
optionsBuilder.UseNpgsql("<connection_string>");
return new DatabaseContext(optionsBuilder.Options);
}
}

View File

@ -1,223 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Newsbot.Collector.Database;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Newsbot.Collector.Database.Migrations
{
[DbContext(typeof(DatabaseContext))]
[Migration("20230619043102_MigrationFromGoose")]
partial class MigrationFromGoose
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.ArticlesEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("AuthorImage")
.HasColumnType("text");
b.Property<string>("AuthorName")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("CodeIsCommit")
.HasColumnType("boolean");
b.Property<bool>("CodeIsRelease")
.HasColumnType("boolean");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("PubDate")
.HasColumnType("timestamp with time zone");
b.Property<Guid>("SourceId")
.HasColumnType("uuid");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Thumbnail")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.HasColumnType("text");
b.Property<string>("Video")
.IsRequired()
.HasColumnType("text");
b.Property<int>("VideoHeight")
.HasColumnType("integer");
b.Property<int>("VideoWidth")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Articles");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.DiscordQueueEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("ArticleId")
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("DiscordQueue");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.DiscordWebhookEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Channel")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Server")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("DiscordWebhooks");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.IconEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("FileName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Site")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("SourceId")
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("Icons");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.SourceEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("Deleted")
.HasColumnType("boolean");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Site")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Source")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.Property<string>("YoutubeId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Sources");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.SubscriptionEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("CodeAllowCommits")
.HasColumnType("boolean");
b.Property<bool>("CodeAllowReleases")
.HasColumnType("boolean");
b.Property<Guid>("DiscordWebHookId")
.HasColumnType("uuid");
b.Property<Guid>("SourceId")
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("Subscriptions");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,140 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.Configuration;
#nullable disable
namespace Newsbot.Collector.Database.Migrations
{
/// <inheritdoc />
public partial class MigrationFromGoose : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Articles",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
SourceId = table.Column<Guid>(type: "uuid", nullable: false),
Tags = table.Column<string>(type: "text", nullable: false),
Title = table.Column<string>(type: "text", nullable: false),
Url = table.Column<string>(type: "text", nullable: true),
PubDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Video = table.Column<string>(type: "text", nullable: false),
VideoHeight = table.Column<int>(type: "integer", nullable: false),
VideoWidth = table.Column<int>(type: "integer", nullable: false),
Thumbnail = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
AuthorName = table.Column<string>(type: "text", nullable: false),
AuthorImage = table.Column<string>(type: "text", nullable: true),
CodeIsRelease = table.Column<bool>(type: "boolean", nullable: false),
CodeIsCommit = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Articles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "DiscordQueue",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
ArticleId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DiscordQueue", x => x.Id);
});
migrationBuilder.CreateTable(
name: "DiscordWebhooks",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
Url = table.Column<string>(type: "text", nullable: false),
Server = table.Column<string>(type: "text", nullable: false),
Channel = table.Column<string>(type: "text", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DiscordWebhooks", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Icons",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
FileName = table.Column<string>(type: "text", nullable: false),
Site = table.Column<string>(type: "text", nullable: false),
SourceId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Icons", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Sources",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
Site = table.Column<string>(type: "text", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
Source = table.Column<string>(type: "text", nullable: false),
Type = table.Column<string>(type: "text", nullable: false),
Value = table.Column<string>(type: "text", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false),
Url = table.Column<string>(type: "text", nullable: false),
Tags = table.Column<string>(type: "text", nullable: false),
Deleted = table.Column<bool>(type: "boolean", nullable: false),
YoutubeId = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Sources", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Subscriptions",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CodeAllowReleases = table.Column<bool>(type: "boolean", nullable: false),
CodeAllowCommits = table.Column<bool>(type: "boolean", nullable: false),
SourceId = table.Column<Guid>(type: "uuid", nullable: false),
DiscordWebHookId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Subscriptions", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Articles");
migrationBuilder.DropTable(
name: "DiscordQueue");
migrationBuilder.DropTable(
name: "DiscordWebhooks");
migrationBuilder.DropTable(
name: "Icons");
migrationBuilder.DropTable(
name: "Sources");
migrationBuilder.DropTable(
name: "Subscriptions");
}
}
}

View File

@ -1,220 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Newsbot.Collector.Database;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Newsbot.Collector.Database.Migrations
{
[DbContext(typeof(DatabaseContext))]
partial class DatabaseContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.ArticlesEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("AuthorImage")
.HasColumnType("text");
b.Property<string>("AuthorName")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("CodeIsCommit")
.HasColumnType("boolean");
b.Property<bool>("CodeIsRelease")
.HasColumnType("boolean");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("PubDate")
.HasColumnType("timestamp with time zone");
b.Property<Guid>("SourceId")
.HasColumnType("uuid");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Thumbnail")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.HasColumnType("text");
b.Property<string>("Video")
.IsRequired()
.HasColumnType("text");
b.Property<int>("VideoHeight")
.HasColumnType("integer");
b.Property<int>("VideoWidth")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Articles");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.DiscordQueueEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("ArticleId")
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("DiscordQueue");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.DiscordWebhookEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Channel")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Server")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("DiscordWebhooks");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.IconEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("FileName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Site")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("SourceId")
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("Icons");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.SourceEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("Deleted")
.HasColumnType("boolean");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Site")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Source")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.Property<string>("YoutubeId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Sources");
});
modelBuilder.Entity("Newsbot.Collector.Domain.Entities.SubscriptionEntity", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("CodeAllowCommits")
.HasColumnType("boolean");
b.Property<bool>("CodeAllowReleases")
.HasColumnType("boolean");
b.Property<Guid>("DiscordWebHookId")
.HasColumnType("uuid");
b.Property<Guid>("SourceId")
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("Subscriptions");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -6,14 +6,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="dapper" Version="2.0.123" /> <PackageReference Include="dapper" Version="2.0.123" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Npgsql" Version="7.0.4" /> <PackageReference Include="Npgsql" Version="7.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>

View File

@ -1,8 +1,6 @@
using System.Data; using System.Data;
using Dapper; using Dapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Npgsql; using Npgsql;
@ -13,12 +11,9 @@ public class ArticlesTable : IArticlesRepository
{ {
private readonly string _connectionString; private readonly string _connectionString;
private DatabaseContext _context;
public ArticlesTable(string connectionString) public ArticlesTable(string connectionString)
{ {
_connectionString = connectionString; _connectionString = connectionString;
_context = new DatabaseContext(connectionString);
} }
public ArticlesTable(IConfiguration configuration) public ArticlesTable(IConfiguration configuration)
@ -27,56 +22,55 @@ public class ArticlesTable : IArticlesRepository
if (conn is null) conn = ""; if (conn is null) conn = "";
_connectionString = conn; _connectionString = conn;
_context = new DatabaseContext(conn);
} }
public List<ArticlesEntity> List(int page = 0, int count = 25) public List<ArticlesModel> List(int page = 0, int count = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var query = context.Articles var res = conn.Query<ArticlesModel>(@"select * from articles
.Skip(page * count) Order By PubDate Desc
.OrderBy(d => d.PubDate) Offset @Page
.Take(25); Fetch Next @Count Rows Only", new
Console.WriteLine(query.ToQueryString()); {
return query.ToList(); Page = page * count,
} Count = count
})
public ArticlesEntity GetById(Guid id) .ToList();
{
using var context = new DatabaseContext(_connectionString);
var query = context.Articles
.FirstOrDefault(d => d.Id.Equals(id));
query ??= new ArticlesEntity();
return query;
}
public ArticlesEntity GetByUrl(string url)
{
using var context = new DatabaseContext(_connectionString);
var res = context.Articles.FirstOrDefault(d => d.Url!.Equals(url));
res ??= new ArticlesEntity();
return res; return res;
} }
public List<ArticlesEntity> ListBySourceId(Guid id, int page, int count) public ArticlesModel GetById(Guid ID)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Articles var res = conn.Query<ArticlesModel>("select * from articles where ID = @ID", new { ID });
.Skip(page * count) if (res.Count() == 0) return new ArticlesModel();
.Where(d => d.SourceId.Equals(id)); return res.First();
return res.ToList();
} }
public ArticlesEntity New(ArticlesEntity model) public ArticlesModel GetByUrl(string url)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
model.Id = new Guid(); var res = conn.Query<ArticlesModel>("select * from articles where Url = @Url Limit 1", new { Url = url });
var query = context.Articles.Add(model); if (res.Count() == 0) return new ArticlesModel();
context.SaveChanges(); return res.First();
return model;
} }
public ArticlesModel NewDapper(ArticlesModel model) public List<ArticlesModel> ListBySourceId(Guid id, int page, int count)
{
using var conn = OpenConnection(_connectionString);
var query = @"Select * from articles
where sourceid = @sourceid
Offset @page
Fetch next @count rows only";
return conn.Query<ArticlesModel>(query, new
{
sourceid = id,
page = page * count,
count
}).ToList();
}
public ArticlesModel New(ArticlesModel model)
{ {
model.ID = Guid.NewGuid(); model.ID = Guid.NewGuid();
@ -106,17 +100,12 @@ public class ArticlesTable : IArticlesRepository
public void DeleteAllBySourceId(Guid sourceId) public void DeleteAllBySourceId(Guid sourceId)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Articles var res = conn.Execute("Delete from articles where sourceid = '@id'", new
.Where(d => d.SourceId.Equals(sourceId))
.ToList();
foreach (var item in res)
{ {
context.Articles.Remove(item); sourceId
} });
if (res == 0) throw new Exception($"No records where deleted that linked to SourceId = '{sourceId}'");
context.SaveChanges();
} }
private IDbConnection OpenConnection(string connectionString) private IDbConnection OpenConnection(string connectionString)

View File

@ -1,6 +1,5 @@
using System.Data; using System.Data;
using Dapper; using Dapper;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Npgsql; using Npgsql;
@ -23,28 +22,33 @@ public class DiscordQueueTable : IDiscordQueueRepository
return conn; return conn;
} }
public void New(DiscordQueueEntity model) public void New(DiscordQueueModel model)
{ {
model.Id = new Guid(); using var conn = OpenConnection(_connectionString);
var query = "Insert into DiscordQueue(ID, ArticleId) Values (@id, @articleid);";
using var context = new DatabaseContext(_connectionString); conn.Execute(query, new
var res = context.DiscordQueue.Add(model); {
context.SaveChanges(); id = Guid.NewGuid(),
articleid = model.ArticleID
});
} }
public void Delete(Guid id) public void Delete(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordQueue.FirstOrDefault(d => d.Id.Equals(id)); var query = "Delete From DiscordQueue Where ID = @id;";
res ??= new DiscordQueueEntity(); conn.Execute(query, new
context.DiscordQueue.Remove(res); {
context.SaveChanges(); id = id
});
} }
public List<DiscordQueueEntity> List(int limit = 25) public List<DiscordQueueModel> List(int limit = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordQueue.Take(limit).ToList(); var query = "Select * from DiscordQueue LIMIT @limit;";
return res; return conn.Query<DiscordQueueModel>(query, new {
limit = limit
}).ToList();
} }
} }

View File

@ -2,7 +2,7 @@ using System.Data;
using Dapper; using Dapper;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Entities; using Newsbot.Collector.Domain.Models;
using Npgsql; using Npgsql;
namespace Newsbot.Collector.Database.Repositories; namespace Newsbot.Collector.Database.Repositories;
@ -22,104 +22,103 @@ public class DiscordWebhooksTable : IDiscordWebHooksRepository
_connectionString = connstr; _connectionString = connstr;
} }
public DiscordWebhookEntity New(DiscordWebhookEntity model) public DiscordWebHookModel New(DiscordWebHookModel model)
{ {
model.Id = new Guid(); var uid = Guid.NewGuid();
using var conn = OpenConnection(_connectionString);
using var context = new DatabaseContext(_connectionString); var query =
context.DiscordWebhooks.Add(model); "Insert Into DiscordWebHooks (ID, Url, Server, Channel, Enabled) Values (@id, @url, @server, @channel, @enabled);";
context.SaveChanges(); conn.Execute(query, new
{
id = uid,
url = model.Url,
server = model.Server,
channel = model.Channel,
enabled = model.Enabled
});
model.ID = uid;
return model; return model;
} }
public DiscordWebhookEntity GetById(Guid id) public DiscordWebHookModel GetByID(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordWebhooks.FirstOrDefault(d => d.Id.Equals(id)); var query = "Select * from DiscordWebHooks Where ID = @id LIMIT 1;";
res ??= new DiscordWebhookEntity(); return conn.Query<DiscordWebHookModel>(query, new
return res; {
id
}).First();
} }
public DiscordWebhookEntity GetByUrl(string url) public DiscordWebHookModel GetByUrl(string url)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordWebhooks.FirstOrDefault(d => d.Url.Equals(url)); var query = "Select * From DiscordWebHooks Where url = @url;";
res ??= new DiscordWebhookEntity(); try
return res; {
var res = conn.QueryFirst<DiscordWebHookModel>(query, new
{
url
});
return res;
}
catch
{
return new DiscordWebHookModel();
}
} }
public List<DiscordWebhookEntity> List(int page, int count = 25) public List<DiscordWebHookModel> List(int page, int count = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordWebhooks var query = @"Select * From DiscordWebHooks
.Skip(page * count) Offset @offset Fetch Next @count Rows Only;";
.Take(count) return conn.Query<DiscordWebHookModel>(query, new
.ToList(); {
res ??= new List<DiscordWebhookEntity>(); offset = page * count, count
return res; }).ToList();
} }
public List<DiscordWebhookEntity> ListByServer(string server, int limit = 25) public List<DiscordWebHookModel> ListByServer(string server, int limit = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordWebhooks var query = "Select * From DiscordWebHooks Where Server = @id Limit @limit;";
.Where(d => d.Server.Equals(server)) return conn.Query<DiscordWebHookModel>(query, new
.Take(limit) {
.ToList(); server, limit
res ??= new List<DiscordWebhookEntity>(); }).ToList();
return res;
} }
public List<DiscordWebhookEntity> ListByServerAndChannel(string server, string channel, int limit = 25) public List<DiscordWebHookModel> ListByServerAndChannel(string server, string channel, int limit = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.DiscordWebhooks var query = "SELECT * FROM DiscordWebHooks WHERE Server = @server and Channel = @channel Limit @limit;";
.Where(s => s.Server.Equals(server)) return conn.Query<DiscordWebHookModel>(query, new
.Where(c => c.Channel.Equals(channel)) {
.Take(limit) server,
.ToList(); channel,
res ??= new List<DiscordWebhookEntity>(); limit
return res; }).ToList();
} }
public int Disable(Guid id) public int Disable(Guid id)
{ {
var res = GetById(id); using var conn = OpenConnection(_connectionString);
using var context = new DatabaseContext(_connectionString); var query = "Update discordwebhooks Set Enabled = FALSE where ID = @id;";
return conn.Execute(query, new
res.Enabled = true;
context.DiscordWebhooks.Update(res);
try
{ {
context.SaveChanges(); id
return 1; });
}
catch(Exception ex)
{
Console.WriteLine($"Failed to update DiscordWebhook ID = {id}. {ex.Message}");
return 0;
}
} }
public int Enable(Guid id) public int Enable(Guid id)
{ {
var res = GetById(id); using var conn = OpenConnection(_connectionString);
using var context = new DatabaseContext(_connectionString); var query = "Update discordwebhooks Set Enabled = TRUE where ID = @id;";
return conn.Execute(query, new
res.Enabled = false;
context.DiscordWebhooks.Update(res);
try
{ {
context.SaveChanges(); id
return 1; });
}
catch(Exception ex)
{
Console.WriteLine($"Failed to update DiscordWebhook ID = {id}. {ex.Message}");
return 0;
}
} }
private IDbConnection OpenConnection(string connectionString) private IDbConnection OpenConnection(string connectionString)

View File

@ -1,7 +1,6 @@
using System.Data; using System.Data;
using Dapper; using Dapper;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Npgsql; using Npgsql;
@ -24,29 +23,37 @@ public class IconsTable : IIconsRepository
_connectionString = connstr; _connectionString = connstr;
} }
public void New(IconEntity model) public void New(IconModel model)
{ {
using var context = new DatabaseContext(_connectionString);
model.Id = Guid.NewGuid(); model.Id = Guid.NewGuid();
context.Icons.Add(model); using var conn = OpenConnection(_connectionString);
context.SaveChanges(); var q = @"Insert Into icons (id, filename, site, sourceid) values (@Id,@FileName, @Site, @SourceId)";
conn.Execute(q, model);
} }
public IconEntity GetById(Guid id) public IconModel GetById(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Icons.FirstOrDefault(f => f.Id.Equals(id)); var query = "Select * From icons where ID = @id Limit 1;";
res ??= new IconEntity(); var res = conn.Query<IconModel>(query, new
return res; {
id
});
if (!res.Any()) return new IconModel();
return res.First();
} }
public IconEntity GetBySourceId(Guid id) public IconModel GetBySourceId(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Icons.FirstOrDefault(f => f.SourceId.Equals(id)); var query = "Select * From icons where sourceid = @id Limit 1;";
res ??= new IconEntity(); var res = conn.Query<IconModel>(query, new
return res; {
id
});
if (!res.Any()) return new IconModel();
return res.First();
} }
private IDbConnection OpenConnection(string connectionString) private IDbConnection OpenConnection(string connectionString)

View File

@ -1,7 +1,6 @@
using System.Data; using System.Data;
using Dapper; using Dapper;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Npgsql; using Npgsql;
@ -24,153 +23,157 @@ public class SourcesTable : ISourcesRepository
_connectionString = connstr; _connectionString = connstr;
} }
public SourceEntity New(SourceEntity model) public SourceModel New(SourceModel model)
{ {
model.Id = Guid.NewGuid(); model.ID = Guid.NewGuid();
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
context.Sources.Add(model); var query =
try "Insert Into Sources (ID, Site, Name, Source, Type, Value, Enabled, Url, Tags, YoutubeId) Values (@id ,@site,@name,@source,@type,@value,@enabled,@url,@tags,@youtubeid);";
conn.Execute(query, new
{ {
context.SaveChanges(); id = model.ID,
} model.Site,
catch (Exception ex) model.Name,
{ model.Source,
Console.WriteLine($"Failed to save source to db. {model.ToString()} {ex.Message} "); model.Type,
} model.Value,
model.Enabled,
model.Url,
model.Tags,
model.YoutubeId
});
return model; return model;
} }
public SourceEntity GetById(Guid id) public SourceModel GetByID(Guid ID)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources.FirstOrDefault(f => f.Id.Equals(id)); var query = "Select * From Sources where ID = @id Limit 1;";
res ??= new SourceEntity(); var res = conn.Query<SourceModel>(query, new
return res; {
id = ID
});
if (res.Count() == 0) return new SourceModel();
return res.First();
} }
public SourceEntity GetById(string id) public SourceModel GetByID(string ID)
{ {
var uid = Guid.Parse(id); var uid = Guid.Parse(ID);
return GetById(uid); return GetByID(uid);
} }
public SourceEntity GetByName(string name) public SourceModel GetByName(string Name)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources.FirstOrDefault(f => f.Name.Equals(name)); var query = "Select * from Sources where name = @name Limit 1;";
res ??= new SourceEntity(); var res = conn.Query<SourceModel>(query, new
return res; {
name = Name
});
if (res.Count() == 0) return new SourceModel();
return res.First();
} }
public SourceEntity GetByNameAndType(string name, string type) public SourceModel GetByNameAndType(string name, string type)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources var query = "Select * from Sources WHERE name = @name and type = @type;";
.Where(f => f.Name.Equals(name)) var res = conn.Query<SourceModel>(query, new
.FirstOrDefault(f => f.Type.Equals(type)); {
res ??= new SourceEntity(); name, type
return res; });
if (res.Count() == 0) return new SourceModel();
return res.First();
} }
public SourceEntity GetByUrl(string url) public SourceModel GetByUrl(string url)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources var query = "Select * from Sources WHERE url = @url;";
.FirstOrDefault(f => f.Url.Equals(url)); var res = conn.Query<SourceModel>(query, new
res ??= new SourceEntity(); {
return res; url
});
if (res.ToList().Count == 0) return new SourceModel();
return res.First();
} }
public List<SourceEntity> List(int page = 0, int count = 100) public List<SourceModel> List(int page = 0, int count = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources var query = @"Select * From Sources
.Skip(page * count) Offset @page
.Take(count) Fetch Next @count Rows Only;";
.ToList(); return conn.Query<SourceModel>(query, new
return res; {
page = page * count, count
}).ToList();
} }
public List<SourceEntity> ListBySource(string source, int page = 0, int limit = 25) public List<SourceModel> ListBySource(string source, int limit = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources var query = "Select * From Sources where Source = @source Limit @limit;";
.Where(f => f.Source.Equals(source)) return conn.Query<SourceModel>(query, new
.Skip(page * limit) {
.Take(limit) source, limit
.ToList(); }).ToList();
return res;
} }
public List<SourceEntity> ListByType(string type,int page = 0, int limit = 25) public List<SourceModel> ListByType(string type, int limit = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Sources var query = "Select * From Sources where Type = @type Limit @limit;";
.Where(f => f.Type.Equals(type)) return conn.Query<SourceModel>(query, new
.Skip(page * limit) {
.Take(limit) type, limit
.ToList(); }).ToList();
return res;
} }
public int Disable(Guid id) public int Disable(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = GetById(id); var query = "Update Sources Set Enabled = FALSE where ID = @id;";
res.Enabled = false; return conn.Execute(query, new
context.Sources.Update(res);
try
{ {
context.SaveChanges(); id
return 1; });
}
catch
{
return 0;
}
} }
public int Enable(Guid id) public int Enable(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = GetById(id); var query = "Update Sources Set Enabled = TRUE where ID = @id;";
res.Enabled = true; return conn.Execute(query, new
context.Sources.Update(res);
try
{ {
context.SaveChanges(); id
return 1; });
}
catch
{
return 0;
}
} }
public void Delete(Guid id) public void Delete(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = GetById(id); var query = "Delete From sources where id = @id;";
context.Sources.Remove(res); var res = conn.Execute(query, new
context.SaveChanges(); {
id
});
if (res == 0) throw new Exception("Nothing was deleted");
} }
public int UpdateYoutubeId(Guid id, string youtubeId) public int UpdateYoutubeId(Guid id, string youtubeId)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = GetById(id); var query = "Update Sources Set youtubeid = @youtubeId where ID = @id;";
res.YoutubeId = youtubeId; return conn.Execute(query, new
context.Sources.Update(res);
try
{ {
context.SaveChanges(); id, youtubeId
return 1; });
}
catch
{
return 0;
}
} }
private IDbConnection OpenConnection(string connectionString) private IDbConnection OpenConnection(string connectionString)

View File

@ -1,7 +1,6 @@
using System.Data; using System.Data;
using Dapper; using Dapper;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Npgsql; using Npgsql;
@ -24,64 +23,104 @@ public class SubscriptionsTable : ISubscriptionRepository
_connectionString = connstr; _connectionString = connstr;
} }
public SubscriptionEntity New(SubscriptionEntity model) public SubscriptionModel New(SubscriptionModel model)
{ {
model.Id = new Guid(); model.Id = Guid.NewGuid();
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
context.Subscriptions.Add(model); var query =
context.SaveChanges(); "Insert Into subscriptions (ID, DiscordWebHookId, SourceId, codeAllowCommits, codeAllowReleases) Values (@id, @webhookId, @sourceId, @codeAllowCommits, @codeAllowReleases);";
return model; try
{
conn.Execute(query, new
{
id = model.Id,
webhookId = model.DiscordWebHookId,
sourceId = model.SourceId,
codeAllowCommits = model.CodeAllowCommits,
codeAllowReleases = model.CodeAllowReleases
});
return model;
}
catch
{
return new SubscriptionModel();
}
} }
public List<SubscriptionEntity> List(int page = 0, int count = 25) public List<SubscriptionModel> List(int page = 0, int count = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
return context.Subscriptions.Skip(page * count).Take(count).ToList(); var query = @"Select * From subscriptions
Offset @page Fetch Next @count Rows Only;";
return conn.Query<SubscriptionModel>(query, new
{
page = page * count, count
}).ToList();
} }
public List<SubscriptionEntity> ListBySourceId(Guid id, int page = 0, int count = 25) public List<SubscriptionModel> ListBySourceID(Guid id, int page = 0, int count = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
return context.Subscriptions.Where(f => f.SourceId.Equals(id)) var query = @"Select * From subscriptions
.Skip(page * count) Where sourceid = @sourceid
.ToList(); Offset @page Fetch Next @count Rows Only";
return conn.Query<SubscriptionModel>(query, new
{
page = page * count,
count,
sourceid = id
}).ToList();
} }
public List<SubscriptionEntity> ListByWebhook(Guid id, int page = 0, int count = 25) public List<SubscriptionModel> ListByWebhook(Guid id, int page = 0, int count = 25)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
return context.Subscriptions.Where(f => f.DiscordWebHookId.Equals(id)).Skip(page * count).ToList(); var query = @"Select * From subscriptions
Where discordwebhookid = @webhookid
Offset @page Fetch Next @count Rows Only";
return conn.Query<SubscriptionModel>(query, new
{
page = page * count,
count,
webhookid = id
}).ToList();
} }
public SubscriptionEntity GetById(Guid id) public SubscriptionModel GetById(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Subscriptions var query = @"Select * From subscriptions Where id = @id;";
.FirstOrDefault(f => f.Id.Equals(id)); var res = conn.Query<SubscriptionModel>(query, new
return res ??= new SubscriptionEntity(); {
id
});
if (res.Count() == 0) return new SubscriptionModel();
return res.First();
} }
public SubscriptionEntity GetByWebhookAndSource(Guid webhookId, Guid sourceId) public SubscriptionModel GetByWebhookAndSource(Guid webhookId, Guid sourceId)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Subscriptions var query = @"Select * From subscriptions
.Where(f => f.DiscordWebHookId.Equals(webhookId)) Where discordwebhookid = @webhookid
.FirstOrDefault(f => f.SourceId.Equals(sourceId)); and sourceid = @sourceid;";
return res ??= new SubscriptionEntity(); var res = conn.Query<SubscriptionModel>(query, new
{
webhookid = webhookId,
sourceid = sourceId
});
if (res.Count() == 0) return new SubscriptionModel();
return res.First();
} }
public void Delete(Guid id) public void Delete(Guid id)
{ {
using var context = new DatabaseContext(_connectionString); using var conn = OpenConnection(_connectionString);
var res = context.Subscriptions.FirstOrDefault(f => f.Id.Equals(id)); var query = "Delete From subscriptions Where id = @id;";
if (res is null) conn.Execute(query, new
{ {
return; id
} });
context.Subscriptions.Remove(res);
context.SaveChanges();
} }
private IDbConnection OpenConnection(string connectionString) private IDbConnection OpenConnection(string connectionString)

View File

@ -1,11 +1,10 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Dto; namespace Newsbot.Collector.Domain.Dto;
public class ArticleDetailsDto public class ArticleDetailsDto
{ {
public Guid Id { get; set; } public Guid ID { get; set; }
public string[]? Tags { get; set; } public string[]? Tags { get; set; }
public string? Title { get; set; } public string? Title { get; set; }
public string? Url { get; set; } public string? Url { get; set; }
@ -20,14 +19,14 @@ public class ArticleDetailsDto
public SourceDto? Source { get; set; } public SourceDto? Source { get; set; }
public static ArticleDetailsDto Convert(ArticlesEntity article, SourceEntity source) public static ArticleDetailsDto Convert(ArticlesModel article, SourceModel source)
{ {
return new ArticleDetailsDto return new ArticleDetailsDto
{ {
Id = article.Id, ID = article.ID,
Tags = article.Tags.Split(','), Tags = article.Tags.Split(','),
Title = article.Title, Title = article.Title,
Url = article.Url, Url = article.URL,
PubDate = article.PubDate, PubDate = article.PubDate,
Video = article.Video, Video = article.Video,
VideoHeight = article.VideoHeight, VideoHeight = article.VideoHeight,

View File

@ -1,4 +1,3 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Dto; namespace Newsbot.Collector.Domain.Dto;
@ -18,7 +17,7 @@ public class ArticleDto
public string? Description { get; set; } public string? Description { get; set; }
public string? AuthorName { get; set; } public string? AuthorName { get; set; }
public string? AuthorImage { get; set; } public string? AuthorImage { get; set; }
public static ArticleDto Convert(ArticlesModel article) public static ArticleDto Convert(ArticlesModel article)
{ {
return new ArticleDto return new ArticleDto
{ {
@ -37,24 +36,4 @@ public class ArticleDto
AuthorImage = article.AuthorImage, AuthorImage = article.AuthorImage,
}; };
} }
public static ArticleDto Convert(ArticlesEntity article)
{
return new ArticleDto
{
ID = article.Id,
SourceID = article.SourceId,
Tags = article.Tags.Split(','),
Title = article.Title,
Url = article.Url,
PubDate = article.PubDate,
Video = article.Video,
VideoHeight = article.VideoHeight,
VideoWidth = article.VideoWidth,
Thumbnail = article.Thumbnail,
Description = article.Description,
AuthorName = article.AuthorName,
AuthorImage = article.AuthorImage,
};
}
} }

View File

@ -1,4 +1,4 @@
using Newsbot.Collector.Domain.Entities; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Dto; namespace Newsbot.Collector.Domain.Dto;
@ -10,11 +10,11 @@ public class DiscordWebHookDto
public string? Channel { get; set; } public string? Channel { get; set; }
public bool Enabled { get; set; } public bool Enabled { get; set; }
public static DiscordWebHookDto Convert(DiscordWebhookEntity model) public static DiscordWebHookDto Convert(DiscordWebHookModel model)
{ {
return new DiscordWebHookDto return new DiscordWebHookDto
{ {
ID = model.Id, ID = model.ID,
Url = model.Url, Url = model.Url,
Server = model.Server, Server = model.Server,
Channel = model.Channel, Channel = model.Channel,

View File

@ -1,5 +1,4 @@
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Dto; namespace Newsbot.Collector.Domain.Dto;
@ -17,10 +16,10 @@ public class SourceDto
public string[]? Tags { get; set; } public string[]? Tags { get; set; }
public bool Deleted { get; set; } public bool Deleted { get; set; }
public static SourceDto Convert(SourceEntity model) { public static SourceDto Convert(SourceModel model) {
return new SourceDto return new SourceDto
{ {
ID = model.Id, ID = model.ID,
Site = model.Site, Site = model.Site,
Name = model.Name, Name = model.Name,
Source = model.Source, Source = model.Source,

View File

@ -1,4 +1,3 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Dto; namespace Newsbot.Collector.Domain.Dto;
@ -11,8 +10,8 @@ public class SubscriptionDetailsDto
public SourceDto? Source { get; set; } public SourceDto? Source { get; set; }
public DiscordWebHookDto? DiscordWebHook { get; set; } public DiscordWebHookDto? DiscordWebHook { get; set; }
public static SubscriptionDetailsDto Convert(SubscriptionEntity subscription, SourceEntity source, public static SubscriptionDetailsDto Convert(SubscriptionModel subscription, SourceModel source,
DiscordWebhookEntity discord) DiscordWebHookModel discord)
{ {
return new SubscriptionDetailsDto return new SubscriptionDetailsDto
{ {

View File

@ -1,4 +1,3 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Dto; namespace Newsbot.Collector.Domain.Dto;
@ -11,7 +10,7 @@ public class SubscriptionDto
public bool CodeAllowReleases { get; set; } public bool CodeAllowReleases { get; set; }
public bool CodeAllowCommits { get; set; } public bool CodeAllowCommits { get; set; }
public static SubscriptionDto Convert(SubscriptionEntity model) public static SubscriptionDto Convert(SubscriptionModel model)
{ {
return new SubscriptionDto return new SubscriptionDto
{ {

View File

@ -1,20 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class ArticlesEntity
{
public Guid Id { get; set; }
public Guid SourceId { get; set; }
public string Tags { get; set; } = "";
public string Title { get; set; } = "";
public string? Url { get; set; }
public DateTime PubDate { get; set; } = DateTime.Now;
public string Video { get; set; } = "";
public int VideoHeight { get; set; } = 0;
public int VideoWidth { get; set; } = 0;
public string Thumbnail { get; set; } = "";
public string Description { get; set; } = "";
public string AuthorName { get; set; } = "";
public string? AuthorImage { get; set; }
public bool CodeIsRelease { get; set; }
public bool CodeIsCommit { get; set; }
}

View File

@ -1,9 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class AuthorEntity
{
public Guid Id { get; set; }
public Guid SourceId { get; set; }
public string Name { get; set; } = "";
public string Image { get; set; } = "";
}

View File

@ -1,7 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class DiscordQueueEntity
{
public Guid Id { get; set; }
public Guid ArticleId { get; set; }
}

View File

@ -1,10 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class DiscordWebhookEntity
{
public Guid Id { get; set; }
public string Url { get; set; } = "";
public string Server { get; set; } = "";
public string Channel { get; set; } = "";
public bool Enabled { get; set; }
}

View File

@ -1,10 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class IconEntity
{
public Guid Id { get; set; }
public string FileName { get; set; } = "";
public string Site { get; set; } = "";
public Guid SourceId { get; set; }
}

View File

@ -1,18 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class SourceEntity
{
public Guid Id { get; set; }
public string Site { get; set; } = "";
public string Name { get; set; } = "";
// Source use to define the worker to query with but moving to Type as it was not used really.
public string Source { get; set; } = "";
public string Type { get; set; } = "";
public string Value { get; set; } = "";
public bool Enabled { get; set; }
public string Url { get; set; } = "";
public string Tags { get; set; } = "";
public bool Deleted { get; set; }
public string YoutubeId { get; set; } = "";
}

View File

@ -1,11 +0,0 @@
namespace Newsbot.Collector.Domain.Entities;
public class SubscriptionEntity
{
public Guid Id { get; set; }
public bool CodeAllowReleases { get; set; }
public bool CodeAllowCommits { get; set; }
public Guid SourceId { get; set; }
public Guid DiscordWebHookId { get; set; }
}

View File

@ -1,14 +1,13 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Interfaces; namespace Newsbot.Collector.Domain.Interfaces;
public interface IArticlesRepository : ITableRepository public interface IArticlesRepository : ITableRepository
{ {
List<ArticlesEntity> List(int page, int count); List<ArticlesModel> List(int page, int count);
List<ArticlesEntity> ListBySourceId(Guid id, int page = 0, int count = 25); List<ArticlesModel> ListBySourceId(Guid id, int page = 0, int count = 25);
ArticlesEntity GetById(Guid id); ArticlesModel GetById(Guid ID);
ArticlesEntity GetByUrl(string url); ArticlesModel GetByUrl(string url);
ArticlesEntity New(ArticlesEntity model); ArticlesModel New(ArticlesModel model);
void DeleteAllBySourceId(Guid sourceId); void DeleteAllBySourceId(Guid sourceId);
} }

View File

@ -1,10 +1,10 @@
using Newsbot.Collector.Domain.Entities; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Interfaces; namespace Newsbot.Collector.Domain.Interfaces;
public interface IDiscordQueueRepository public interface IDiscordQueueRepository
{ {
void New(DiscordQueueEntity model); void New(DiscordQueueModel model);
void Delete(Guid id); void Delete(Guid id);
List<DiscordQueueEntity> List(int limit); List<DiscordQueueModel> List(int limit);
} }

View File

@ -1,17 +1,18 @@
using Newsbot.Collector.Domain.Entities; using Microsoft.VisualBasic;
using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Interfaces; namespace Newsbot.Collector.Domain.Interfaces;
public interface IDiscordWebHooksRepository public interface IDiscordWebHooksRepository
{ {
DiscordWebhookEntity New(DiscordWebhookEntity model); DiscordWebHookModel New(DiscordWebHookModel model);
DiscordWebhookEntity GetById(Guid id); DiscordWebHookModel GetByID(Guid id);
DiscordWebhookEntity GetByUrl(string url); DiscordWebHookModel GetByUrl(string url);
List<DiscordWebhookEntity> List(int page, int count = 25); List<DiscordWebHookModel> List(int page, int count = 25);
List<DiscordWebhookEntity> ListByServer(string server, int limit); List<DiscordWebHookModel> ListByServer(string server, int limit);
List<DiscordWebhookEntity> ListByServerAndChannel(string server, string channel, int limit); List<DiscordWebHookModel> ListByServerAndChannel(string server, string channel, int limit);
int Disable(Guid id); int Disable(Guid id);
int Enable(Guid id); int Enable(Guid id);

View File

@ -1,11 +1,11 @@
using Newsbot.Collector.Domain.Entities; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Interfaces; namespace Newsbot.Collector.Domain.Interfaces;
public interface IIconsRepository public interface IIconsRepository
{ {
public void New(IconEntity model); public void New(IconModel model);
public IconEntity GetById(Guid id); public IconModel GetById(Guid id);
public IconEntity GetBySourceId(Guid id); public IconModel GetBySourceId(Guid id);
} }

View File

@ -1,19 +1,18 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Interfaces; namespace Newsbot.Collector.Domain.Interfaces;
public interface ISourcesRepository public interface ISourcesRepository
{ {
public SourceEntity New(SourceEntity model); public SourceModel New(SourceModel model);
public SourceEntity GetById(Guid id); public SourceModel GetByID(Guid ID);
public SourceEntity GetById(string id); public SourceModel GetByID(string ID);
public SourceEntity GetByName(string name); public SourceModel GetByName(string name);
public SourceEntity GetByNameAndType(string name, string type); public SourceModel GetByNameAndType(string name, string type);
SourceEntity GetByUrl(string url); SourceModel GetByUrl(string url);
public List<SourceEntity> List(int page, int count); public List<SourceModel> List(int page, int count);
public List<SourceEntity> ListBySource(string source,int page, int limit); public List<SourceModel> ListBySource(string source, int limit);
public List<SourceEntity> ListByType(string type,int page, int limit = 25); public List<SourceModel> ListByType(string type, int limit = 25);
public int Disable(Guid id); public int Disable(Guid id);
public int Enable(Guid id); public int Enable(Guid id);
public void Delete(Guid id); public void Delete(Guid id);

View File

@ -1,18 +1,17 @@
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Domain.Interfaces; namespace Newsbot.Collector.Domain.Interfaces;
public interface ISubscriptionRepository public interface ISubscriptionRepository
{ {
SubscriptionEntity New(SubscriptionEntity model); SubscriptionModel New(SubscriptionModel model);
List<SubscriptionEntity> List(int page = 0, int count = 25); List<SubscriptionModel> List(int page = 0, int count = 25);
List<SubscriptionEntity> ListBySourceId(Guid id, int page = 0, int count = 25); List<SubscriptionModel> ListBySourceID(Guid id, int page = 0, int count = 25);
List<SubscriptionEntity> ListByWebhook(Guid id, int page = 0, int count = 25); List<SubscriptionModel> ListByWebhook(Guid id, int page = 0, int count = 25);
SubscriptionEntity GetById(Guid id); SubscriptionModel GetById(Guid id);
SubscriptionEntity GetByWebhookAndSource(Guid webhookId, Guid sourceId); SubscriptionModel GetByWebhookAndSource(Guid webhookId, Guid sourceId);
void Delete(Guid id); void Delete(Guid id);
} }

View File

@ -3,7 +3,6 @@ using System.ServiceModel.Syndication;
using System.Xml; using System.Xml;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Domain.Models.Config; using Newsbot.Collector.Domain.Models.Config;
@ -61,10 +60,10 @@ public class CodeProjectWatcherJob
private void Execute() private void Execute()
{ {
var sources = _source.ListByType(SourceTypes.CodeProject, 0, 100); var sources = _source.ListByType(SourceTypes.CodeProject);
// query sources for things to pull // query sources for things to pull
var items = new List<ArticlesEntity>(); var items = new List<ArticlesModel>();
foreach (var source in sources) foreach (var source in sources)
{ {
@ -75,14 +74,14 @@ public class CodeProjectWatcherJob
foreach (var item in items) foreach (var item in items)
{ {
_articles.New(item); _articles.New(item);
_queue.New(new DiscordQueueEntity() _queue.New(new DiscordQueueModel
{ {
ArticleId = item.Id ArticleID = item.ID
}); });
} }
} }
public IEnumerable<ArticlesEntity> CheckForReleases(SourceEntity source) public IEnumerable<ArticlesModel> CheckForReleases(SourceModel source)
{ {
var url = new Uri(source.Url); var url = new Uri(source.Url);
var links = new List<string> var links = new List<string>
@ -111,10 +110,10 @@ public class CodeProjectWatcherJob
url.AbsoluteUri); url.AbsoluteUri);
} }
return new List<ArticlesEntity>(); return new List<ArticlesModel>();
} }
public IEnumerable<ArticlesEntity> CheckForCommits(SourceEntity source) public IEnumerable<ArticlesModel> CheckForCommits(SourceModel source)
{ {
var url = new Uri(source.Url); var url = new Uri(source.Url);
var links = new List<string> var links = new List<string>
@ -137,19 +136,19 @@ public class CodeProjectWatcherJob
url.AbsoluteUri); url.AbsoluteUri);
} }
return new List<ArticlesEntity>(); return new List<ArticlesModel>();
} }
private IEnumerable<ArticlesEntity> ProcessFeed(IEnumerable<SyndicationItem> feed, SourceEntity source, private IEnumerable<ArticlesModel> ProcessFeed(IEnumerable<SyndicationItem> feed, SourceModel source,
bool isRelease, bool isCommit) bool isRelease, bool isCommit)
{ {
var items = new List<ArticlesEntity>(); var items = new List<ArticlesModel>();
foreach (var item in feed) foreach (var item in feed)
{ {
var itemUrl = item.Links[0].Uri.AbsoluteUri; var itemUrl = item.Links[0].Uri.AbsoluteUri;
var exits = _articles.GetByUrl(itemUrl); var exits = _articles.GetByUrl(itemUrl);
if (exits.Id != Guid.Empty) continue; if (exits.ID != Guid.Empty) continue;
var parser = new HtmlPageReader(new HtmlPageReaderOptions var parser = new HtmlPageReader(new HtmlPageReaderOptions
{ {
@ -157,12 +156,12 @@ public class CodeProjectWatcherJob
}); });
parser.Parse(); parser.Parse();
var a = new ArticlesEntity var a = new ArticlesModel
{ {
SourceId = source.Id, SourceID = source.ID,
Tags = source.Tags, Tags = source.Tags,
Title = item.Title.Text, Title = item.Title.Text,
Url = itemUrl, URL = itemUrl,
PubDate = item.LastUpdatedTime.DateTime, PubDate = item.LastUpdatedTime.DateTime,
Thumbnail = parser.Data.Header.Image, Thumbnail = parser.Data.Header.Image,
Description = item.Title.Text, Description = item.Title.Text,

View File

@ -1,5 +1,4 @@
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Services.Notifications.Discord; using Newsbot.Collector.Services.Notifications.Discord;
@ -84,44 +83,45 @@ public class DiscordNotificationJob
_logger.Information($"{JobName} - Loop has been completed."); _logger.Information($"{JobName} - Loop has been completed.");
} }
public void ProcessQueueItem(DiscordQueueEntity request) public void ProcessQueueItem(DiscordQueueModel request)
{ {
_logger.Debug($"{JobName} - Processing {request.Id}"); _logger.Debug($"{JobName} - Processing {request.ID}");
// Get all details on the article in the queue // Get all details on the article in the queue
var articleDetails = _article.GetById(request.ArticleId); var articleDetails = _article.GetById(request.ArticleID);
// Get the details of the source // Get the details of the source
var sourceDetails = _sources.GetById(articleDetails.SourceId); var sourceDetails = _sources.GetByID(articleDetails.SourceID);
if (sourceDetails.Id == Guid.Empty) if (sourceDetails.ID == Guid.Empty)
{ {
_logger.Error( _logger.Error(
$"{JobName} - Article ({articleDetails.Id}) was linked to a empty Source ID. Removing from the queue."); $"{JobName} - Article ({articleDetails.ID}) was linked to a empty Source ID. Removing from the queue.");
_queue.Delete(request.Id); _queue.Delete(request.ID);
return; return;
} }
var sourceIcon = new IconEntity(); var sourceIcon = new IconModel();
try try
{ {
sourceIcon = _icons.GetBySourceId(sourceDetails.Id); sourceIcon = _icons.GetBySourceId(sourceDetails.ID);
} }
catch catch
{ {
_logger.Warning("{JobName} - Source ID \'{SourceDetailsId}\' is missing an icon", JobName, _logger.Warning("{JobName} - Source ID \'{SourceDetailsId}\' is missing an icon", JobName,
sourceDetails.Id); sourceDetails.ID);
} }
// Find all the subscriptions for that source // Find all the subscriptions for that source
var allSubscriptions = _subs.ListBySourceId(sourceDetails.Id); var allSubscriptions = _subs.ListBySourceID(sourceDetails.ID);
foreach (var sub in allSubscriptions) foreach (var sub in allSubscriptions)
SendSubscriptionNotification(request.Id, articleDetails, sourceDetails, sourceIcon, sub); SendSubscriptionNotification(request.ID, articleDetails, sourceDetails, sourceIcon, sub);
_logger.Debug("{JobName} - Removing {RequestId} from the queue", JobName, request.Id); _logger.Debug("{JobName} - Removing {RequestId} from the queue", JobName, request.ID);
_queue.Delete(request.Id); _queue.Delete(request.ID);
} }
public void SendSubscriptionNotification(Guid requestId, ArticlesEntity articleDetails, SourceEntity sourceDetails, IconEntity sourceIcon, SubscriptionEntity sub) public void SendSubscriptionNotification(Guid requestId, ArticlesModel articleDetails, SourceModel sourceDetails,
IconModel sourceIcon, SubscriptionModel sub)
{ {
// Check if the subscription code flags // Check if the subscription code flags
// If the article is a code commit and the subscription does not want them, skip. // If the article is a code commit and the subscription does not want them, skip.
@ -131,7 +131,7 @@ public class DiscordNotificationJob
if (articleDetails.CodeIsRelease && !sub.CodeAllowReleases) throw new MessageTypeNotRequestedException("Message was a code release and was not requested by the subscription"); if (articleDetails.CodeIsRelease && !sub.CodeAllowReleases) throw new MessageTypeNotRequestedException("Message was a code release and was not requested by the subscription");
// find the discord webhooks we need to post to // find the discord webhooks we need to post to
var discordDetails = _webhook.GetById(sub.DiscordWebHookId); var discordDetails = _webhook.GetByID(sub.DiscordWebHookId);
if (discordDetails.Enabled == false) return; if (discordDetails.Enabled == false) return;
var client = new DiscordWebhookClient(discordDetails.Url); var client = new DiscordWebhookClient(discordDetails.Url);
@ -143,15 +143,15 @@ public class DiscordNotificationJob
{ {
_logger.Error("Failed to post message to Discord. {ErrorMessage}", e.Message); _logger.Error("Failed to post message to Discord. {ErrorMessage}", e.Message);
_logger.Debug("Queue Record: {RequestId}", requestId); _logger.Debug("Queue Record: {RequestId}", requestId);
_logger.Debug("Article: {ArticleDetailsId}", articleDetails.Id); _logger.Debug("Article: {ArticleDetailsId}", articleDetails.ID);
_logger.Debug("Source: {SourceDetailsId}", sourceDetails.Id); _logger.Debug("Source: {SourceDetailsId}", sourceDetails.ID);
_logger.Debug("Subscription: {SubId}", sub.Id); _logger.Debug("Subscription: {SubId}", sub.Id);
} }
Thread.Sleep(3000); Thread.Sleep(3000);
} }
public DiscordMessage GenerateDiscordMessage(SourceEntity source, ArticlesEntity article, IconEntity icon) public DiscordMessage GenerateDiscordMessage(SourceModel source, ArticlesModel article, IconModel icon)
{ {
var embed = new DiscordMessageEmbed var embed = new DiscordMessageEmbed
{ {
@ -172,13 +172,13 @@ public class DiscordNotificationJob
new() new()
{ {
Name = "Link", Name = "Link",
Value = article.Url, Value = article.URL,
Inline = false Inline = false
} }
} }
}; };
if (article.Url is not null && article.Url != "") embed.Url = article.Url; if (article.URL is not null && article.URL != "") embed.Url = article.URL;
if (article.Thumbnail != "") if (article.Thumbnail != "")
embed.Image = new DiscordMessageEmbedImage embed.Image = new DiscordMessageEmbedImage

View File

@ -2,7 +2,6 @@ using System.ServiceModel.Syndication;
using System.Xml; using System.Xml;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Domain.Models.Config; using Newsbot.Collector.Domain.Models.Config;
@ -57,17 +56,17 @@ public class RssWatcherJob
public void Execute() public void Execute()
{ {
var articles = new List<ArticlesEntity>(); var articles = new List<ArticlesModel>();
_logger.Information($"{JobName} - Requesting sources"); _logger.Information($"{JobName} - Requesting sources");
var sources = _source.ListByType(SourceTypes.Rss, 0, 100); var sources = _source.ListByType(SourceTypes.Rss);
_logger.Information("{JobName} - Got {SourcesCount} back", JobName, sources.Count); _logger.Information($"{JobName} - Got {sources.Count} back");
foreach (var source in sources) foreach (var source in sources)
{ {
_logger.Information("{JobName} - Starting to process \'{SourceName}\'", JobName, source.Name); _logger.Information($"{JobName} - Starting to process '{source.Name}'");
_logger.Information($"{JobName} - Starting to request feed to be processed"); _logger.Information($"{JobName} - Starting to request feed to be processed");
var results = Collect(source.Url, source.Id); var results = Collect(source.Url, source.ID);
_logger.Information($"{JobName} - Collected {results.Count} posts"); _logger.Information($"{JobName} - Collected {results.Count} posts");
articles.AddRange(results); articles.AddRange(results);
@ -79,9 +78,9 @@ public class RssWatcherJob
_logger.Information($"{JobName} - Done!"); _logger.Information($"{JobName} - Done!");
} }
public List<ArticlesEntity> Collect(string url, Guid sourceId, int sleep = 3000) public List<ArticlesModel> Collect(string url, Guid sourceId, int sleep = 3000)
{ {
var collectedPosts = new List<ArticlesEntity>(); var collectedPosts = new List<ArticlesModel>();
using var reader = XmlReader.Create(url); using var reader = XmlReader.Create(url);
var feed = SyndicationFeed.Load(reader); var feed = SyndicationFeed.Load(reader);
@ -100,15 +99,15 @@ public class RssWatcherJob
}); });
meta.Parse(); meta.Parse();
var article = new ArticlesEntity var article = new ArticlesModel
{ {
Title = post.Title.Text, Title = post.Title.Text,
Tags = FetchTags(post), Tags = FetchTags(post),
Url = articleUrl, URL = articleUrl,
PubDate = post.PublishDate.DateTime, PubDate = post.PublishDate.DateTime,
Thumbnail = meta.Data.Header.Image, Thumbnail = meta.Data.Header.Image,
Description = meta.Data.Header.Description, Description = meta.Data.Header.Description,
SourceId = sourceId SourceID = sourceId
}; };
collectedPosts.Add(article); collectedPosts.Add(article);
@ -120,20 +119,20 @@ public class RssWatcherJob
return collectedPosts; return collectedPosts;
} }
public void UpdateDatabase(List<ArticlesEntity> items) public void UpdateDatabase(List<ArticlesModel> items)
{ {
foreach (var item in items) foreach (var item in items)
{ {
if (item.Url is null) if (item.URL is null)
{ {
Log.Warning("RSS Watcher collected a blank url and was skipped"); Log.Warning("RSS Watcher collected a blank url and was skipped.");
continue; continue;
} }
var p = _articles.New(item); var p = _articles.New(item);
_queue.New(new DiscordQueueEntity _queue.New(new DiscordQueueModel
{ {
ArticleId = p.Id ArticleID = p.ID
}); });
} }
} }
@ -141,7 +140,7 @@ public class RssWatcherJob
private bool IsThisUrlKnown(string url) private bool IsThisUrlKnown(string url)
{ {
var isKnown = _articles.GetByUrl(url); var isKnown = _articles.GetByUrl(url);
if (isKnown.Url == url) return true; if (isKnown.URL == url) return true;
return false; return false;
} }

View File

@ -2,7 +2,6 @@ using System.ServiceModel.Syndication;
using System.Xml; using System.Xml;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Interfaces;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Services.HtmlParser; using Newsbot.Collector.Services.HtmlParser;
@ -67,11 +66,11 @@ public class YoutubeWatcherJob
if (channelId == "") if (channelId == "")
{ {
channelId = GetChannelId(source.Url); channelId = GetChannelId(source.Url);
_source.UpdateYoutubeId(source.Id, channelId); _source.UpdateYoutubeId(source.ID, channelId);
} }
// Make sure we have a Icon for the channel // Make sure we have a Icon for the channel
var icon = _icons.GetBySourceId(source.Id); var icon = _icons.GetBySourceId(source.ID);
if (icon.Id == Guid.Empty) Console.WriteLine("I was triggered :V"); if (icon.Id == Guid.Empty) Console.WriteLine("I was triggered :V");
_logger.Information($"{JobName} - Checking '{source.Name}'"); _logger.Information($"{JobName} - Checking '{source.Name}'");
@ -83,9 +82,9 @@ public class YoutubeWatcherJob
{ {
_logger.Debug($"{JobName} - {video.AuthorName} '{video.Title}' was found"); _logger.Debug($"{JobName} - {video.AuthorName} '{video.Title}' was found");
_articles.New(video); _articles.New(video);
_queue.New(new DiscordQueueEntity _queue.New(new DiscordQueueModel
{ {
ArticleId = video.Id ArticleID = video.ID
}); });
} }
} }
@ -110,9 +109,9 @@ public class YoutubeWatcherJob
return id; return id;
} }
private List<ArticlesEntity> CheckFeed(string url, SourceEntity source) private List<ArticlesModel> CheckFeed(string url, SourceModel source)
{ {
var videos = new List<ArticlesEntity>(); var videos = new List<ArticlesModel>();
using var reader = XmlReader.Create(url); using var reader = XmlReader.Create(url);
var feed = SyndicationFeed.Load(reader); var feed = SyndicationFeed.Load(reader);
@ -127,17 +126,17 @@ public class YoutubeWatcherJob
}); });
videoDetails.Parse(); videoDetails.Parse();
var article = new ArticlesEntity var article = new ArticlesModel
{ {
//Todo add the icon //Todo add the icon
AuthorName = post.Authors[0].Name, AuthorName = post.Authors[0].Name,
Title = post.Title.Text, Title = post.Title.Text,
Tags = FetchTags(post), Tags = FetchTags(post),
Url = articleUrl, URL = articleUrl,
PubDate = post.PublishDate.DateTime, PubDate = post.PublishDate.DateTime,
Thumbnail = videoDetails.Data.Header.Image, Thumbnail = videoDetails.Data.Header.Image,
Description = videoDetails.Data.Header.Description, Description = videoDetails.Data.Header.Description,
SourceId = source.Id, SourceID = source.ID,
Video = "true" Video = "true"
}; };
@ -152,7 +151,7 @@ public class YoutubeWatcherJob
private bool IsThisUrlKnown(string url) private bool IsThisUrlKnown(string url)
{ {
var isKnown = _articles.GetByUrl(url); var isKnown = _articles.GetByUrl(url);
if (isKnown.Url == url) return true; if (isKnown.URL == url) return true;
return false; return false;
} }

View File

@ -7,10 +7,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Selenium.WebDriver" Version="4.8.1" /> <PackageReference Include="Selenium.WebDriver" Version="4.8.1" />
<PackageReference Include="Selenium.WebDriver.GeckoDriver" Version="0.32.2" /> <PackageReference Include="Selenium.WebDriver.GeckoDriver" Version="0.32.2" />
<PackageReference Include="Serilog" Version="2.12.0" /> <PackageReference Include="Serilog" Version="2.12.0" />

View File

@ -1,6 +1,5 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Domain.Consts; using Newsbot.Collector.Domain.Consts;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Domain.Models.Config; using Newsbot.Collector.Domain.Models.Config;
using Newsbot.Collector.Services.Jobs; using Newsbot.Collector.Services.Jobs;
@ -19,9 +18,9 @@ public class CodeProjectWatcherJobTests
FeaturePullCommits = true, FeaturePullCommits = true,
FeaturePullReleases = true FeaturePullReleases = true
}); });
var results = client.CheckForReleases(new SourceEntity var results = client.CheckForReleases(new SourceModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
Url = "https://github.com/jtom38/dvb", Url = "https://github.com/jtom38/dvb",
Type = SourceTypes.CodeProject, Type = SourceTypes.CodeProject,
Site = SourceTypes.CodeProject, Site = SourceTypes.CodeProject,
@ -45,9 +44,9 @@ public class CodeProjectWatcherJobTests
FeaturePullCommits = true, FeaturePullCommits = true,
FeaturePullReleases = true FeaturePullReleases = true
}); });
var results = client.CheckForReleases(new SourceEntity var results = client.CheckForReleases(new SourceModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
Url = "https://github.com/python/cpython", Url = "https://github.com/python/cpython",
Type = SourceTypes.CodeProject, Type = SourceTypes.CodeProject,
Site = SourceTypes.CodeProject, Site = SourceTypes.CodeProject,
@ -71,9 +70,9 @@ public class CodeProjectWatcherJobTests
FeaturePullCommits = true, FeaturePullCommits = true,
FeaturePullReleases = true FeaturePullReleases = true
}); });
var results = client.CheckForCommits(new SourceEntity var results = client.CheckForCommits(new SourceModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
Url = "https://github.com/jtom38/dvb", Url = "https://github.com/jtom38/dvb",
Type = SourceTypes.CodeProject, Type = SourceTypes.CodeProject,
Site = SourceTypes.CodeProject, Site = SourceTypes.CodeProject,

View File

@ -1,4 +1,4 @@
using Newsbot.Collector.Domain.Entities; using Newsbot.Collector.Domain.Models;
using Newsbot.Collector.Services.Jobs; using Newsbot.Collector.Services.Jobs;
using Newsbot.Collector.Services.Notifications.Discord; using Newsbot.Collector.Services.Notifications.Discord;
@ -13,9 +13,9 @@ public class DiscordNotificationJobTest
var webhookClient = new DiscordWebhookClient(uri); var webhookClient = new DiscordWebhookClient(uri);
var client = new DiscordNotificationJob(); var client = new DiscordNotificationJob();
var msg = client.GenerateDiscordMessage(new SourceEntity var msg = client.GenerateDiscordMessage(new SourceModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
Site = "Unit Test", Site = "Unit Test",
Source = "placeholder", Source = "placeholder",
Type = "a", Type = "a",
@ -24,17 +24,17 @@ public class DiscordNotificationJobTest
Url = "https://github.com", Url = "https://github.com",
Tags = "Unit, Testing" Tags = "Unit, Testing"
}, },
new ArticlesEntity new ArticlesModel
{ {
Tags = "more,unit,testing", Tags = "more,unit,testing",
Title = "Nope not real", Title = "Nope not real",
Url = "https://github.com/jtom38", URL = "https://github.com/jtom38",
PubDate = DateTime.Now, PubDate = DateTime.Now,
Thumbnail = "https://cdn.arstechnica.net/wp-content/uploads/2023/03/GettyImages-944827400-800x534.jpg", Thumbnail = "https://cdn.arstechnica.net/wp-content/uploads/2023/03/GettyImages-944827400-800x534.jpg",
Description = "Please work", Description = "Please work",
AuthorName = "No one knows" AuthorName = "No one knows"
}, },
new IconEntity() new IconModel
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
FileName = "https://www.redditstatic.com/desktop2x/img/favicon/android-icon-192x192.png" FileName = "https://www.redditstatic.com/desktop2x/img/favicon/android-icon-192x192.png"
@ -50,11 +50,11 @@ public class DiscordNotificationJobTest
{ {
client.SendSubscriptionNotification( client.SendSubscriptionNotification(
new Guid(), new Guid(),
new ArticlesEntity new ArticlesModel
{ {
Tags = "more,unit,testing", Tags = "more,unit,testing",
Title = "Nope not real", Title = "Nope not real",
Url = "https://github.com/jtom38", URL = "https://github.com/jtom38",
PubDate = DateTime.Now, PubDate = DateTime.Now,
Thumbnail = Thumbnail =
"https://cdn.arstechnica.net/wp-content/uploads/2023/03/GettyImages-944827400-800x534.jpg", "https://cdn.arstechnica.net/wp-content/uploads/2023/03/GettyImages-944827400-800x534.jpg",
@ -62,9 +62,9 @@ public class DiscordNotificationJobTest
AuthorName = "No one knows", AuthorName = "No one knows",
CodeIsCommit = true CodeIsCommit = true
}, },
new SourceEntity new SourceModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
Site = "Unit Test", Site = "Unit Test",
Source = "placeholder", Source = "placeholder",
Type = "a", Type = "a",
@ -73,12 +73,12 @@ public class DiscordNotificationJobTest
Url = "https://github.com", Url = "https://github.com",
Tags = "Unit, Testing" Tags = "Unit, Testing"
}, },
new IconEntity() new IconModel
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
FileName = "https://www.redditstatic.com/desktop2x/img/favicon/android-icon-192x192.png" FileName = "https://www.redditstatic.com/desktop2x/img/favicon/android-icon-192x192.png"
}, },
new SubscriptionEntity new SubscriptionModel
{ {
CodeAllowCommits = false, CodeAllowCommits = false,
CodeAllowReleases = true CodeAllowReleases = true
@ -87,7 +87,6 @@ public class DiscordNotificationJobTest
} }
catch (MessageTypeNotRequestedException) catch (MessageTypeNotRequestedException)
{ {
Console.Write($"Message did not send as expected"); Console.Write($"Message did not send as expected");
} }

View File

@ -61,7 +61,7 @@ public class RssWatcherJobTest
[Fact] [Fact]
public void CanReadHtmlDrivenFeedPage() public void CanReadHtmlDrivenFeedPage()
{ {
//var url = "https://www.howtogeek.com/feed/"; var url = "https://www.howtogeek.com/feed/";
var client = new RssWatcherJob(); var client = new RssWatcherJob();
client.InitAndExecute(new RssWatcherJobOptions client.InitAndExecute(new RssWatcherJobOptions
{ {

View File

@ -9,10 +9,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" /> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />

View File

@ -1,6 +1,5 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Tests.Tables; namespace Newsbot.Collector.Tests.Tables;
@ -24,7 +23,7 @@ public class ArticlesTableTests
{ {
var cfg = GetConfiguration(); var cfg = GetConfiguration();
var client = new ArticlesTable(cfg); var client = new ArticlesTable(cfg);
client.List(0, 25); client.List();
} }
[Fact] [Fact]
@ -35,7 +34,7 @@ public class ArticlesTableTests
var cfg = GetConfiguration(); var cfg = GetConfiguration();
var client = new ArticlesTable(cfg); var client = new ArticlesTable(cfg);
var res = client.GetById(uid); var res = client.GetById(uid);
if (!res.Id.Equals(uid)) if (!res.ID.Equals(uid))
{ {
Assert.Fail("Incorrect record or not found"); Assert.Fail("Incorrect record or not found");
} }
@ -46,14 +45,14 @@ public class ArticlesTableTests
{ {
var cfg = GetConfiguration(); var cfg = GetConfiguration();
var client = new ArticlesTable(cfg); var client = new ArticlesTable(cfg);
var m = new ArticlesEntity var m = new ArticlesModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
SourceId = Guid.NewGuid(), SourceID = Guid.NewGuid(),
Tags = "thing, thing2", Tags = "thing, thing2",
Title = "Unit Testing!", Title = "Unit Testing!",
Url = "https://google.com", URL = "https://google.com",
PubDate = DateTime.Now.ToUniversalTime(), PubDate = DateTime.Now.ToLocalTime(),
}; };
client.New(m); client.New(m);
} }

View File

@ -1,5 +1,4 @@
using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Database.Repositories;
using Newsbot.Collector.Domain.Entities;
using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models;
namespace Newsbot.Collector.Tests.Tables; namespace Newsbot.Collector.Tests.Tables;
@ -10,9 +9,9 @@ public class SourcesTableTests
public void NewRecordTest() public void NewRecordTest()
{ {
var client = new SourcesTable(""); var client = new SourcesTable("");
var m = new SourceEntity var m = new SourceModel
{ {
Id = Guid.NewGuid(), ID = Guid.NewGuid(),
Site = "Testing", Site = "Testing",
Name = "Testing", Name = "Testing",
Source = "Testing", Source = "Testing",

View File

@ -1,26 +1,2 @@
# Newsbot.Collector # Newsbot.Collector
C# API Server to collect news from around the world
C# API Server to collect news from around the world.
## Features
- YouTube
- Github
- Should support other source control services but untested
- RSS
## Notifications
- Discord Webhooks
## Legacy Features No longer support
- Twitter
- API Changes
- Reddit
- API Changes
- Could come back as long as the json dump is still available
- Instagram
- No plans to attempt to get this working again.

View File

@ -1,18 +0,0 @@
# docker compose -f docker-compose.dev.yaml up -d
version: "3"
volumes:
db:
services:
db:
image: postgres:latest
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- "5432:5432"
volumes:
- db:/var/lib/postgresql/data

View File

@ -10,7 +10,7 @@ services:
db: db:
image: postgres:latest image: postgres:latest
environment: environment:
POSTGRES_USER: ${PostgresUser}] POSTGRES_USER: ${PostgresUser}
POSTGRES_PASSWORD: ${PostgresPassword} POSTGRES_PASSWORD: ${PostgresPassword}
POSTGRES_DB: ${PostgresDatabaseName} POSTGRES_DB: ${PostgresDatabaseName}
ports: ports:
@ -25,6 +25,12 @@ services:
timeout: "30s" timeout: "30s"
retries: 5 retries: 5
adminer:
image: adminer
restart: always
ports:
- "8080:8080"
api: api:
image: newsbot.collector:latest image: newsbot.collector:latest
environment: environment:

View File

@ -21,9 +21,11 @@ docker-run: ## Runs the docker compose
docker-migrate: ## Runs the migrations stored in the Docker image docker-migrate: ## Runs the migrations stored in the Docker image
docker run -it --env-file .env ghcr.io/jtom38/newsbot.collector:master /app/goose --dir "/app/migrations" up docker run -it --env-file .env ghcr.io/jtom38/newsbot.collector:master /app/goose --dir "/app/migrations" up
ef-build: ## Builds migration artifact migrate-dev: ## Apply sql migrations to dev db
dotnet ef migrations bundle --project "Newsbot.Collector.Database" --force goose -dir "./Newsbot.Collector.Database/Migrations" postgres "host=localhost user=postgres password=postgres dbname=postgres sslmode=disable" up
ef-migrate: ## Runs migrations based on the newest artifact migrate-dev-down: ## revert sql migrations to dev db
dotnet ef migrations bundle --project "Newsbot.Collector.Database" --force goose -dir "./Newsbot.Collector.Database/Migrations" postgres "host=localhost user=postgres password=postgres dbname=postgres sslmode=disable" down
./efbundle --connection "Host=localhost;Username=postgres;Password=postgres;Database=postgres;sslmode=disable"
migrate-refresh: ## Rolls back all migrations
goose -dir "./Newsbot.Collector.Database/Migrations" postgres "host=localhost user=postgres password=postgres dbname=postgres sslmode=disable" reset