2017-04-16 22:46:29 +02:00
using System ;
using System.Globalization ;
using System.IO ;
using System.Linq ;
using System.Runtime ;
using System.Runtime.Remoting.Channels ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
using Discord ;
using Discord.Net ;
2017-09-25 19:50:59 +02:00
using Discord.WebSocket ;
2017-04-16 22:46:29 +02:00
using DML.Application.Classes ;
using DML.Application.Dialogs ;
using LiteDB ;
2017-04-17 14:39:29 +02:00
using SweetLib.Utils ;
2017-04-16 22:46:29 +02:00
using SweetLib.Utils.Logger ;
using SweetLib.Utils.Logger.Memory ;
using static SweetLib . Utils . Logger . Logger ;
2017-04-16 17:57:27 +02:00
namespace DML.Application
{
2017-04-16 22:46:29 +02:00
public static class Core
2017-04-16 17:57:27 +02:00
{
2017-09-25 19:50:59 +02:00
internal static DiscordSocketClient Client { get ; set ; }
2017-04-16 22:46:29 +02:00
internal static LiteDatabase Database { get ; set ; }
internal static Settings Settings { get ; set ; }
2017-04-17 21:56:53 +02:00
internal static JobScheduler Scheduler { get ; } = new JobScheduler ( ) ;
2017-04-16 17:57:27 +02:00
2017-04-16 22:46:29 +02:00
internal static string DataDirectory
= > Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) , @"Serraniel\Discord Media Loader" ) ;
public static async Task Run ( string [ ] paramStrings )
2017-04-16 17:57:27 +02:00
{
2017-04-16 22:46:29 +02:00
try
{
2017-04-30 11:06:10 +02:00
var splash = new FrmInternalSplash ( ) ;
splash . Show ( ) ;
System . Windows . Forms . Application . DoEvents ( ) ;
2017-04-16 22:46:29 +02:00
Info ( "Starting up Discord Media Loader application..." ) ;
var useTrace = false ;
#if DEBUG
//temporary add debug log level if debugging...
GlobalLogLevel | = LogLevel . Debug ;
Debug ( "Running in debug configuartion. Added log level debug." ) ;
#endif
Debug ( $"Parameters: {string.Join(" , ", paramStrings)}" ) ;
if ( paramStrings . Contains ( "--trace" ) | | paramStrings . Contains ( "-t" ) )
{
useTrace = true ;
GlobalLogLevel | = LogLevel . Trace ;
Trace ( "Trace parameter found. Added log level trace." ) ;
}
Debug ( $"Application data folder: {DataDirectory}" ) ;
Trace ( "Checking application data folder..." ) ;
if ( ! Directory . Exists ( DataDirectory ) )
{
Debug ( "Creating application data folder..." ) ;
Directory . CreateDirectory ( DataDirectory ) ;
Trace ( "Creating application data folder." ) ;
}
Trace ( "Initializing profile optimizations..." ) ;
ProfileOptimization . SetProfileRoot ( System . Windows . Forms . Application . UserAppDataPath ) ;
ProfileOptimization . StartProfile ( "profile.opt" ) ;
Trace ( "Finished initializing profile optimizations." ) ;
Trace ( "Trying to identify log memory..." ) ;
var logMemory = DefaultLogMemory as ArchivableConsoleLogMemory ;
if ( logMemory ! = null )
{
var logFolder = Path . Combine ( DataDirectory , "logs" ) ;
if ( ! Directory . Exists ( logFolder ) )
{
Debug ( "Creating log folder..." ) ;
Directory . CreateDirectory ( logFolder ) ;
Trace ( "Created log folder." ) ;
}
var logFile = Path . Combine ( logFolder ,
2017-04-17 14:39:29 +02:00
SweetUtils . LegalizeFilename ( $"{DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.SortableDateTimePattern)}.log.zip" ) ) ;
2017-04-16 22:46:29 +02:00
Trace ( $"Setting log file: {logFile}" ) ;
logMemory . AutoArchiveOnDispose = true ;
logMemory . ArchiveFile = logFile ;
}
Debug ( "Loading database..." ) ;
Database = new LiteDatabase ( Path . Combine ( DataDirectory , "config.db" ) ) ;
Database . Log . Logging + = ( message ) = > Trace ( $"LiteDB: {message}" ) ;
Debug ( "Loading settings collection out of database..." ) ;
var settingsDB = Database . GetCollection < Settings > ( "settings" ) ;
if ( settingsDB . Count ( ) > 1 )
{
Warn ( "Found more than one setting. Loading first one..." ) ;
}
Settings = settingsDB . FindAll ( ) . FirstOrDefault ( ) ;
if ( Settings = = null )
{
Warn ( "Settings not found. Creating new one. This is normal on first start up..." ) ;
Settings = new Settings ( ) ;
Settings . Store ( ) ;
}
2017-04-17 21:56:53 +02:00
Debug ( "Loading jobs collection out of database..." ) ;
Scheduler . JobList = Job . RestoreJobs ( ) . ToList ( ) ;
2017-04-16 22:46:29 +02:00
Info ( "Loaded settings." ) ;
Debug (
$"Settings: Email: {Settings.Email}, password: {(string.IsNullOrEmpty(Settings.Password) ? " not set " : " is set ")}, use username: {Settings.UseUserData}, loginToken: {Settings.LoginToken}" ) ;
Trace ( "Updating log level..." ) ;
GlobalLogLevel = Settings . ApplicactionLogLevel ;
#if DEBUG
//temporary add debug log level if debugging...
GlobalLogLevel | = LogLevel . Debug ;
Debug ( "Running in debug configuartion. Added log level debug." ) ;
#endif
if ( useTrace )
{
GlobalLogLevel | = LogLevel . Trace ;
Trace ( "Creating application data folder." ) ;
}
Debug ( "Creating discord client..." ) ;
2017-09-25 19:50:59 +02:00
Client = new DiscordSocketClient ( ) ;
Client . Log + = ( arg ) = >
2017-04-16 22:46:29 +02:00
{
2017-09-25 19:50:59 +02:00
var logMessage = $"DiscordClient: {arg.Message}" ;
switch ( arg . Severity )
2017-04-16 22:46:29 +02:00
{
case LogSeverity . Verbose :
Trace ( logMessage ) ;
break ;
case LogSeverity . Debug :
Trace ( logMessage ) ;
break ;
case LogSeverity . Info :
Info ( logMessage ) ;
break ;
case LogSeverity . Warning :
Warn ( logMessage ) ;
break ;
case LogSeverity . Error :
Error ( logMessage ) ;
break ;
}
2017-09-25 19:50:59 +02:00
return Task . CompletedTask ;
2017-04-16 22:46:29 +02:00
} ;
Info ( "Trying to log into discord..." ) ;
var abort = false ;
2017-09-25 19:50:59 +02:00
Client . Connected + = Client_Connected ;
while ( Client . LoginState ! = LoginState . LoggedIn & & ! abort )
2017-04-16 22:46:29 +02:00
{
2017-09-25 19:50:59 +02:00
Debug ( Client . ConnectionState . ToString ( ) ) ;
Debug ( Client . LoginState . ToString ( ) ) ;
2017-04-16 22:46:29 +02:00
2017-09-25 19:50:59 +02:00
Trace ( "Entering login loop." ) ;
2017-04-16 22:46:29 +02:00
try
{
2017-09-25 19:50:59 +02:00
if ( Client . ConnectionState = = ConnectionState . Connecting )
continue ;
2017-04-16 22:46:29 +02:00
if ( ! string . IsNullOrEmpty ( Settings . LoginToken ) )
{
Debug ( "Trying to login with last known token..." ) ;
2017-09-25 19:50:59 +02:00
await Client . LoginAsync ( TokenType . User , Settings . LoginToken ) ;
await Task . Delay ( 1000 ) ;
2017-04-16 22:46:29 +02:00
}
}
2017-09-25 19:50:59 +02:00
catch ( HttpException ex )
2017-04-16 22:46:29 +02:00
{
2017-09-25 19:50:59 +02:00
Warn ( $"Login seems to have failed or gone wrong: {ex.GetType().Name} - {ex.Message}" ) ;
2017-04-16 22:46:29 +02:00
}
2017-09-25 19:50:59 +02:00
if ( Client . LoginState = = LoginState . LoggedOut )
2017-04-16 22:46:29 +02:00
{
Settings . Password = string . Empty ;
Debug ( "Showing dialog for username and password..." ) ;
var loginDlg = new LoginDialog ( ) ;
loginDlg . ShowDialog ( ) ;
Trace ( "Dialog closed." ) ;
}
}
2017-04-17 21:56:53 +02:00
2017-05-04 15:24:04 +02:00
Debug ( "Start checking for invalid jobs..." ) ;
2017-09-25 19:50:59 +02:00
//Client
while ( Client . Guilds . Count = = 0 )
{
// wait until guilds are loaded
}
2017-05-04 15:24:04 +02:00
for ( var i = Scheduler . JobList . Count - 1 ; i > = 0 ; i - - )
{
var job = Scheduler . JobList [ i ] ;
var isError = false ;
var guild = FindServerById ( job . GuildId ) ;
if ( guild = = null )
isError = true ;
else
{
var channel = FindChannelById ( guild , job . ChannelId ) ;
if ( channel = = null )
isError = true ;
}
if ( isError )
{
MessageBox . Show ( $"Invalid job for guild {job.GuildId}, channel {job.ChannelId} found. Guild or channel may not exist any more. This job will be deleted..." , "Invalid job" ,
MessageBoxButtons . OK , MessageBoxIcon . Warning ) ;
Scheduler . JobList . Remove ( job ) ;
Scheduler . RunningJobs . Remove ( job . Id ) ;
job . Stop ( ) ;
job . Delete ( ) ;
}
}
2017-04-30 11:06:10 +02:00
splash . Close ( ) ;
2017-04-17 21:56:53 +02:00
Info ( "Starting scheduler..." ) ;
Scheduler . Start ( ) ;
2017-04-16 22:46:29 +02:00
System . Windows . Forms . Application . Run ( new MainForm ( ) ) ;
2017-04-17 21:56:53 +02:00
Info ( "Stopping scheduler..." ) ;
Scheduler . Stop ( ) ;
2017-04-16 22:46:29 +02:00
}
catch ( Exception ex )
{
Error ( $"{ex.Message} occured at: {ex.StackTrace}" ) ;
}
2017-04-16 17:57:27 +02:00
}
2017-05-04 15:24:04 +02:00
2017-09-25 19:50:59 +02:00
private static Task Client_Connected ( )
{
Debug ( "Connected" ) ;
return Task . CompletedTask ;
}
2017-05-04 15:24:04 +02:00
//TODO: this is thrid time we implement this.....this has to be fixed!!!
2017-09-25 19:50:59 +02:00
private static SocketGuild FindServerById ( ulong id )
2017-05-04 15:24:04 +02:00
{
Trace ( $"Trying to find server by Id: {id}" ) ;
2017-09-25 19:50:59 +02:00
return ( from s in Core . Client . Guilds where s . Id = = id select s ) . FirstOrDefault ( ) ;
2017-05-04 15:24:04 +02:00
}
2017-09-25 19:50:59 +02:00
private static SocketTextChannel FindChannelById ( SocketGuild server , ulong id )
2017-05-04 15:24:04 +02:00
{
Trace ( $"Trying to find channel in {server} by id: {id}" ) ;
return ( from c in server . TextChannels where c . Id = = id select c ) . FirstOrDefault ( ) ;
}
2017-04-16 17:57:27 +02:00
}
}