Skip to content

Commit

Permalink
Major updates to Artist Alley table registration service
Browse files Browse the repository at this point in the history
  • Loading branch information
Pinselohrkater committed May 14, 2019
1 parent ddfe84d commit 3513e09
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,57 @@
using Eurofurence.App.Domain.Model.Fragments;
using System;
using System.Collections.Generic;

namespace Eurofurence.App.Domain.Model.ArtistsAlley
{
public class TableRegistrationRecord : EntityBase
{
public class StateChangeRecord
{
public DateTime ChangedDateTimeUtc{ get; set; }
public string ChangedByUid { get; set; }
public RegistrationStateEnum OldState { get; set; }
public RegistrationStateEnum NewState { get; set; }
}

public enum RegistrationStateEnum
{
Pending = 0,
Accepted = 1,
Published = 2,
Rejected = 3
}

public string OwnerUid { get; set; }

public string DisplayName { get; set; }

public string Merchandise { get; set; }
public string WebsiteUrl { get; set; }

public string ShortDescription { get; set; }

public ImageFragment Image { get; set; }

public RegistrationStateEnum State { get; set; }

public IList<StateChangeRecord> StateChangeLog { get; set; }

public TableRegistrationRecord()
{
this.StateChangeLog = new List<StateChangeRecord>();
}

public void ChangeState(RegistrationStateEnum newState, string uid)
{
StateChangeLog.Add(new StateChangeRecord()
{
ChangedByUid = uid,
ChangedDateTimeUtc = DateTime.UtcNow,
NewState = newState,
OldState = State
});

State = newState;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Eurofurence.App.Domain.Model.ArtistsAlley;

namespace Eurofurence.App.Server.Services.Abstractions.ArtistsAlley
{
public interface ITableRegistrationService
{
Task RegisterTableAsync(string uid, TableRegistrationRequest request);
Task<IEnumerable<TableRegistrationRecord>> GetRegistrations(TableRegistrationRecord.RegistrationStateEnum? state);

Task ApproveByIdAsync(Guid id, string operatorUid);
Task RejectByIdAsync(Guid id, string operatorUid);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Eurofurence.App.Server.Services.Abstractions.ArtistsAlley
namespace Eurofurence.App.Server.Services.Abstractions.ArtistsAlley
{
public class TableRegistrationRequest
{
public string DisplayName { get; set; }

public string Merchandise { get; set; }
public string WebsiteUrl { get; set; }

public string ShortDescription { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ namespace Eurofurence.App.Server.Services.Abstractions.Telegram
public interface ITelegramMessageSender
{
Task SendMarkdownMessageToChatAsync(string chatId, string message);
Task SendImageToChatAsync(string chatId, byte[] imageBytes, string message = "");
}

public interface ITelegramMessageBroker : ITelegramMessageSender
{
event Func<string, string, Task> OnSendMarkdownMessageToChatAsync;
event Func<string, byte[], string, Task> OnSendImageToChatAsync;
}
}
Original file line number Diff line number Diff line change
@@ -1,43 +1,160 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Eurofurence.App.Common.ExtensionMethods;
using Eurofurence.App.Domain.Model.Abstractions;
using Eurofurence.App.Domain.Model.ArtistsAlley;
using Eurofurence.App.Domain.Model.Security;
using Eurofurence.App.Server.Services.Abstractions.ArtistsAlley;
using Eurofurence.App.Server.Services.Abstractions.Images;
using Eurofurence.App.Server.Services.Abstractions.Telegram;
using LinqToTwitter;

namespace Eurofurence.App.Server.Services.ArtistsAlley
{
public class TableRegistrationService : ITableRegistrationService
{
private readonly ArtistAlleyConfiguration _configuration;
private readonly IEntityRepository<TableRegistrationRecord> _tableRegistrationRepository;
private readonly ITelegramMessageSender _telegramMessageSender;
private readonly IImageService _imageService;
private readonly IEntityRepository<RegSysIdentityRecord> _regSysIdentityRepository;
private TwitterContext _twitterContext;

public TableRegistrationService(
ArtistAlleyConfiguration configuration,
IEntityRepository<TableRegistrationRecord> tableRegistrationRepository,
ITelegramMessageSender telegramMessageSender,
IEntityRepository<RegSysIdentityRecord> regSysIdentityRepository,
IImageService imageService)
{
_configuration = configuration;
_tableRegistrationRepository = tableRegistrationRepository;
_telegramMessageSender = telegramMessageSender;
_regSysIdentityRepository = regSysIdentityRepository;
_imageService = imageService;

var auth = new SingleUserAuthorizer
{
CredentialStore = new SingleUserInMemoryCredentialStore
{
ConsumerKey = _configuration.TwitterConsumerKey,
ConsumerSecret = _configuration.TwitterConsumerSecret,
AccessToken = _configuration.TwitterAccessToken,
AccessTokenSecret = _configuration.TwitterAccessTokenSecret
}
};
_twitterContext = new TwitterContext(auth);
}

public async Task<IEnumerable<TableRegistrationRecord>> GetRegistrations(TableRegistrationRecord.RegistrationStateEnum? state)
{
var records = await _tableRegistrationRepository.FindAllAsync(a => !state.HasValue || a.State == state.Value);
return records;
}

public async Task RegisterTableAsync(string uid, TableRegistrationRequest request)
{
var identity = await _regSysIdentityRepository.FindOneAsync(a => a.Uid == uid);

byte[] imageBytes = Convert.FromBase64String(request.ImageContent);
var imageFragment = _imageService.GenerateFragmentFromBytes(imageBytes);

imageFragment = _imageService.EnforceMaximumDimensions(imageFragment, 1500, 1500);

var record = new TableRegistrationRecord()
{
OwnerUid = uid,
DisplayName = request.DisplayName,
Merchandise = request.Merchandise,
WebsiteUrl = request.WebsiteUrl,
ShortDescription = request.ShortDescription,
Image = imageFragment
Image = imageFragment,
State = TableRegistrationRecord.RegistrationStateEnum.Pending
};

record.NewId();
record.Touch();

await _tableRegistrationRepository.InsertOneAsync(record);
await _telegramMessageSender.SendMarkdownMessageToChatAsync(
_configuration.TelegramAdminGroupChatId,
$"*New Table Registration Request:*\n\nFrom: *{identity.Username.RemoveMarkdown()} ({uid})*\n\nDisplay Name: *{record.DisplayName.RemoveMarkdown()}*\n_{record.ShortDescription.RemoveMarkdown()}_");
}

public async Task ApproveByIdAsync(Guid id, string operatorUid)
{
var record = await _tableRegistrationRepository.FindOneAsync(a => a.Id == id
&& a.State == TableRegistrationRecord.RegistrationStateEnum.Pending);
var identity = await _regSysIdentityRepository.FindOneAsync(a => a.Uid == record.OwnerUid);

record.ChangeState(TableRegistrationRecord.RegistrationStateEnum.Accepted, operatorUid);
record.Touch();

await _tableRegistrationRepository.ReplaceOneAsync(record);

await _telegramMessageSender.SendMarkdownMessageToChatAsync(
_configuration.TelegramAdminGroupChatId,
$"*Approved:* {identity.Username} ({record.OwnerUid} / {record.Id})\n\nRegistration has been approved by *{operatorUid}* and will be published on Twitter/Telegram.");



await BroadcastAsync(record);
// Todo: Send a message to user.
}

private async Task BroadcastAsync(TableRegistrationRecord record)
{
var messageBuilder = new StringBuilder();
messageBuilder.Append($"Now in the Artist Alley:\n\n*{record.DisplayName.RemoveMarkdown()}*\n\n");
messageBuilder.Append($"_{record.ShortDescription.RemoveMarkdown()}_");
if (record.WebsiteUrl != null)
{
messageBuilder.Append("\n\n");
messageBuilder.Append(record.WebsiteUrl);
}

var message = messageBuilder.ToString();

if (record.Image != null)
{
await _telegramMessageSender.SendImageToChatAsync(
_configuration.TelegramAnnouncementChannelId,
record.Image.ImageBytes,
message);

var media = await _twitterContext.UploadMediaAsync(
record.Image.ImageBytes,
record.Image.MimeType,
"tweet_image");

await _twitterContext.TweetAsync(message.RemoveMarkdown(), new ulong[] { media.MediaID });
}
else
{
await _telegramMessageSender.SendMarkdownMessageToChatAsync(
_configuration.TelegramAnnouncementChannelId,
message);

await _twitterContext.TweetAsync(message.RemoveMarkdown());
}
}

public async Task RejectByIdAsync(Guid id, string operatorUid)
{
var record = await _tableRegistrationRepository.FindOneAsync(a => a.Id == id
&& a.State == TableRegistrationRecord.RegistrationStateEnum.Pending);
var identity = await _regSysIdentityRepository.FindOneAsync(a => a.Uid == record.OwnerUid);

record.ChangeState(TableRegistrationRecord.RegistrationStateEnum.Rejected, operatorUid);
record.Touch();

await _tableRegistrationRepository.ReplaceOneAsync(record);

await _telegramMessageSender.SendMarkdownMessageToChatAsync(_configuration.TelegramAdminGroupChatId,
$"*Rejected:* {identity.Username} ({record.OwnerUid} / {record.Id})\n\nRegistration has been rejected by *{operatorUid}*. Reason given: ...");

// Todo: Send a message to user.
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
<ItemGroup>
<PackageReference Include="Autofac" Version="4.8.0" />
<PackageReference Include="CsvHelper" Version="7.1.0" />
<PackageReference Include="linqtotwitter" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.2.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0005" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0005" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.2.2" />
<PackageReference Include="Telegram.Bot" Version="13.4.0" />
<PackageReference Include="Telegram.Bot" Version="14.11.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
Expand Down
Loading

0 comments on commit 3513e09

Please sign in to comment.