a LOT More work

This commit is contained in:
Kwoth 2016-08-24 19:04:24 +02:00
parent cb7fb76b91
commit acd1480cb1
24 changed files with 264 additions and 3723 deletions

1
.gitignore vendored
View File

@ -32,3 +32,4 @@ NadekoBot.sln.iml
.idea/vcs.xml .idea/vcs.xml
.idea/modules.xml .idea/modules.xml
NadekoBot/bin/Debug/data/config_xnaas.json NadekoBot/bin/Debug/data/config_xnaas.json
src/NadekoBot/project.lock.json

View File

@ -1,53 +0,0 @@
using System.Threading.Tasks;
namespace NadekoBot.Classes
{
internal static class FlowersHandler
{
public static async Task AddFlowersAsync(Discord.User u, string reason, int amount, bool silent = false)
{
if (amount <= 0)
return;
await Task.Run(() =>
{
DbHandler.Instance.Connection.Insert(new DataModels.CurrencyTransaction
{
Reason = reason,
UserId = (long)u.Id,
Value = amount,
});
}).ConfigureAwait(false);
if (silent)
return;
var flows = amount + " " + NadekoBot.Config.CurrencySign;
await u.SendMessageAsync("👑Congratulations!👑\nYou received: " + flows).ConfigureAwait(false);
}
public static async Task<bool> RemoveFlowers(Discord.User u, string reason, int amount, bool silent=false, string message="👎`Bot owner has taken {0}{1} from you.`")
{
if (amount <= 0)
return false;
var uid = (long)u.Id;
var state = DbHandler.Instance.FindOne<DataModels.CurrencyState>(cs => cs.UserId == uid);
if (state.Value < amount)
return false;
DbHandler.Instance.Connection.Insert(new DataModels.CurrencyTransaction
{
Reason = reason,
UserId = (long)u.Id,
Value = -amount,
});
if (silent)
return true;
await u.SendMessageAsync(string.Format(message,amount,NadekoBot.Config.CurrencySign)).ConfigureAwait(false);
return true;
}
}
}

View File

@ -1,25 +0,0 @@
using NadekoBot.DataModels;
using System;
namespace NadekoBot.Classes
{
internal static class IncidentsHandler
{
public static void Add(ulong serverId, ulong channelId, string text)
{
var def = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"INCIDENT: {text}");
Console.ForegroundColor = def;
var incident = new Incident
{
ChannelId = (long)channelId,
ServerId = (long)serverId,
Text = text,
Read = false
};
DbHandler.Instance.Connection.Insert(incident, typeof(Incident));
}
}
}

View File

