[smuxi: 51/179] Engine(-IRC), Frontend-*: automatically start smuxi-server sessions (closes: #1067)



commit 1ac2edf80d28d0e72d24c0a99b7f10d13faaf3d0
Author: Mirco Bauer <meebey meebey net>
Date:   Sun May 22 13:21:00 2016 +0200

    Engine(-IRC), Frontend-*: automatically start smuxi-server sessions (closes: #1067)
    
    Immediately connect to auto-connect servers and execute on-startup commands when
    smuxi-server (and local) sessions are initialized. This way the user will be
    less offline, as a frontend is not required to connect first. The gap can be
    huge if a smuxi-server crashes for example.

 src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs |    3 -
 src/Engine/Session.cs                              |  163 ++++++++++---------
 src/Engine/SessionManager.cs                       |    5 +-
 src/Frontend-Curses/Frontend.cs                    |    2 +
 src/Frontend-GNOME/Frontend.cs                     |    2 +
 src/Frontend-STFL/Frontend.cs                      |    2 +
 src/Frontend-SWF/Frontend.cs                       |    2 +
 src/Frontend-Test/Frontend.cs                      |    2 +
 8 files changed, 100 insertions(+), 81 deletions(-)
---
diff --git a/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs 
b/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
index c3747d6..42c2657 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
@@ -327,9 +327,6 @@ namespace Smuxi.Engine
         {
             Trace.Call(fm, server);
 
-            if (fm == null) {
-                throw new ArgumentNullException("fm");
-            }
             if (server == null) {
                 throw new ArgumentNullException("server");
             }
diff --git a/src/Engine/Session.cs b/src/Engine/Session.cs
index 31417d6..9cd9fd4 100644
--- a/src/Engine/Session.cs
+++ b/src/Engine/Session.cs
@@ -58,6 +58,7 @@ namespace Smuxi.Engine
         DateTime NewsFeedLastModified { get; set; }
         TimeSpan NewsFeedUpdateInterval { get; set; }
         TimeSpan NewsFeedRetryInterval { get; set; }
+        bool IsFirstNewsFeedEntry { get; set; }
         internal MessageBuilderSettings MessageBuilderSettings { get; private set; }
 
         public event EventHandler<GroupChatPersonAddedEventArgs> GroupChatPersonAdded;
@@ -173,10 +174,87 @@ namespace Smuxi.Engine
             SeenNewsFeedIds = new List<string>();
             NewsFeedUpdateInterval = TimeSpan.FromHours(12);
             NewsFeedRetryInterval = TimeSpan.FromMinutes(5);
+            IsFirstNewsFeedEntry = true;
             NewsFeedTimer = new Timer(delegate { UpdateNewsFeed(); }, null,
                                       TimeSpan.Zero, NewsFeedUpdateInterval);
         }
 
+        public void ExecuteOnStartupCommands()
+        {
+            foreach (string command in (string[]) _UserConfig["OnStartupCommands"]) {
+                if (command.Length == 0) {
+                    continue;
+                }
+                var cd = new CommandModel(null, _SessionChat,
+                    (string)_UserConfig["Interface/Entry/CommandCharacter"],
+                    command);
+                var handled = Command(cd);
+                if (!handled) {
+#if LOG4NET
+                    f_Logger.Error("ExecuteOnStartupCommands(): command unknown: " + command);
+#endif
+                    var builder = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendErrorText("unknown command: {0}", command);
+                    AddMessageToChat(_SessionChat, builder.ToMessage(), true);
+                }
+            }
+        }
+
+        public void ProcessAutoConnect()
+        {
+            var serverCon = new ServerListController(_UserConfig);
+            IList<ServerModel> servers = serverCon.GetServerList();
+            foreach (ServerModel server in servers) {
+                if (!server.OnStartupConnect) {
+                    continue;
+                }
+
+                var msg = String.Format(
+                    _("Automatically connecting to {0}..."),
+                    String.Format("{0}/{1} ({2}:{3})", server.Protocol,
+                        server.Network, server.Hostname, server.Port)
+                );
+#if LOG4NET
+                f_Logger.Info(msg);
+#endif
+                var builder = CreateMessageBuilder().
+                    AppendEventPrefix().
+                    AppendText(msg);
+                AddMessageToChat(_SessionChat, builder.ToMessage(), true);
+
+                var srv = server;
+                // run connects in background threads as they block
+                ThreadPool.QueueUserWorkItem(delegate {
+                    bool isError = false;
+                    try {
+                        IProtocolManager protocolManager = Connect(srv, null);
+
+                        // if the connect command was correct, we should be
+                        // able to get the chat model
+                        if (protocolManager.Chat == null) {
+                            isError = true;
+                        }
+                    } catch (Exception ex) {
+#if LOG4NET
+                        f_Logger.Error("ProcessAutoConnect(): Exception during "+
+                            "automatic connect: ", ex);
+#endif
+                        isError = true;
+                    }
+                    if (isError) {
+                        builder = CreateMessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendErrorText(
+                            _("Automatic connect to {0} failed!"),
+                            srv.Hostname + ":" + srv.Port
+                        );
+                        AddMessageToChat(_SessionChat, builder.ToMessage(), true);
+                    }
+                });
+            }
+        }
+
         public IProtocolManager NextProtocolManager(IProtocolManager currentProtocolManager)
         {
             lock (_ProtocolManagers) {
@@ -222,75 +300,6 @@ namespace Smuxi.Engine
             lock (_FrontendManagers) {
                 _FrontendManagers[uri] = fm;
             }
-            
-            // if this is the first frontend, we process OnStartupCommands
-            if (!_OnStartupCommandsProcessed) {
-                _OnStartupCommandsProcessed = true;
-
-                foreach (string command in (string[])_UserConfig["OnStartupCommands"]) {
-                    if (command.Length == 0) {
-                        continue;
-                    }
-                    CommandModel cd = new CommandModel(fm, _SessionChat,
-                        (string)_UserConfig["Interface/Entry/CommandCharacter"],
-                        command);
-                    bool handled;
-                    handled = Command(cd);
-                    if (!handled) {
-                        if (fm.CurrentProtocolManager != null) {
-                            fm.CurrentProtocolManager.Command(cd);
-                        }
-                    }
-                }
-                
-                // process server specific connects/commands
-                ServerListController serverCon = new ServerListController(_UserConfig);
-                IList<ServerModel> servers = serverCon.GetServerList();
-                foreach (ServerModel server in servers) {
-                    if (!server.OnStartupConnect) {
-                        continue;
-                    }
-
-                    var msg = String.Format(
-                        _("Automatically connecting to {0}..."),
-                        String.Format("{0}/{1} ({2}:{3})", server.Protocol,
-                                      server.Network, server.Hostname, server.Port)
-                    );
-#if LOG4NET
-                    f_Logger.Info(msg);
-#endif
-                    fm.SetStatus(msg);
-
-                    var srv = server;
-                    // run connects in background threads as they block
-                    ThreadPool.QueueUserWorkItem(delegate {
-                        bool isError = false;
-                        try {
-                            IProtocolManager protocolManager = Connect(srv, fm);
-
-                            // if the connect command was correct, we should be
-                            // able to get the chat model
-                            if (protocolManager.Chat == null) {
-                                isError = true;
-                            }
-                        } catch (Exception ex) {
-#if LOG4NET
-                            f_Logger.Error("RegisterFrontendUI(): Exception during "+
-                                           "automatic connect: ", ex);
-#endif
-                            isError = true;
-                        }
-                        if (isError) {
-                            var builder = CreateMessageBuilder();
-                            builder.AppendErrorText(
-                                _("Automatic connect to {0} failed!"),
-                                srv.Hostname + ":" + srv.Port
-                            );
-                            fm.AddMessageToChat(_SessionChat, builder.ToMessage());
-                        }
-                    });
-                }
-            }
         }
         
         internal void DeregisterFrontendManager(FrontendManager fm)
@@ -1497,9 +1506,6 @@ namespace Smuxi.Engine
             if (String.IsNullOrEmpty(server.Protocol)) {
                 throw new ArgumentNullException("server.Protocol");
             }
-            if (frontendManager == null) {
-                throw new ArgumentNullException("frontendManager");
-            }
 
             IProtocolManager protocolManager = CreateProtocolManager(
                 server.Protocol
@@ -1533,7 +1539,7 @@ namespace Smuxi.Engine
                                     protocolManager.Command(cd);
                                 } catch (Exception ex) {
 #if LOG4NET
-                                    f_Logger.Error("Command in Connected event: Exception", ex);
+                                    f_Logger.Error("Connect(): Command in Connected event: Exception", ex);
 #endif
                                     var msg = CreateMessageBuilder().
                                         AppendErrorText("Command '{0}' failed. Reason: {1} ({2})",
@@ -1544,7 +1550,7 @@ namespace Smuxi.Engine
                             }
                         } catch (Exception ex) {
 #if LOG4NET
-                            f_Logger.Error("Connected event: Exception", ex);
+                            f_Logger.Error("Connect(): Connected event: Exception", ex);
 #endif
                         }
                     });
@@ -1929,9 +1935,6 @@ namespace Smuxi.Engine
             builder.AppendText(text);
             builder.AppendText(Environment.NewLine);
 
-            builder.AppendText(Environment.NewLine);
-
-            builder.AppendHeader("Smuxi News");
             AddMessageToChat(_SessionChat,builder.ToMessage());
         }
 
