Skip to content

Commit

Permalink
Merge pull request #6 from rmaclean/export
Browse files Browse the repository at this point in the history
Export
  • Loading branch information
rmaclean committed Jul 17, 2020
2 parents 892f20a + c9a98fe commit 4b15f8a
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 19 deletions.
10 changes: 4 additions & 6 deletions Commands/BaseScoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ namespace twot
using Tweetinvi;
using Tweetinvi.Models;

using static System.ConsoleColor;
using static ConsoleHelper;

internal class ScoreSettings
{
public string mode { get; set; } = string.Empty;
Expand All @@ -33,16 +30,17 @@ protected BaseScoreCommand()

internal static async Task<List<(IUser, double)>> GetBotsOrDead(double minScore)
{
Writeln(DarkBlue, "Loading people, this may take some time...");
using (var spinner = new Spinner())
using (var spinner = new Spinner("Loading your details"))
{
var me = User.GetAuthenticatedUser();

spinner.Message = "Loading your friends";
var friends = await me.GetFriendIdsAsync(int.MaxValue);
spinner.Message = "Loading your followers";
var followers = await me.GetFollowersAsync(int.MaxValue);

var scoringConfig = new ScoreConfig();

spinner.Message = "Determining scores";
var result = followers
.Where(_ => !friends.Contains(_.Id))
.Select(follower => (Follower: follower, Score: Score(follower, scoringConfig)))
Expand Down
6 changes: 5 additions & 1 deletion Commands/BlockTrainCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,19 @@ public void AddCommand(Command rootCommand)

private static async Task<List<IUser>> GetTargets(string targetUsername)
{
using (var spinner = new Spinner())
using (var spinner = new Spinner("Loading your details"))
{
var result = new List<IUser>();
var me = User.GetAuthenticatedUser();

spinner.Message = "Loading your friends";
var friends = await me.GetFriendsAsync(int.MaxValue);

spinner.Message = "Loading your target";
var target = User.GetUserFromScreenName(targetUsername);
result.Add(target);

spinner.Message = "Loading your targets followers";
var enermies = await target.GetFollowersAsync(int.MaxValue);

var targetsForBlock = enermies.Where(enermy => !friends.Contains(enermy));
Expand Down
75 changes: 75 additions & 0 deletions Commands/ExportCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
namespace twot
{
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Threading.Tasks;
using Tweetinvi;
using Tweetinvi.Models;
using static System.ConsoleColor;
using static CommandHelpers;
using static ConsoleHelper;

#pragma warning disable CA1812
internal class ExportCommand : ICommand
#pragma warning restore CA1812
{
public void AddCommand(Command rootCommand)
{
var cmd = new Command("Export", "Exports your block or mute list");
cmd.AddAlias("export");
cmd.AddAlias("e");

var muteOption = new Option<bool>("--mute", "Rather than export your block list, this command will " +
"export your mute list");
muteOption.AddAlias("-m");
cmd.Add(muteOption);

var fileOption = new Option<string>("--file", () => "export.log", "The file to export to. Defaults to " +
"export.log");
fileOption.AddAlias("-f");
cmd.Add(fileOption);

cmd.Handler = CommandHandler.Create<bool, string>(this.Execute);
rootCommand.Add(cmd);
}

private async Task<int> Execute(bool mute, string file)
{
if (!CommandHeader("Running export ✍", false))
{
return -1;
}

using (var logger = new ThreadedLogger($"{file}", true))
using (var spinner = new Spinner("Loading your details"))
{
logger.LogMessage($"# Export started {DateTime.Now.ToLongDateString()} " +
$"{DateTime.Now.ToLongTimeString()}");
logger.LogMessage($"# {(mute ? "Muted accounts" : "Blocked accounts")}");

var me = User.GetAuthenticatedUser();
IEnumerable<IUser> users;
if (mute)
{
spinner.Message = "Loading your muted accounts";
users = Account.GetMutedUsers();
}
else
{
spinner.Message = "Loading your blocked accounts";
users = await me.GetBlockedUsersAsync();
}

foreach (var user in users)
{
logger.LogMessage(user.ScreenName);
}
}

Writeln(Green, "Export completed");
return 0;
}
}
}
2 changes: 1 addition & 1 deletion Commands/UnblockCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private async Task<int> Execute(bool dryRun, string targetUsername, bool all, st

if (all)
{
using (var spinner = new Spinner())
using (var spinner = new Spinner("Loading accounts"))
{
if (unmute)
{
Expand Down
26 changes: 24 additions & 2 deletions Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ namespace twot
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using Microsoft.Extensions.Configuration;
using Tweetinvi;

using Tweetinvi.Events;
using static System.ConsoleColor;
using static ConsoleHelper;

Expand Down Expand Up @@ -55,7 +56,8 @@ public static (bool Success, Config Config) Load()
propInfo.PropertyInfo.SetValue(result, configValue);
}

RateLimit.RateLimitTrackerMode = RateLimitTrackerMode.TrackAndAwait;
RateLimit.RateLimitTrackerMode = RateLimitTrackerMode.TrackOnly;
TweetinviEvents.QueryBeforeExecute += RateLimitCheck;
Auth.SetUserCredentials(result.APIKey, result.APISecret, result.AccessToken, result.AccessSecret);
return (true, result);
}
Expand All @@ -68,6 +70,26 @@ public override string ToString()
.Where(property => property.Config != null)
.Select(property => $"{property.Config!.DisplayName} = {property.PropertyInfo.GetValue(this)}"));
}

private static void RateLimitCheck(object? sender, QueryBeforeExecuteEventArgs args)
{
var queryRateLimits = RateLimit.GetQueryRateLimit(args.QueryURL);

if (queryRateLimits != null)
{
if (queryRateLimits.Remaining > 0)
{
return;
}

using (var spinner = new Spinner("You have been rate limited by Twitter until " +
$"{queryRateLimits.ResetDateTime.ToLongTimeString()}. Please wait or Ctrl+C to quit"))
{
Thread.Sleep((int)queryRateLimits.ResetDateTimeInMilliseconds);
spinner.Done();
}
}
}
}

[System.AttributeUsage(System.AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
Expand Down
10 changes: 5 additions & 5 deletions ProgressMeters/ProgressMeter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,20 @@ public void Dispose()
GC.SuppressFinalize(this);
}

internal void Write(string message, int offset = 0)
internal void Write(string message, int verticalOffset = 0, int horizontalOffset = 0)
{
lock (writeLocker)
{
var target = this.cursorLine + offset;
var target = this.cursorLine + verticalOffset;
if (target >= Console.BufferHeight)
{
target = Console.BufferHeight - 1 - Math.Min(offset - 1, 1 - offset);
this.cursorLine = target - offset;
target = Console.BufferHeight - 1 - Math.Min(verticalOffset - 1, 1 - verticalOffset);
this.cursorLine = target - verticalOffset;
}

Console.CursorTop = target;

Console.CursorLeft = 0;
Console.CursorLeft = horizontalOffset;
Console.Write(message);
}
}
Expand Down
51 changes: 47 additions & 4 deletions ProgressMeters/Spinner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,67 @@ namespace twot

internal class Spinner : ProgressMeter, IDisposable
{
private readonly string[] steps = new[] { "|", "/", "-", "\\" };
private readonly string[][] spinners = new[]
{
new[] { "|", "/", "-", "\\" },
new[] { "", "", "", "", "", "", "", "" },
new[] { "", "", "", "", "", "", "", "" },
new[] { "", "", "", "", "", "", "", "" },
new[] { "", "", "", "" },
new[] { "", "", "", "" },
new[] { "", "", "", "" },
new[] { "", "", "", "" },
new[] { "", "", "", "", "", "", "", "" },
new[] { "", "", "", "", "", "", "", "", "", "" },
};

private string[] steps;

private int step;

public Spinner()
private bool messageUpdated = false;

private string message = string.Empty;

private Random random = new Random();

public Spinner(string message)
: base(200)
{
// no-op
this.steps = this.spinners[0];
this.Message = message;
}

public string Message
{
get => this.message;
set
{
this.message = value;
this.messageUpdated = true;
}
}

internal override void UpdateUI(object? state)
{
this.Write(this.steps[this.step]);
if (this.messageUpdated)
{
this.steps = this.spinners[this.random.Next(this.spinners.Length)];
this.Write(string.Empty.PadRight(Console.WindowWidth - 1, ' '));
var existingColour = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.DarkBlue;
this.Write(this.Message);
Console.ForegroundColor = existingColour;
this.messageUpdated = false;
}

this.step++;
if (this.step >= this.steps.Length)
{
this.step = 0;
}

this.Write(this.steps[this.step], horizontalOffset: this.Message.Length + 1);
}

internal void Done()
Expand Down

0 comments on commit 4b15f8a

Please sign in to comment.