@ -1,284 +0,0 @@
using Discord;
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules.Administration.Commands;
using NadekoBot.Modules.Music;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using System.Timers;
namespace NadekoBot
{
public class NadekoStats
{
public static NadekoStats Instance { get; } = new NadekoStats();
public string BotVersion => $"{Assembly.GetExecutingAssembly().GetName().Name} v{Assembly.GetExecutingAssembly().GetName().Version}";
private int commandsRan = 0;
private string statsCache = "";
private readonly Stopwatch statsStopwatch = new Stopwatch();
public int ServerCount { get; private set; } = 0;
public int TextChannelsCount { get; private set; } = 0;
public int VoiceChannelsCount { get; private set; } = 0;
private readonly Timer commandLogTimer = new Timer() { Interval = 10000 };
private readonly Timer carbonStatusTimer = new Timer() { Interval = 3600000 };
private static ulong messageCounter = 0;
public static ulong MessageCounter => messageCounter;
static NadekoStats() { }
private NadekoStats()
{
var commandService = NadekoBot.Client.GetService<CommandService>();
statsStopwatch.Start();
commandService.CommandExecuted += StatsCollector_RanCommand;
commandService.CommandFinished += CommandService_CommandFinished;
commandService.CommandErrored += CommandService_CommandFinished;
Task.Run(StartCollecting);
commandLogTimer.Start();
ServerCount = NadekoBot.Client.Servers.Count();
var channels = NadekoBot.Client.Servers.SelectMany(s => s.AllChannels);
var channelsArray = channels as Channel[] ?? channels.ToArray();
TextChannelsCount = channelsArray.Count(c => c.Type == ChannelType.Text);
VoiceChannelsCount = channelsArray.Count() - TextChannelsCount;
NadekoBot.Client.MessageReceived += (s, e) => messageCounter++;
NadekoBot.Client.JoinedServer += (s, e) =>
{
try
{
ServerCount++;
TextChannelsCount += e.Server.TextChannels.Count();
VoiceChannelsCount += e.Server.VoiceChannels.Count();
//await SendUpdateToCarbon().ConfigureAwait(false);
}
catch { }
};
NadekoBot.Client.LeftServer += (s, e) =>
{
try
{
ServerCount--;
TextChannelsCount -= e.Server.TextChannels.Count();
VoiceChannelsCount -= e.Server.VoiceChannels.Count();
//await SendUpdateToCarbon().ConfigureAwait(false);
}
catch { }
};
NadekoBot.Client.ChannelCreated += (s, e) =>
{
try
{
if (e.Channel.IsPrivate)
return;
if (e.Channel.Type == ChannelType.Text)
TextChannelsCount++;
else if (e.Channel.Type == ChannelType.Voice)
VoiceChannelsCount++;
}
catch { }
};
NadekoBot.Client.ChannelDestroyed += (s, e) =>
{
try
{
if (e.Channel.IsPrivate)
return;
if (e.Channel.Type == ChannelType.Text)
TextChannelsCount--;
else if (e.Channel.Type == ChannelType.Voice)
VoiceChannelsCount--;
}
catch { }
};
carbonStatusTimer.Elapsed += async (s, e) => await SendUpdateToCarbon().ConfigureAwait(false);
carbonStatusTimer.Start();
}
HttpClient carbonClient = new HttpClient();
private async Task SendUpdateToCarbon()
{
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.CarbonKey))
return;
try
{
using (var content = new FormUrlEncodedContent(new Dictionary<string, string> {
{ "servercount", NadekoBot.Client.Servers.Count().ToString() },
{ "key", NadekoBot.Credentials.CarbonKey }
}))
{
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var res = await carbonClient.PostAsync("https://www.carbonitex.net/discord/data/botdata.php", content).ConfigureAwait(false);
};
}
catch (Exception ex)
{
Console.WriteLine("Failed sending status update to carbon.");
Console.WriteLine(ex);
}
}
public TimeSpan GetUptime() =>
DateTime.Now - Process.GetCurrentProcess().StartTime;
public string GetUptimeString()
{
var time = GetUptime();
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
}
public Task LoadStats() =>
Task.Run(() =>
{
var songs = MusicModule.MusicPlayers.Count(mp => mp.Value.CurrentSong != null);
var sb = new System.Text.StringBuilder();
sb.AppendLine("`Author: Kwoth` `Library: Discord.Net`");
sb.AppendLine($"`Bot Version: {BotVersion}`");
sb.AppendLine($"`Bot id: {NadekoBot.Client.CurrentUser.Id}`");
sb.Append("`Owners' Ids:` ");
sb.AppendLine("`" + String.Join(", ", NadekoBot.Credentials.OwnerIds) + "`");
sb.AppendLine($"`Uptime: {GetUptimeString()}`");
sb.Append($"`Servers: {ServerCount}");
sb.Append($" | TextChannels: {TextChannelsCount}");
sb.AppendLine($" | VoiceChannels: {VoiceChannelsCount}`");
sb.AppendLine($"`Commands Ran this session: {commandsRan}`");
sb.AppendLine($"`Message queue size: {NadekoBot.Client.MessageQueue.Count}`");
sb.Append($"`Greeted {ServerGreetCommand.Greeted} times.`");
sb.AppendLine($" `| Playing {songs} songs, ".SnPl(songs) +
$"{MusicModule.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count)} queued.`");
sb.AppendLine($"`Messages: {messageCounter} ({messageCounter / (double)GetUptime().TotalSeconds:F2}/sec)` `Heap: {Heap(false)}`");
statsCache = sb.ToString();
});
public string Heap(bool pass = true) => Math.Round((double)GC.GetTotalMemory(pass) / 1.MiB(), 2).ToString();
public async Task<string> GetStats()
{
if (statsStopwatch.Elapsed.Seconds < 4 &&
!string.IsNullOrWhiteSpace(statsCache)) return statsCache;
await LoadStats().ConfigureAwait(false);
statsStopwatch.Restart();
return statsCache;
}
private async Task StartCollecting()
{
var statsSw = new Stopwatch();
while (true)
{
await Task.Delay(new TimeSpan(0, 30, 0)).ConfigureAwait(false);
statsSw.Start();
try
{
var onlineUsers = await Task.Run(() => NadekoBot.Client.Servers.Sum(x => x.Users.Count())).ConfigureAwait(false);
var realOnlineUsers = await Task.Run(() => NadekoBot.Client.Servers
.Sum(x => x.Users.Count(u => u.Status == UserStatus.Online)))
.ConfigureAwait(false);
var connectedServers = NadekoBot.Client.Servers.Count();
Classes.DbHandler.Instance.Connection.Insert(new DataModels.Stats
{
OnlineUsers = onlineUsers,
RealOnlineUsers = realOnlineUsers,
Uptime = GetUptime(),
ConnectedServers = connectedServers,
DateAdded = DateTime.Now
});
statsSw.Stop();
var clr = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine($"--------------\nCollecting stats finished in {statsSw.Elapsed.TotalSeconds}s\n-------------");
Console.ForegroundColor = clr;
statsSw.Reset();
}
catch
{
Console.WriteLine("DB Exception in stats collecting.");
break;
}
}
}
private static ConcurrentDictionary<ulong, DateTime> commandTracker = new ConcurrentDictionary<ulong, DateTime>();
private void CommandService_CommandFinished(object sender, CommandEventArgs e)
{
DateTime dt;
if (!commandTracker.TryGetValue(e.Message.Id, out dt))
return;
try
{
if (e is CommandErrorEventArgs)
{
var er = e as CommandErrorEventArgs;
if (er.ErrorType == CommandErrorType.Exception)
{
File.AppendAllText("errors.txt", $@"Command: {er.Command}
{er.Exception}
-------------------------------------
");
Console.WriteLine($">>COMMAND ERRORED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {imsg.Author.Username} [{imsg.Author.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----");
}
}
else
{
Console.WriteLine($">>COMMAND ENDED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {imsg.Author.Username} [{imsg.Author.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----");
}
}
catch { }
}
private async void StatsCollector_RanCommand(object sender, CommandEventArgs e)
{
commandTracker.TryAdd(e.Message.Id, DateTime.UtcNow);
Console.WriteLine($">>COMMAND STARTED\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {imsg.Author.Username} [{imsg.Author.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----");
#if !NADEKO_RELEASE
await Task.Run(() =>
{
try
{
commandsRan++;
Classes.DbHandler.Instance.Connection.Insert(new DataModels.Command
{
ServerId = (long)(e.Server?.Id ?? 0),
ServerName = e.Server?.Name ?? "--Direct Message--",
ChannelId = (long)e.Channel.Id,
ChannelName = e.Channel.IsPrivate ? "--Direct Message" : e.Channel.Name,
UserId = (long)imsg.Author.Id,
UserName = imsg.Author.Username,
CommandName = e.Command.Text,
DateAdded = DateTime.Now
});
}
catch (Exception ex)
{
Console.WriteLine("Probably unimportant error in ran command DB write.");
Console.WriteLine(ex);
}
}).ConfigureAwait(false);
#endif
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,8 @@ using NadekoBot.Services;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Discord.WebSocket; using Discord.WebSocket;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
//todo fix delmsgoncmd //todo fix delmsgoncmd
//todo DB //todo DB
@ -36,22 +38,25 @@ namespace NadekoBot.Modules.Administration
// Environment.Exit(0); // Environment.Exit(0);
//} //}
////todo DB [LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)]
//[RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)]
//[RequirePermission(GuildPermission.ManageGuild)] public async Task Delmsgoncmd(IMessage imsg)
//public async Task Delmsgoncmd(IMessage imsg) {
//{ var channel = (ITextChannel)imsg.Channel;
// var channel = (ITextChannel)imsg.Channel; Config conf;
using (var uow = DbHandler.UnitOfWork())
// var conf = SpecificConfigurations.Default.Of(channel.Guild.Id); {
// conf.AutoDeleteMessagesOnCommand = !conf.AutoDeleteMessagesOnCommand; conf = uow.Configs.For(channel.Guild.Id);
// await Classes.JSONModels.ConfigHandler.SaveConfig().ConfigureAwait(false); conf.DeleteMessageOnCommand = !conf.DeleteMessageOnCommand;
// if (conf.AutoDeleteMessagesOnCommand) uow.Configs.Update(conf);
// await channel.SendMessageAsync("❗`Now automatically deleting successfull command invokations.`"); await uow.CompleteAsync();
// else }
// await channel.SendMessageAsync("❗`Stopped automatic deletion of successfull command invokations.`"); if (conf.DeleteMessageOnCommand)
//} await channel.SendMessageAsync("❗`Now automatically deleting successfull command invokations.`");
else
await channel.SendMessageAsync("❗`Stopped automatic deletion of successfull command invokations.`");
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary] [LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
@ -563,30 +568,6 @@ namespace NadekoBot.Modules.Administration
// } // }
//} //}
////todo owner only
////todo DB
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)]
//public async Task Donadd(IMessage imsg, IUser donator, int amount)
//{
// var channel = (ITextChannel)imsg.Channel;
// var donator = channel.Guild.FindUsers(donator).FirstOrDefault();
// var amount = int.Parse(amount);
// if (donator == null) return;
// try
// {
// DbHandler.Instance.Connection.Insert(new Donator
// {
// Amount = amount,
// UserName = donator.Name,
// UserId = (long)donator.Id
// });
// channel.SendMessageAsync("Successfuly added a new donator. 👑").ConfigureAwait(false);
// }
// catch { }
//}
////todo owner only ////todo owner only
//[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)] //[RequireContext(ContextType.Guild)]
@ -660,18 +641,36 @@ namespace NadekoBot.Modules.Administration
await channel.SendMessageAsync(send).ConfigureAwait(false); await channel.SendMessageAsync(send).ConfigureAwait(false);
} }
//todo DB [LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)]
//[RequireContext(ContextType.Guild)] public async Task Donators(IMessage imsg)
//public async Task Donators(IMessage imsg) {
//{ var channel = (ITextChannel)imsg.Channel;
// var channel = (ITextChannel)imsg.Channel; IEnumerable<Donator> donatorsOrdered;
using (var uow = DbHandler.UnitOfWork())
{
donatorsOrdered = uow.Donators.GetDonatorsOrdered();
}
// var rows = DbHandler.Instance.GetAllRows<Donator>(); string str = $"**Thanks to the people listed below for making this project happen!**\n";
// var donatorsOrdered = rows.OrderByDescending(d => d.Amount); await channel.SendMessageAsync(str + string.Join("⭐", donatorsOrdered.Select(d => d.Name))).ConfigureAwait(false);
// string str = $"**Thanks to the people listed below for making this project happen!**\n"; }
// await channel.SendMessageAsync(str + string.Join("⭐", donatorsOrdered.Select(d => d.UserName))).ConfigureAwait(false);
//} [LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Donadd(IMessage imsg, IUser donator, int amount)
{
var channel = (ITextChannel)imsg.Channel;
Donator don;
using (var uow = DbHandler.UnitOfWork())
{
don = uow.Donators.AddOrUpdateDonator(donator.Id, donator.Username, amount);
await uow.CompleteAsync();
}
await channel.SendMessageAsync($"Successfuly added a new donator. Total donated amount from this user: {don.Amount} 👑").ConfigureAwait(false);
}
} }
} }

