added deletion workflow
This commit is contained in:
parent
4fb04c16b8
commit
6f8a2c0373
15 changed files with 239 additions and 54 deletions
|
@ -15,4 +15,8 @@
|
|||
<ProjectReference Include="..\DataAccessLayers\BirdsiteLive.DAL\BirdsiteLive.DAL.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Enum\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
9
src/BirdsiteLive.Domain/Enum/MigrationTypeEnum.cs
Normal file
9
src/BirdsiteLive.Domain/Enum/MigrationTypeEnum.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace BirdsiteLive.Domain.Enum
|
||||
{
|
||||
public enum MigrationTypeEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Migration = 1,
|
||||
Deletion = 2
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ using BirdsiteLive.ActivityPub.Models;
|
|||
using BirdsiteLive.DAL.Contracts;
|
||||
using BirdsiteLive.ActivityPub.Converters;
|
||||
using BirdsiteLive.Common.Settings;
|
||||
using BirdsiteLive.DAL.Models;
|
||||
using BirdsiteLive.Domain.Enum;
|
||||
|
||||
namespace BirdsiteLive.Domain
|
||||
{
|
||||
|
@ -37,9 +39,21 @@ namespace BirdsiteLive.Domain
|
|||
return $"[[BirdsiteLIVE-MigrationCode|{hash.Substring(0, 10)}]]";
|
||||
}
|
||||
|
||||
public bool ValidateTweet(string acct, string tweetId)
|
||||
public string GetDeletionCode(string acct)
|
||||
{
|
||||
var code = GetMigrationCode(acct);
|
||||
var hash = GetHashString(acct);
|
||||
return $"[[BirdsiteLIVE-DeletionCode|{hash.Substring(0, 10)}]]";
|
||||
}
|
||||
|
||||
public bool ValidateTweet(string acct, string tweetId, MigrationTypeEnum type)
|
||||
{
|
||||
string code;
|
||||
if (type == MigrationTypeEnum.Migration)
|
||||
code = GetMigrationCode(acct);
|
||||
else if (type == MigrationTypeEnum.Deletion)
|
||||
code = GetDeletionCode(acct);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
|
||||
var castedTweetId = ExtractedTweetId(tweetId);
|
||||
var tweet = _twitterTweetsService.GetTweet(castedTweetId);
|
||||
|
@ -47,10 +61,10 @@ namespace BirdsiteLive.Domain
|
|||
if (tweet == null)
|
||||
throw new Exception("Tweet not found");
|
||||
|
||||
if (tweet.CreatorName.Trim().ToLowerInvariant() != acct.Trim().ToLowerInvariant())
|
||||
if (tweet.CreatorName.Trim().ToLowerInvariant() != acct.Trim().ToLowerInvariant())
|
||||
throw new Exception($"Tweet not published by @{acct}");
|
||||
|
||||
if (!tweet.MessageContent.Contains(code))
|
||||
if (!tweet.MessageContent.Contains(code))
|
||||
throw new Exception("Tweet don't have migration code");
|
||||
|
||||
return true;
|
||||
|
@ -74,7 +88,7 @@ namespace BirdsiteLive.Domain
|
|||
if (string.IsNullOrWhiteSpace(fediverseAcct))
|
||||
throw new ArgumentException("Please provide Fediverse account");
|
||||
|
||||
if( !fediverseAcct.Contains('@') || !fediverseAcct.StartsWith("@") || fediverseAcct.Trim('@').Split('@').Length != 2)
|
||||
if (!fediverseAcct.Contains('@') || !fediverseAcct.StartsWith("@") || fediverseAcct.Trim('@').Split('@').Length != 2)
|
||||
throw new ArgumentException("Please provide valid Fediverse handle");
|
||||
|
||||
var objectId = await _activityPubService.GetUserIdAsync(fediverseAcct);
|
||||
|
@ -98,15 +112,23 @@ namespace BirdsiteLive.Domain
|
|||
if (twitterAccount == null)
|
||||
{
|
||||
await _twitterUserDal.CreateTwitterUserAsync(acct, -1, validatedUser.ObjectId, validatedUser.FediverseAcct);
|
||||
}
|
||||
else
|
||||
{
|
||||
twitterAccount.MovedTo = validatedUser.ObjectId;
|
||||
twitterAccount.MovedToAcct = validatedUser.FediverseAcct;
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(twitterAccount);
|
||||
twitterAccount = await _twitterUserDal.GetTwitterUserAsync(acct);
|
||||
}
|
||||
|
||||
twitterAccount.MovedTo = validatedUser.ObjectId;
|
||||
twitterAccount.MovedToAcct = validatedUser.FediverseAcct;
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(twitterAccount);
|
||||
|
||||
// Notify Followers
|
||||
var message = $@"<p>[BSL MIRROR SERVICE NOTIFICATION]<br/>
|
||||
This bot has been disabled by it's original owner.<br/>
|
||||
It has been redirected to {validatedUser.FediverseAcct}.
|
||||
</p>";
|
||||
NotifyFollowers(acct, twitterAccount, message);
|
||||
}
|
||||
|
||||
private void NotifyFollowers(string acct, SyncTwitterUser twitterAccount, string message)
|
||||
{
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
var followers = await _followersDal.GetFollowersAsync(twitterAccount.Id);
|
||||
|
@ -118,7 +140,8 @@ namespace BirdsiteLive.Domain
|
|||
var actorUrl = UrlFactory.GetActorUrl(_instanceSettings.Domain, acct);
|
||||
var noteUrl = UrlFactory.GetNoteUrl(_instanceSettings.Domain, acct, noteId);
|
||||
|
||||
var to = validatedUser.ObjectId;
|
||||
//var to = validatedUser.ObjectId;
|
||||
var to = follower.ActorId;
|
||||
var cc = new string[0];
|
||||
|
||||
var note = new Note
|
||||
|
@ -132,13 +155,11 @@ namespace BirdsiteLive.Domain
|
|||
to = new[] { to },
|
||||
cc = cc,
|
||||
|
||||
content = $@"<p>[MIRROR SERVICE NOTIFICATION]<br/>
|
||||
This bot has been disabled by it's original owner.<br/>
|
||||
It has been redirected to {validatedUser.FediverseAcct}.
|
||||
</p>"
|
||||
content = message
|
||||
};
|
||||
|
||||
await _activityPubService.PostNewNoteActivity(note, acct, Guid.NewGuid().ToString(), follower.Host, follower.InboxRoute);
|
||||
await _activityPubService.PostNewNoteActivity(note, acct, Guid.NewGuid().ToString(), follower.Host,
|
||||
follower.InboxRoute);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -148,11 +169,37 @@ namespace BirdsiteLive.Domain
|
|||
});
|
||||
}
|
||||
|
||||
public async Task DeleteAccountAsync(string acct)
|
||||
{
|
||||
// Apply moved to
|
||||
var twitterAccount = await _twitterUserDal.GetTwitterUserAsync(acct);
|
||||
if (twitterAccount == null)
|
||||
{
|
||||
await _twitterUserDal.CreateTwitterUserAsync(acct, -1);
|
||||
twitterAccount = await _twitterUserDal.GetTwitterUserAsync(acct);
|
||||
}
|
||||
|
||||
twitterAccount.Deleted = true;
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(twitterAccount);
|
||||
|
||||
|
||||
// Notify Followers
|
||||
var message = $@"<p>[BSL MIRROR SERVICE NOTIFICATION]<br/>
|
||||
This bot has been deleted by it's original owner.<br/>
|
||||
</p>";
|
||||
NotifyFollowers(acct, twitterAccount, message);
|
||||
}
|
||||
|
||||
public async Task TriggerRemoteMigrationAsync(string id, string tweetid, string handle)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
public async Task TriggerRemoteDeleteAsync(string id, string tweetid)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
private byte[] GetHash(string inputString)
|
||||
{
|
||||
using (HashAlgorithm algorithm = SHA256.Create())
|
||||
|
|
|
@ -49,12 +49,12 @@ namespace BirdsiteLive.Pipeline.Processors
|
|||
{
|
||||
var tweetId = tweets.Last().Id;
|
||||
var now = DateTime.UtcNow;
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(user.Id, tweetId, tweetId, user.FetchingErrorCount, now, user.MovedTo, user.MovedToAcct);
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(user.Id, tweetId, tweetId, user.FetchingErrorCount, now, user.MovedTo, user.MovedToAcct, user.Deleted);
|
||||
}
|
||||
else
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(user.Id, user.LastTweetPostedId, user.LastTweetSynchronizedForAllFollowersId, user.FetchingErrorCount, now, user.MovedTo, user.MovedToAcct);
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(user.Id, user.LastTweetPostedId, user.LastTweetSynchronizedForAllFollowersId, user.FetchingErrorCount, now, user.MovedTo, user.MovedToAcct, user.Deleted);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace BirdsiteLive.Pipeline.Processors
|
|||
var lastPostedTweet = userWithTweetsToSync.Tweets.Select(x => x.Id).Max();
|
||||
var minimumSync = followingSyncStatuses.Min();
|
||||
var now = DateTime.UtcNow;
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(userId, lastPostedTweet, minimumSync, userWithTweetsToSync.User.FetchingErrorCount, now, userWithTweetsToSync.User.MovedTo, userWithTweetsToSync.User.MovedToAcct);
|
||||
await _twitterUserDal.UpdateTwitterUserAsync(userId, lastPostedTweet, minimumSync, userWithTweetsToSync.User.FetchingErrorCount, now, userWithTweetsToSync.User.MovedTo, userWithTweetsToSync.User.MovedToAcct, userWithTweetsToSync.User.Deleted);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Npgsql.TypeHandlers;
|
||||
using BirdsiteLive.Domain;
|
||||
using BirdsiteLive.Domain.Enum;
|
||||
|
||||
namespace BirdsiteLive.Controllers
|
||||
{
|
||||
|
@ -20,8 +21,8 @@ namespace BirdsiteLive.Controllers
|
|||
#endregion
|
||||
|
||||
[HttpGet]
|
||||
[Route("/migration/{id}")]
|
||||
public IActionResult Index(string id)
|
||||
[Route("/migration/move/{id}")]
|
||||
public IActionResult IndexMove(string id)
|
||||
{
|
||||
var migrationCode = _migrationService.GetMigrationCode(id);
|
||||
var data = new MigrationData()
|
||||
|
@ -30,12 +31,26 @@ namespace BirdsiteLive.Controllers
|
|||
MigrationCode = migrationCode
|
||||
};
|
||||
|
||||
return View(data);
|
||||
return View("Index", data);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/migration/delete/{id}")]
|
||||
public IActionResult IndexDelete(string id)
|
||||
{
|
||||
var migrationCode = _migrationService.GetDeletionCode(id);
|
||||
var data = new MigrationData()
|
||||
{
|
||||
Acct = id,
|
||||
MigrationCode = migrationCode
|
||||
};
|
||||
|
||||
return View("Delete", data);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("/migration/{id}")]
|
||||
public async Task<IActionResult> Migrate(string id, string tweetid, string handle)
|
||||
[Route("/migration/move/{id}")]
|
||||
public async Task<IActionResult> MigrateMove(string id, string tweetid, string handle)
|
||||
{
|
||||
var migrationCode = _migrationService.GetMigrationCode(id);
|
||||
|
||||
|
@ -56,7 +71,7 @@ namespace BirdsiteLive.Controllers
|
|||
try
|
||||
{
|
||||
fediverseUserValidation = await _migrationService.ValidateFediverseAcctAsync(handle);
|
||||
var isTweetValid = _migrationService.ValidateTweet(id, tweetid);
|
||||
var isTweetValid = _migrationService.ValidateTweet(id, tweetid, MigrationTypeEnum.Migration);
|
||||
|
||||
data.IsAcctValid = fediverseUserValidation.IsValid;
|
||||
data.IsTweetValid = isTweetValid;
|
||||
|
@ -85,11 +100,55 @@ namespace BirdsiteLive.Controllers
|
|||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("/migration/{id}/{tweetid}/{handle}")]
|
||||
public async Task<IActionResult> RemoteMigrate(string id, string tweetid, string handle)
|
||||
[Route("/migration/delete/{id}")]
|
||||
public async Task<IActionResult> MigrateDelete(string id, string tweetid)
|
||||
{
|
||||
var migrationCode = _migrationService.GetMigrationCode(id);
|
||||
|
||||
var data = new MigrationData()
|
||||
{
|
||||
Acct = id,
|
||||
MigrationCode = migrationCode,
|
||||
|
||||
IsTweetProvided = !string.IsNullOrWhiteSpace(tweetid),
|
||||
|
||||
TweetId = tweetid
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var isTweetValid = _migrationService.ValidateTweet(id, tweetid, MigrationTypeEnum.Migration);
|
||||
data.IsTweetValid = isTweetValid;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
data.ErrorMessage = e.Message;
|
||||
}
|
||||
|
||||
if (data.IsTweetValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _migrationService.DeleteAccountAsync(id);
|
||||
await _migrationService.TriggerRemoteDeleteAsync(id, tweetid);
|
||||
data.MigrationSuccess = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
data.ErrorMessage = e.Message;
|
||||
}
|
||||
}
|
||||
|
||||
return View("Index", data);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("/migration/move/{id}/{tweetid}/{handle}")]
|
||||
public async Task<IActionResult> RemoteMigrateMove(string id, string tweetid, string handle)
|
||||
{
|
||||
var fediverseUserValidation = await _migrationService.ValidateFediverseAcctAsync(handle);
|
||||
var isTweetValid = _migrationService.ValidateTweet(id, tweetid);
|
||||
var isTweetValid = _migrationService.ValidateTweet(id, tweetid, MigrationTypeEnum.Deletion);
|
||||
|
||||
if (fediverseUserValidation.IsValid && isTweetValid)
|
||||
{
|
||||
|
@ -99,6 +158,13 @@ namespace BirdsiteLive.Controllers
|
|||
|
||||
return StatusCode(500);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("/migration/delete/{id}/{tweetid}/{handle}")]
|
||||
public async Task<IActionResult> RemoteDeleteMove(string id, string tweetid, string handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
44
src/BirdsiteLive/Views/Migration/Delete.cshtml
Normal file
44
src/BirdsiteLive/Views/Migration/Delete.cshtml
Normal file
|
@ -0,0 +1,44 @@
|
|||
@model BirdsiteLive.Controllers.MigrationData
|
||||
@{
|
||||
ViewData["Title"] = "Migration";
|
||||
}
|
||||
|
||||
<div class="col-12 col-sm-10 col-md-8 col-lg-6 mx-auto">
|
||||
@if (!string.IsNullOrWhiteSpace(ViewData.Model.ErrorMessage))
|
||||
{
|
||||
<div class="alert alert-danger" role="alert">
|
||||
@ViewData.Model.ErrorMessage
|
||||
</div>
|
||||
}
|
||||
|
||||
<h1 class="display-4 migration__title">Delete @@@ViewData.Model.Acct mirror</h1>
|
||||
|
||||
@if (!ViewData.Model.IsTweetProvided)
|
||||
{
|
||||
<h2 class="display-4 migration__subtitle">What is needed?</h2>
|
||||
|
||||
<p>You'll need access to the Twitter account to provide proof of ownership.</p>
|
||||
|
||||
<h2 class="display-4 migration__subtitle">What will deletion do?</h2>
|
||||
|
||||
<p>
|
||||
Deletion will remove all followers, delete the account and will be blacklisted so that it can't be recreated.<br />
|
||||
</p>
|
||||
}
|
||||
|
||||
<h2 class="display-4 migration__subtitle">Start the deletion!</h2>
|
||||
|
||||
<p>Please copy and post this string in a public Tweet (the string must be untampered, but you can write anything you want before or after it):</p>
|
||||
|
||||
<input type="text" name="textbox" value="@ViewData.Model.MigrationCode" onclick="this.select()" class="form-control" readonly />
|
||||
<br />
|
||||
|
||||
<h2 class="display-4 migration__subtitle">Provide deletion information:</h2>
|
||||
<form method="POST">
|
||||
<div class="form-group">
|
||||
<label for="tweetid">Tweet URL</label>
|
||||
<input type="text" class="form-control" id="tweetid" name="tweetid" autocomplete="off" placeholder="https://twitter.com/<username>/status/<tweet id>" value="@ViewData.Model.TweetId">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Delete!</button>
|
||||
</form>
|
||||
</div>
|
|
@ -11,7 +11,7 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
<h1 class="display-4 migration__title">Migrate @@@ViewData.Model.Acct</h1>
|
||||
<h1 class="display-4 migration__title">Migrate @@@ViewData.Model.Acct mirror to my Fediverse account</h1>
|
||||
|
||||
@if (!ViewData.Model.IsAcctProvided && !ViewData.Model.IsTweetProvided)
|
||||
{
|
||||
|
@ -21,16 +21,17 @@
|
|||
|
||||
<h2 class="display-4 migration__subtitle">What will migration do?</h2>
|
||||
|
||||
<p>Migration will transfer the followers to the provided account.<br/>
|
||||
After a week, the account will be deleted. It will also be blacklisted so that it can't be recreated.</p>
|
||||
<p>
|
||||
Migration will notify followers of the migration of the mirror account to your fediverse account and will be disabled after that.<br />
|
||||
</p>
|
||||
}
|
||||
|
||||
<h2 class="display-4 migration__subtitle">Start the migration!</h2>
|
||||
|
||||
<p>Please copy and post this string in a Tweet (the string must be untampered, but you can write anything you want before or after it):</p>
|
||||
<p>Please copy and post this string in a public Tweet (the string must be untampered, but you can write anything you want before or after it):</p>
|
||||
|
||||
<input type="text" name="textbox" value="@ViewData.Model.MigrationCode" onclick="this.select()" class="form-control" readonly/>
|
||||
<br/>
|
||||
<input type="text" name="textbox" value="@ViewData.Model.MigrationCode" onclick="this.select()" class="form-control" readonly />
|
||||
<br />
|
||||
|
||||
<h2 class="display-4 migration__subtitle">Provide migration information:</h2>
|
||||
<form method="POST">
|
||||
|
@ -49,4 +50,10 @@
|
|||
</div>
|
||||
<button type="submit" class="btn btn-primary">Migrate!</button>
|
||||
</form>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div class="user-owner">
|
||||
<a href="/migration/delete/@ViewData.Model.Acct">I don't have a fediverse account and I'd like to delete this mirror.</a>
|
||||
</div>
|
||||
</div>
|
|
@ -47,6 +47,6 @@
|
|||
}
|
||||
|
||||
<div class="user-owner">
|
||||
<a href="/migration/@ViewData.Model.Acct">I'm the owner of this account and I'm now on the Fediverse</a>
|
||||
<a href="/migration/move/@ViewData.Model.Acct">I'm the owner of this account and I would like to take control of this mirror.</a>
|
||||
</div>
|
||||
</div>
|
|
@ -119,14 +119,14 @@ namespace BirdsiteLive.DAL.Postgres.DataAccessLayers
|
|||
}
|
||||
}
|
||||
|
||||
public async Task UpdateTwitterUserAsync(int id, long lastTweetPostedId, long lastTweetSynchronizedForAllFollowersId, int fetchingErrorCount, DateTime lastSync, string movedTo, string movedToAcct)
|
||||
public async Task UpdateTwitterUserAsync(int id, long lastTweetPostedId, long lastTweetSynchronizedForAllFollowersId, int fetchingErrorCount, DateTime lastSync, string movedTo, string movedToAcct, bool deleted)
|
||||
{
|
||||
if(id == default) throw new ArgumentException("id");
|
||||
if(lastTweetPostedId == default) throw new ArgumentException("lastTweetPostedId");
|
||||
if(lastTweetSynchronizedForAllFollowersId == default) throw new ArgumentException("lastTweetSynchronizedForAllFollowersId");
|
||||
if(lastSync == default) throw new ArgumentException("lastSync");
|
||||
|
||||
var query = $"UPDATE {_settings.TwitterUserTableName} SET lastTweetPostedId = @lastTweetPostedId, lastTweetSynchronizedForAllFollowersId = @lastTweetSynchronizedForAllFollowersId, fetchingErrorCount = @fetchingErrorCount, lastSync = @lastSync, movedTo = @movedTo, movedToAcct = @movedToAcct WHERE id = @id";
|
||||
var query = $"UPDATE {_settings.TwitterUserTableName} SET lastTweetPostedId = @lastTweetPostedId, lastTweetSynchronizedForAllFollowersId = @lastTweetSynchronizedForAllFollowersId, fetchingErrorCount = @fetchingErrorCount, lastSync = @lastSync, movedTo = @movedTo, movedToAcct = @movedToAcct, deleted = @deleted WHERE id = @id";
|
||||
|
||||
using (var dbConnection = Connection)
|
||||
{
|
||||
|
@ -140,14 +140,15 @@ namespace BirdsiteLive.DAL.Postgres.DataAccessLayers
|
|||
fetchingErrorCount,
|
||||
lastSync = lastSync.ToUniversalTime(),
|
||||
movedTo,
|
||||
movedToAcct
|
||||
movedToAcct,
|
||||
deleted
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateTwitterUserAsync(SyncTwitterUser user)
|
||||
{
|
||||
await UpdateTwitterUserAsync(user.Id, user.LastTweetPostedId, user.LastTweetSynchronizedForAllFollowersId, user.FetchingErrorCount, user.LastSync, user.MovedTo, user.MovedToAcct);
|
||||
await UpdateTwitterUserAsync(user.Id, user.LastTweetPostedId, user.LastTweetSynchronizedForAllFollowersId, user.FetchingErrorCount, user.LastSync, user.MovedTo, user.MovedToAcct, user.Deleted);
|
||||
}
|
||||
|
||||
public async Task DeleteTwitterUserAsync(string acct)
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BirdsiteLive.DAL.Contracts
|
|||
Task<SyncTwitterUser> GetTwitterUserAsync(int id);
|
||||
Task<SyncTwitterUser[]> GetAllTwitterUsersAsync(int maxNumber);
|
||||
Task<SyncTwitterUser[]> GetAllTwitterUsersAsync();
|
||||
Task UpdateTwitterUserAsync(int id, long lastTweetPostedId, long lastTweetSynchronizedForAllFollowersId, int fetchingErrorCount, DateTime lastSync, string movedTo, string movedToAcct);
|
||||
Task UpdateTwitterUserAsync(int id, long lastTweetPostedId, long lastTweetSynchronizedForAllFollowersId, int fetchingErrorCount, DateTime lastSync, string movedTo, string movedToAcct, bool deleted);
|
||||
Task UpdateTwitterUserAsync(SyncTwitterUser user);
|
||||
Task DeleteTwitterUserAsync(string acct);
|
||||
Task DeleteTwitterUserAsync(int id);
|
||||
|
|
|
@ -16,5 +16,7 @@ namespace BirdsiteLive.DAL.Models
|
|||
|
||||
public string MovedTo { get; set; }
|
||||
public string MovedToAcct { get; set; }
|
||||
|
||||
public bool Deleted { get; set; } //TODO: update DAL
|
||||
}
|
||||
}
|
|
@ -109,7 +109,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
var updatedLastSyncId = 1550L;
|
||||
var now = DateTime.Now;
|
||||
var errors = 15;
|
||||
await dal.UpdateTwitterUserAsync(result.Id, updatedLastTweetId, updatedLastSyncId, errors, now, null, null);
|
||||
await dal.UpdateTwitterUserAsync(result.Id, updatedLastTweetId, updatedLastSyncId, errors, now, null, null, false);
|
||||
|
||||
result = await dal.GetTwitterUserAsync(acct);
|
||||
|
||||
|
@ -140,7 +140,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
var errors = 15;
|
||||
var movedTo = "https://";
|
||||
var movedToAcct = "@account@instance";
|
||||
await dal.UpdateTwitterUserAsync(result.Id, updatedLastTweetId, updatedLastSyncId, errors, now, movedTo, movedToAcct);
|
||||
await dal.UpdateTwitterUserAsync(result.Id, updatedLastTweetId, updatedLastSyncId, errors, now, movedTo, movedToAcct, false);
|
||||
|
||||
result = await dal.GetTwitterUserAsync(acct);
|
||||
|
||||
|
@ -222,7 +222,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
public async Task Update_NoId()
|
||||
{
|
||||
var dal = new TwitterUserPostgresDal(_settings);
|
||||
await dal.UpdateTwitterUserAsync(default, default, default, default, DateTime.UtcNow, null, null);
|
||||
await dal.UpdateTwitterUserAsync(default, default, default, default, DateTime.UtcNow, null, null, false);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -230,7 +230,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
public async Task Update_NoLastTweetPostedId()
|
||||
{
|
||||
var dal = new TwitterUserPostgresDal(_settings);
|
||||
await dal.UpdateTwitterUserAsync(12, default, default, default, DateTime.UtcNow, null, null);
|
||||
await dal.UpdateTwitterUserAsync(12, default, default, default, DateTime.UtcNow, null, null, false);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -238,7 +238,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
public async Task Update_NoLastTweetSynchronizedForAllFollowersId()
|
||||
{
|
||||
var dal = new TwitterUserPostgresDal(_settings);
|
||||
await dal.UpdateTwitterUserAsync(12, 9556, default, default, DateTime.UtcNow, null, null);
|
||||
await dal.UpdateTwitterUserAsync(12, 9556, default, default, DateTime.UtcNow, null, null, false);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -246,7 +246,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
public async Task Update_NoLastSync()
|
||||
{
|
||||
var dal = new TwitterUserPostgresDal(_settings);
|
||||
await dal.UpdateTwitterUserAsync(12, 9556, 65, default, default, null, null);
|
||||
await dal.UpdateTwitterUserAsync(12, 9556, 65, default, default, null, null, false);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -381,7 +381,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
{
|
||||
var user = allUsers[i];
|
||||
var date = i % 2 == 0 ? oldest : newest;
|
||||
await dal.UpdateTwitterUserAsync(user.Id, user.LastTweetPostedId, user.LastTweetSynchronizedForAllFollowersId, 0, date, null, null);
|
||||
await dal.UpdateTwitterUserAsync(user.Id, user.LastTweetPostedId, user.LastTweetSynchronizedForAllFollowersId, 0, date, null, null, false);
|
||||
}
|
||||
|
||||
var result = await dal.GetAllTwitterUsersAsync(10);
|
||||
|
@ -453,7 +453,7 @@ namespace BirdsiteLive.DAL.Postgres.Tests.DataAccessLayers
|
|||
if (i == 0 || i == 2 || i == 3)
|
||||
{
|
||||
var t = await dal.GetTwitterUserAsync(acct);
|
||||
await dal.UpdateTwitterUserAsync(t.Id ,1L,2L, 50+i*2, DateTime.Now, null, null);
|
||||
await dal.UpdateTwitterUserAsync(t.Id ,1L,2L, 50+i*2, DateTime.Now, null, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
|
|||
It.Is<int>(y => y == 0),
|
||||
It.IsAny<DateTime>(),
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<string>(y => y == null)
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<bool>(y => y == false)
|
||||
))
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
|
|||
It.Is<int>(y => y == 0),
|
||||
It.IsAny<DateTime>(),
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<string>(y => y == null)
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<bool>(y => y == false)
|
||||
))
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
|
@ -137,7 +138,8 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
|
|||
It.Is<int>(y => y == 0),
|
||||
It.IsAny<DateTime>(),
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<string>(y => y == null)
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<bool>(y => y == false)
|
||||
))
|
||||
.Throws(new ArgumentException());
|
||||
|
||||
|
@ -208,7 +210,8 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
|
|||
It.Is<int>(y => y == 0),
|
||||
It.IsAny<DateTime>(),
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<string>(y => y == null)
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<bool>(y => y == false)
|
||||
))
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
|
@ -289,7 +292,8 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
|
|||
It.Is<int>(y => y == 0),
|
||||
It.IsAny<DateTime>(),
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<string>(y => y == null)
|
||||
It.Is<string>(y => y == null),
|
||||
It.Is<bool>(y => y == false)
|
||||
))
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
|
|
Reference in a new issue