@@ -1970,6 +1973,12 @@ namespace Smuxi.Engine
                     SeenNewsFeedIds.Add(entry.Id);
 
                     var msg = new FeedMessageBuilder();
+                    if (IsFirstNewsFeedEntry) {
+                        IsFirstNewsFeedEntry = false;
+                        msg.AppendText("\n");
+                        msg.AppendHeader("Smuxi News");
+                        msg.AppendText("\n");
+                    }
                     msg.Append(entry);
                     if (!msg.IsEmpty) {
                         msg.AppendText("\n");
diff --git a/src/Engine/SessionManager.cs b/src/Engine/SessionManager.cs
index d281036..21011de 100644
--- a/src/Engine/SessionManager.cs
+++ b/src/Engine/SessionManager.cs
@@ -77,7 +77,10 @@ namespace Smuxi.Engine
 #if LOG4NET
                 _Logger.Debug("Creating Session for User "+user);
 #endif
-                _Sessions.Add(user, new Session(_Config, _ProtocolManagerFactory, user));
+                var session = new Session(_Config, _ProtocolManagerFactory, user);
+                session.ExecuteOnStartupCommands();
+                session.ProcessAutoConnect();
+                _Sessions.Add(user, session);
             }
         }
         
diff --git a/src/Frontend-Curses/Frontend.cs b/src/Frontend-Curses/Frontend.cs
index 8e749cc..b1835c5 100644
--- a/src/Frontend-Curses/Frontend.cs
+++ b/src/Frontend-Curses/Frontend.cs
@@ -179,6 +179,8 @@ namespace Smuxi.Frontend.Curses
             _Session = new Engine.Session(Engine.Engine.Config,
                                           Engine.Engine.ProtocolManagerFactory,
                                           "local");