View File

@ -10,7 +10,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Commands namespace NadekoBot.Modules.Utility
{ {
public partial class Utility public partial class Utility
{ {
@ -103,7 +103,7 @@ namespace NadekoBot.Modules.Utility.Commands
{ {
var quotes = uow.Quotes.GetAllQuotesByKeyword(keyword); var quotes = uow.Quotes.GetAllQuotesByKeyword(keyword);
uow.Quotes.RemoveRange(quotes.Select(q => q.Id).ToArray());//wtf?! uow.Quotes.RemoveRange(quotes.ToArray());//wtf?!
await uow.CompleteAsync(); await uow.CompleteAsync();
} }

View File

@ -10,6 +10,8 @@ namespace NadekoBot.Services.Database
public interface IUnitOfWork : IDisposable public interface IUnitOfWork : IDisposable
{ {
IQuoteRepository Quotes { get; } IQuoteRepository Quotes { get; }
IConfigRepository Configs { get; }
IDonatorsRepository Donators { get; }
int Complete(); int Complete();
Task<int> CompleteAsync(); Task<int> CompleteAsync();
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Models
{
public class Config : DbEntity
{
public ulong GuildId { get; set; }
public bool DeleteMessageOnCommand { get; set; } = false;
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Models
{
public class Donator : DbEntity
{
public ulong UserId { get; set; }
public string Name { get; set; }
public int Amount { get; set; } = 0;
}
}

View File

@ -15,24 +15,28 @@ namespace NadekoBot.Services.Database
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
#region QUOTES #region QUOTES
//// guildid and keyword are unique pair
var quoteEntity = modelBuilder.Entity<Quote>(); var quoteEntity = modelBuilder.Entity<Quote>();
//quoteEntity
// .HasAlternateKey(q => q.GuildId)
// .HasName("AK_GuildId_Keyword");
//quoteEntity
// .HasAlternateKey(q => q.Keyword)
// .HasName("AK_GuildId_Keyword");
quoteEntity
.HasIndex(q => new { q.GuildId, q.Keyword })
.IsUnique();
#endregion #endregion
#region
#region Donators
var donatorEntity = modelBuilder.Entity<Donator>();
donatorEntity
.HasIndex(d => d.UserId)
.IsUnique();
#endregion
#region Config
var configEntity = modelBuilder.Entity<Config>();
configEntity
.HasIndex(c => c.GuildId)
.IsUnique();
#endregion #endregion
} }
protected abstract override void OnConfiguring(DbContextOptionsBuilder optionsBuilder); protected abstract override void OnConfiguring(DbContextOptionsBuilder optionsBuilder);

View File

@ -0,0 +1,15 @@
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Database.Repositories.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Repositories
{
public interface IConfigRepository : IRepository<Config>
{
Config For(ulong guildId);
}
}

View File

@ -0,0 +1,15 @@
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Repositories
{
public interface IDonatorsRepository : IRepository<Donator>
{
IEnumerable<Donator> GetDonatorsOrdered();
Donator AddOrUpdateDonator(ulong userId, string name, int amount);
}
}

View File

@ -18,7 +18,7 @@ namespace NadekoBot.Services.Database.Repositories
void Remove(int id); void Remove(int id);
void Remove(T obj); void Remove(T obj);
void RemoveRange(params int[] ids); void RemoveRange(params T[] objs);
void Update(T obj); void Update(T obj);
void UpdateRange(params T[] objs); void UpdateRange(params T[] objs);

View File

@ -0,0 +1,35 @@
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace NadekoBot.Services.Database.Repositories.Impl
{
public class ConfigRepository : Repository<Config>, IConfigRepository
{
public ConfigRepository(DbContext context) : base(context)
{
}
/// <summary>
/// Gets and creates if it doesn't exist a config for a guild.
/// </summary>
/// <param name="guildId"></param>
/// <returns></returns>
public Config For(ulong guildId)
{
var config = _set.Where(c => c.GuildId == guildId).FirstOrDefault();
if (config == null)
{
_set.Add((config = new Config
{
GuildId = guildId
}));
}
return config;
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Services.Database.Repositories.Impl
{
public class DonatorsRepository : Repository<Donator>, IDonatorsRepository
{
public DonatorsRepository(DbContext context) : base(context)
{
}
public Donator AddOrUpdateDonator(ulong userId, string name, int amount)
{
var donator = _set.Find(userId);
if (donator == null)
{
_set.Add(donator = new Donator
{
Amount = amount,
UserId = userId
});
}
else
{
donator.Amount += amount;
_set.Update(donator);
}
return donator;
}
public IEnumerable<Donator> GetDonatorsOrdered() =>
_set.OrderByDescending(d => d.Amount).ToList();
}
}

View File

@ -15,6 +15,11 @@ namespace NadekoBot.Services.Database
private IQuoteRepository _quotes; private IQuoteRepository _quotes;
public IQuoteRepository Quotes => _quotes ?? (_quotes = new QuoteRepository(_context)); public IQuoteRepository Quotes => _quotes ?? (_quotes = new QuoteRepository(_context));
private IConfigRepository _configs;
public IConfigRepository Configs => _configs ?? (_configs = new ConfigRepository(_context));
private IDonatorsRepository _donators;
public IDonatorsRepository Donators => _donators ?? (_donators = new DonatorsRepository(_context));
public UnitOfWork(NadekoContext context) public UnitOfWork(NadekoContext context)
{ {

View File

@ -41,7 +41,10 @@ namespace NadekoBot.Services.Impl
MashapeKey = cm.MashapeKey; MashapeKey = cm.MashapeKey;
OsuApiKey = cm.OsuApiKey; OsuApiKey = cm.OsuApiKey;
SoundCloudClientId = cm.SoundCloudClientId; SoundCloudClientId = cm.SoundCloudClientId;
Db = new DB(string.IsNullOrWhiteSpace(cm.Db.Type) ? cm.Db.Type : "sqlite", cm.Db.ConnectionString); if (cm.Db == null)
Db = new DB("sqlite", "");
else
Db = new DB(cm.Db.Type, cm.Db.ConnectionString);
} }
else else
_log.Fatal("credentials.json is missing. Failed to start."); _log.Fatal("credentials.json is missing. Failed to start.");

View File

@ -7,7 +7,7 @@
"emitEntryPoint": true, "emitEntryPoint": true,
"allowUnsafe": true, "allowUnsafe": true,
"compile": { "compile": {
"exclude": [ "_Models", "Classes", "_Modules" ] "exclude": [ "_Models", "_Classes", "_Modules" ]
}, },
"define": [] "define": []
}, },
@ -24,6 +24,7 @@
"System.Resources.ResourceWriter": "4.0.0-beta-22816", "System.Resources.ResourceWriter": "4.0.0-beta-22816",
"Google.Apis.YouTube.v3": "1.15.0.582", "Google.Apis.YouTube.v3": "1.15.0.582",
"Google.Apis.Urlshortener.v1": "1.15.0.138", "Google.Apis.Urlshortener.v1": "1.15.0.138",
"Google.Apis.Customsearch.v1": "1.16.0.466",
"System.Diagnostics.Contracts": "4.0.1", "System.Diagnostics.Contracts": "4.0.1",
"NLog": "4.4.0-betaV15", "NLog": "4.4.0-betaV15",
"VideoLibrary": "1.3.4", "VideoLibrary": "1.3.4",

View File

@ -23,10 +23,10 @@
"lib/netstandard1.3/NCalc.dll": {} "lib/netstandard1.3/NCalc.dll": {}
} }
}, },
"Google.Apis/1.15.0": { "Google.Apis/1.16.0": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
"Google.Apis.Core": "1.15.0", "Google.Apis.Core": "1.16.0",
"System.Collections": "4.0.11", "System.Collections": "4.0.11",
"System.Diagnostics.Debug": "4.0.11", "System.Diagnostics.Debug": "4.0.11",
"System.IO": "4.1.0", "System.IO": "4.1.0",
@ -81,7 +81,7 @@
"lib/netstandard1.3/Google.Apis.Auth.dll": {} "lib/netstandard1.3/Google.Apis.Auth.dll": {}
} }
}, },
"Google.Apis.Core/1.15.0": { "Google.Apis.Core/1.16.0": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
"Newtonsoft.Json": "9.0.1", "Newtonsoft.Json": "9.0.1",
@ -108,6 +108,18 @@
"lib/netstandard1.3/Google.Apis.Core.dll": {} "lib/netstandard1.3/Google.Apis.Core.dll": {}
} }
}, },
"Google.Apis.Customsearch.v1/1.16.0.466": {
"type": "package",
"dependencies": {
"Google.Apis": "1.16.0"
},
"compile": {
"lib/netstandard1.3/Google.Apis.Customsearch.v1.dll": {}
},
"runtime": {
"lib/netstandard1.3/Google.Apis.Customsearch.v1.dll": {}
}
},
"Google.Apis.Urlshortener.v1/1.15.0.138": { "Google.Apis.Urlshortener.v1/1.15.0.138": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
@ -3203,12 +3215,12 @@
"lib/netstandard1.3/NCalc.dll" "lib/netstandard1.3/NCalc.dll"
] ]
}, },
"Google.Apis/1.15.0": { "Google.Apis/1.16.0": {
"sha512": "B//vbZgUsR0jdJztCJ0ORmVcAzhoiisIsxwc1libVjoZzu+kxUKNJKUl5Wlkj7V28kauS56y3hJUj3FMsgaJZQ==", "sha512": "/p657K7J7p9aRl6QxUjQfNK0AobxnLHwDWdSqAr/17lZeQR+XMuEbIy7No80+zDeS39kKrRVWFlu1vHiws7gRQ==",
"type": "package", "type": "package",
"path": "Google.Apis/1.15.0", "path": "Google.Apis/1.16.0",
"files": [ "files": [
"Google.Apis.1.15.0.nupkg.sha512", "Google.Apis.1.16.0.nupkg.sha512",
"Google.Apis.nuspec", "Google.Apis.nuspec",
"License.txt", "License.txt",
"lib/net45/Google.Apis.PlatformServices.dll", "lib/net45/Google.Apis.PlatformServices.dll",
@ -3286,12 +3298,12 @@
"lib/wpa81/Google.Apis.Auth.xml" "lib/wpa81/Google.Apis.Auth.xml"
] ]
}, },
"Google.Apis.Core/1.15.0": { "Google.Apis.Core/1.16.0": {
"sha512": "izmsmat5RRL0bmJ2tr3SvlqEiGf40wDeOTHv0PJOVUvHoZBdAaVbbZFxtevOWOyo878mwpYGXfzMs5Zfoyfrfw==", "sha512": "uATqVAsPHlpOf+3VV51xFEIghAMSLJyh1hqoVpnPOlkXBx7fkOcs0qP3tKXtmsaeuyC/7BYM1Tt42lyIyhY2lQ==",
"type": "package", "type": "package",
"path": "Google.Apis.Core/1.15.0", "path": "Google.Apis.Core/1.16.0",
"files": [ "files": [
"Google.Apis.Core.1.15.0.nupkg.sha512", "Google.Apis.Core.1.16.0.nupkg.sha512",
"Google.Apis.Core.nuspec", "Google.Apis.Core.nuspec",
"License.txt", "License.txt",
"lib/net45/Google.Apis.Core.dll", "lib/net45/Google.Apis.Core.dll",
@ -3305,6 +3317,24 @@
"lib/portable-net45+sl50+netcore45+wpa81+wp8/Google.Apis.Core.xml" "lib/portable-net45+sl50+netcore45+wpa81+wp8/Google.Apis.Core.xml"
] ]
}, },
"Google.Apis.Customsearch.v1/1.16.0.466": {
"sha512": "uZ5VP/xKgTZCMJXgEfwHYEIR/7FsbtvL+bncm08a07RhWLFZTdRpCAkNL4b5wADHkblpkBe1VWKv43W77I4tJw==",
"type": "package",
"path": "Google.Apis.Customsearch.v1/1.16.0.466",
"files": [
"Google.Apis.Customsearch.v1.1.16.0.466.nupkg.sha512",
"Google.Apis.Customsearch.v1.nuspec",
"lib/netstandard1.3/Google.Apis.Customsearch.v1.dll",
"lib/netstandard1.3/Google.Apis.Customsearch.v1.pdb",
"lib/netstandard1.3/Google.Apis.Customsearch.v1.xml",
"lib/portable-net40+sl50+netcore45+wpa81+wp8/Google.Apis.Customsearch.v1.dll",
"lib/portable-net40+sl50+netcore45+wpa81+wp8/Google.Apis.Customsearch.v1.pdb",
"lib/portable-net40+sl50+netcore45+wpa81+wp8/Google.Apis.Customsearch.v1.xml",
"lib/portable-net45+netcore45+wpa81+wp8/Google.Apis.Customsearch.v1.dll",
"lib/portable-net45+netcore45+wpa81+wp8/Google.Apis.Customsearch.v1.pdb",
"lib/portable-net45+netcore45+wpa81+wp8/Google.Apis.Customsearch.v1.xml"
]
},
"Google.Apis.Urlshortener.v1/1.15.0.138": { "Google.Apis.Urlshortener.v1/1.15.0.138": {
"sha512": "67USnpqrk8tWO3LAgaK9qDQT6h8A7i7eUIOKm+OISThZoQuHiLCn6dbg46FVb597LUh57AxClSSbhnweYcYC3Q==", "sha512": "67USnpqrk8tWO3LAgaK9qDQT6h8A7i7eUIOKm+OISThZoQuHiLCn6dbg46FVb597LUh57AxClSSbhnweYcYC3Q==",
"type": "package", "type": "package",
@ -9004,6 +9034,7 @@
"": [ "": [
"CoreCLR-NCalc >= 2.1.0", "CoreCLR-NCalc >= 2.1.0",
"Discord.Net.Commands >= 1.0.0-dev", "Discord.Net.Commands >= 1.0.0-dev",
"Google.Apis.Customsearch.v1 >= 1.16.0.466",
"Google.Apis.Urlshortener.v1 >= 1.15.0.138", "Google.Apis.Urlshortener.v1 >= 1.15.0.138",
"Google.Apis.YouTube.v3 >= 1.15.0.582", "Google.Apis.YouTube.v3 >= 1.15.0.582",
"Microsoft.EntityFrameworkCore >= 1.0.0", "Microsoft.EntityFrameworkCore >= 1.0.0",