using System; using System.Collections.Generic; using System.Linq; using System.Text; using Perforce.P4; using log4net; using log4net.Appender; using log4net.Config; namespace P4NetContentTrigger { // Class to wrap P4API.NET, adding logging to it. class P4Interface { private string _p4port; private string _p4user; private Server _Server; public Repository repo; private static readonly ILog _log = LogManager.GetLogger(typeof(P4Interface)); public P4Interface(string p4port, string p4user) { _p4port = p4port; _p4user = p4user; } public bool Connect() { _log.DebugFormat("Specified P4Port: '{0}' p4user: '{1}'", _p4port, _p4user); _Server = new Server(new ServerAddress(_p4port)); repo = new Repository(_Server); repo.Connection.UserName = _p4user; Options options = new Options(); options["Password"] = ""; if (repo.Connection.Connect(options)) { _log.DebugFormat("Connected P4Port: '{0}' p4user: '{1}'", repo.Server.Address, repo.Connection.UserName); repo.Connection.InfoResultsReceived += CommandLine_InfoResultsCallbackFn; repo.Connection.ErrorReceived += CommandLine_ErrorCallbackFn; repo.Connection.TextResultsReceived += CommandLine_TextResultsCallbackFn; repo.Connection.TaggedOutputReceived += CommandLine_TaggedOutputCallbackFn; repo.Connection.CommandEcho += CommandLine_CommandEchoCallbackFn; return true; } else { _log.Error("Failed to connect"); return false; } } #region Logging stuff // How to log all P4API.NET calls public static void LoggingFunction(int log_level, String source, String message) { if (!_log.IsDebugEnabled) return; _log.DebugFormat("{0}:{1}:{2}", log_level, source, message); } private static void LogP4Exception(P4Exception p4e) { _log.WarnFormat("Exception: {0}", p4e.Message); } static string[] ErrorSeverity = new string[] { "Empty", "Info", "Warning", "Failed", "Fatal" }; static int[] MessageSeverity = new int[] { 4, //"E_EMPTY", 3, //"E_INFO", 2, //"E_WARN", 1, //"E_FAILED", 0 //"E_FATAL", }; private void CommandLine_ErrorCallbackFn(uint cmdId, int severity, int errorNumber, string data) { try { string severityStr = string.Empty; if ((severity < 0) || (severity >= ErrorSeverity.Length)) { severityStr = string.Format("E_{0}", severity); } else { severityStr = ErrorSeverity[severity]; } string msg = string.Format("{0}: {1}", severityStr, data); if (_log.IsDebugEnabled) { } if ((severity < 0) || (severity >= ErrorSeverity.Length)) { LoggingFunction(0, "P4API.NET", msg); } else { LoggingFunction(MessageSeverity[severity], "P4API.NET", msg); } } catch (Exception ex) { string msg = string.Format("Error trying to log message: [{0}]: {1}", severity, data); LoggingFunction(0, "P4API.NET", msg); _log.Error(ex.Message); _log.Error(ex.StackTrace); } } private void CommandLine_InfoResultsCallbackFn(uint cmdId, int msgId, int level, string data) { if (_log.IsDebugEnabled) { // level is generally from 0-9, though for some reason trying to add an // ignored file sends a message with a level of 34, so ignor level of 34 if (level == 34) { level = 0; } try { string msg = "--->"; for (int idx = 0; idx < level; idx++) { msg += ". "; } msg += (data != null) ? data : string.Empty; LoggingFunction(3, "P4API.NET", msg); } catch (Exception ex) { _log.Error(ex.Message); _log.Error(ex.StackTrace); } } } private void CommandLine_TaggedOutputCallbackFn(uint cmdId, int ObjId, Perforce.P4.TaggedObject Obj) { if (_log.IsDebugEnabled) { try { if (Obj == null) { return; } string msg = "--->Tagged Data: { "; foreach (string key in Obj.Keys) { msg += string.Format("{{{0}:{1}}} ", key, Obj[key]); } msg += "}"; LoggingFunction(3, "P4API.NET", msg); } catch (Exception ex) { _log.Error(ex.Message); _log.Error(ex.StackTrace); } } } private void CommandLine_TextResultsCallbackFn(uint cmdId, string data) { if (_log.IsDebugEnabled) { string msg = string.Format("->{0}", data); LoggingFunction(3, "P4API.NET", msg); } } private void CommandLine_CommandEchoCallbackFn(string data) { if (data.StartsWith("DataSet set to:")) { // echoing the commands data set, record this only to the log file. LoggingFunction(3, "P4API.NET", data); return; } string[] cmds = data.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); string cmd = cmds[0]; bool log = false; switch (cmd) { case "depot": case "client": case "workspace": case "user": case "group": case "changelist": case "change": case "job": case "branch": case "label": case "remote": case "stream": case "server": case "protect": case "triggers": if ((data.IndexOf(" -i ") > 0) || (data.EndsWith(" -i")) || (data.IndexOf(" -d ") > 0) || (data.EndsWith(" -d"))) { log = true; } break; default: log = true; break; } if (log && _log.IsDebugEnabled) { string msg = string.Format("->{0}", data); LoggingFunction(3, "P4API.NET", msg); return; } } #endregion } }