+            _Session.ExecuteOnStartupCommands();
+            _Session.ProcessAutoConnect();
             _Session.RegisterFrontendUI(_MainWindow.UI);
             _UserConfig = _Session.UserConfig;
             ConnectEngineToGUI();
diff --git a/src/Frontend-GNOME/Frontend.cs b/src/Frontend-GNOME/Frontend.cs
index 9bd9730..54274ee 100644
--- a/src/Frontend-GNOME/Frontend.cs
+++ b/src/Frontend-GNOME/Frontend.cs
@@ -277,6 +277,8 @@ namespace Smuxi.Frontend.Gnome
                 _LocalSession = new Engine.Session(Engine.Engine.Config,
                                                    Engine.Engine.ProtocolManagerFactory,
                                                    "local");
+                _LocalSession.ExecuteOnStartupCommands();
+                _LocalSession.ProcessAutoConnect();
             }
             EngineAssemblyVersion = Engine.Engine.AssemblyVersion;
             EngineProtocolVersion = Engine.Engine.ProtocolVersion;
diff --git a/src/Frontend-STFL/Frontend.cs b/src/Frontend-STFL/Frontend.cs
index 507a14c..86d39aa 100644
--- a/src/Frontend-STFL/Frontend.cs
+++ b/src/Frontend-STFL/Frontend.cs
@@ -177,6 +177,8 @@ namespace Smuxi.Frontend.Stfl
                                          Engine.Engine.ProtocolManagerFactory,
                                          "local");
             Session = _LocalSession;
+            Session.ExecuteOnStartupCommands();
+            Session.ProcessAutoConnect();
             Session.RegisterFrontendUI(_MainWindow.UI);
             _UserConfig = Session.UserConfig;
             ConnectEngineToGUI();
diff --git a/src/Frontend-SWF/Frontend.cs b/src/Frontend-SWF/Frontend.cs
index 218de2c..1905e00 100644
--- a/src/Frontend-SWF/Frontend.cs
+++ b/src/Frontend-SWF/Frontend.cs
@@ -186,6 +186,8 @@ namespace Smuxi.Frontend.Swf
             _Session = new Engine.Session(Engine.Engine.Config,
                                           Engine.Engine.ProtocolManagerFactory,
                                           "local");
+            _Session.ExecuteOnStartupCommands();
+            _Session.ProcessAutoConnect();
             _Session.RegisterFrontendUI(_MainWindow.UI);
             _UserConfig = _Session.UserConfig;
             ConnectEngineToGUI();
diff --git a/src/Frontend-Test/Frontend.cs b/src/Frontend-Test/Frontend.cs
index a08f424..aaeda72 100644
--- a/src/Frontend-Test/Frontend.cs
+++ b/src/Frontend-Test/Frontend.cs
@@ -104,6 +104,8 @@ namespace Smuxi.FrontendTest
                 session = new Engine.Session(Engine.Engine.Config,
                                              Engine.Engine.ProtocolManagerFactory,
                                              "local");
+                session.ExecuteOnStartupCommands();
+                session.ProcessAutoConnect();
                 session.RegisterFrontendUI(ui);
             } else {
                 // remote engine


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]