using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Windows.Forms; using System.IO; using ETHZurich.OrigoVSIntegration.Workitems; using ETHZurich.OrigoVSIntegration.Dialogs; namespace ETHZurich.OrigoVSIntegration { class OrigoProject { public int id; public string name; public bool isOwned; public OrigoProject() { id = -1; name = Constants.projGlobNoProj; isOwned = false; } public OrigoProject(int a_id, string a_name, bool a_isOwned) { id = a_id; name = a_name; isOwned = a_isOwned; } public override string ToString() { return name; } }; class XmlRpcCalls { #region -------------------- Members ------------------------------------ public OrigoSettings m_OrigoSettings; #endregion ----------------- End Members -------------------------------- //*********************************************************************** #region -------------------- Initialisation ----------------------------- public XmlRpcCalls(OrigoSettings a_OrigoSettings) { if (a_OrigoSettings == null) { throw new ArgumentNullException("a_OrigoSettings"); } m_OrigoSettings = a_OrigoSettings; } #endregion ----------------- End Initialisation ------------------------- //*********************************************************************** #region -------------------- XML RPC Calls ------------------------------ public string Login() { //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "login -uk " + m_OrigoSettings.OrigoKey + " -ak " + Constants.applicationKey; process.Start(); string session = ""; string error = ""; ReadStandardStreams(process, ref session, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during login:\n" + error); } //return the session return session; } //----------------------------------------------------------------------- //get the username which belongs to the session public string MyUsername(string a_session) { if (a_session == null) { throw new ArgumentNullException("An argument of MyUsername was null."); } //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "my_name -s " + a_session; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during my_username:\n" + error); } //return the username return stdout; } //----------------------------------------------------------------------- //get the username which belongs to the session public string MyPassword(string a_session) { if (a_session == null) { throw new ArgumentNullException("An argument of MyPassword was null."); } //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "my_password -s " + a_session; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during my_password:\n" + error); } //return the password return stdout; } //----------------------------------------------------------------------- //returns list of projects a user is developer or owner of //a project is represented as a key value pair where the key is the project id and the value the project name public List ProjectListOfUser(string a_session, string a_username) { if (a_session == null || a_username == null) { throw new ArgumentNullException("An argument of ProjectListOfUser was null."); } //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "project_list_of_user -s " + a_session + " -u " + a_username; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during project_list_of_user:\n" + error); } //return the project list List projectList = new List(); char[] seperators = new char[1]; seperators[0] = '\t'; OrigoProject project; string[] stringParts; while (!stdout.Equals(string.Empty)) { stringParts = ReadStringUntil(ref stdout, '\n').Split(seperators); project = new OrigoProject(int.Parse(stringParts[0]), stringParts[1], stringParts[2].Equals("3")); projectList.Add(project); } process.Dispose(); return projectList; } //----------------------------------------------------------------------- public void Release(string a_session, ListView a_list, ReleaseDialog a_dialog, int a_projectId) { if (a_session == null || a_list == null || a_dialog == null) { throw new ArgumentNullException("An argument of MyPassword was null."); } else if (a_projectId <= 0) { throw new ArgumentException("a_project_id must be a positive number."); } string fileList = ""; ListViewGroup group; //a_list.Groups[0] is the group of the files which are not released for (int i = 1; i < a_list.Groups.Count; i++) { group = a_list.Groups[i]; for (int j = 0; j < group.Items.Count; j++) { fileList += group.Items[j].Text + ":" + group.Name + ";"; } } char[] trimChars = new char[1]; trimChars[0] = ';'; fileList = fileList.TrimEnd(trimChars); //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "release -s " + a_session; process.StartInfo.Arguments += " -pid " + a_projectId.ToString(); process.StartInfo.Arguments += " -n \"" + a_dialog.ReleaseName + "\""; if (!a_dialog.ReleaseDescription.Equals(string.Empty)) { process.StartInfo.Arguments += " -d \"" + a_dialog.ReleaseDescription + "\""; } process.StartInfo.Arguments += " -ver \"" + a_dialog.ReleaseVersion + "\""; process.StartInfo.Arguments += " -fl \"" + fileList + "\""; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during release:\n" + error); } return; } //----------------------------------------------------------------------- //returns list of workitems of the last days public List WorkitemList(string a_session, int a_number, bool a_unread_only) { if (a_session == null) { throw new ArgumentNullException("An argument of ProjectListOfUser was null."); } else if (a_number <= 0) { throw new ArgumentException("a_number must be positive"); } try { //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "workitem_list -s " + a_session + " -num " + a_number.ToString(); if (a_unread_only) { process.StartInfo.Arguments += " -uro"; } process.Start(); string stdout = ""; string stderror = ""; ReadStandardStreams(process, ref stdout, ref stderror); process.Dispose(); //check if an error occurred if (!stderror.Equals(string.Empty)) { throw new ApplicationException("Error during workitem_list:\n" + stderror); } //return the workitem list List workitemList = new List(); Workitem workitem; string line; int type; while (!stdout.Equals(string.Empty)) { line = ReadStringUntil(ref stdout, '\n'); type = int.Parse(line); switch (type) { case Constants.WorkitemTypeIssue: workitem = ReadIssueWorkitem(ref stdout, false); break; case Constants.WorkitemTypeRelease: workitem = ReadReleaseWorkitem(ref stdout, false); break; case Constants.WorkitemTypeCommit: workitem = ReadCommitWorkitem(ref stdout, false); break; case Constants.WorkitemTypeWiki: workitem = ReadWikiWorkitem(ref stdout, false); break; case Constants.WorkitemTypeBlog: workitem = ReadBlogWorkitem(ref stdout, false); break; case Constants.WorkitemTypeComment: workitem = ReadCommentWorkitem(ref stdout, false); break; default: workitem = new Workitem(); FillGeneralWorkitem(workitem, ref stdout); workitem.type = type; break; } workitemList.Add(workitem); //skip the empty line between workitems line = ReadStringUntil(ref stdout, '\n'); Debug.Assert(line.Equals(string.Empty)); } return workitemList; } catch (Exception e) { throw new ApplicationException("Exception during WorkitemList:\n" + e.Message); } } //----------------------------------------------------------------------- //returns details of a given workitem public Workitem WorkitemDetails(string a_session, int a_workitem_id) { if (a_session == null) { throw new ArgumentNullException("An argument of ProjectListOfUser was null."); } else if (a_workitem_id <= 0) { throw new ArgumentException("a_workitem_id must be positive"); } try { //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "workitem -s " + a_session + " -w " + a_workitem_id.ToString(); process.Start(); string stdout = ""; string stderror = ""; ReadStandardStreams(process, ref stdout, ref stderror); process.Dispose(); //check if an error occurred if (!stderror.Equals(string.Empty)) { throw new ApplicationException("Error during workitem:\n" + stderror); } //return the workitem list Workitem workitem; string line; int type; line = ReadStringUntil(ref stdout, '\n'); type = int.Parse(line); switch (type) { case Constants.WorkitemTypeIssue: workitem = ReadIssueWorkitem(ref stdout, true); break; case Constants.WorkitemTypeRelease: workitem = ReadReleaseWorkitem(ref stdout, true); break; case Constants.WorkitemTypeCommit: workitem = ReadCommitWorkitem(ref stdout, true); break; case Constants.WorkitemTypeWiki: workitem = ReadWikiWorkitem(ref stdout, true); break; case Constants.WorkitemTypeBlog: workitem = ReadBlogWorkitem(ref stdout, true); break; case Constants.WorkitemTypeComment: workitem = ReadCommentWorkitem(ref stdout, true); break; default: workitem = new Workitem(); FillGeneralWorkitem(workitem, ref stdout); workitem.type = type; break; } Debug.Assert(stdout.Equals(string.Empty)); return workitem; } catch (Exception e) { throw new ApplicationException("Exception during WorkitemDetails:\n" + e.Message); } } //----------------------------------------------------------------------- public List FtpFileList(string a_username, string a_password) { if (a_username == null || a_password == null) { throw new ArgumentNullException("An argument of FtpFileList was null."); } //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "ftp_file_list -p " + a_password + " -u " + a_username; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during ftp_file_list:\n" + error); } //return the file list List fileList = new List(); while (!stdout.Equals(string.Empty)) { fileList.Add(ReadStringUntil(ref stdout, '\n')); } return fileList; } //----------------------------------------------------------------------- public void FtpUpload(string a_username, string a_password, string a_filename) { if (a_username == null || a_password == null || a_filename == null) { throw new ArgumentNullException("An argument of FtpDelete was null"); } //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "ftp_upload -p " + a_password + " -u " + a_username + " -f \"" + a_filename + "\""; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during ftp_file_list:\n" + error); } } //----------------------------------------------------------------------- public void FtpDelete(string a_username, string a_password, string a_filename) { if (a_username == null || a_password == null || a_filename == null) { throw new ArgumentNullException("An argument of FtpDelete was null"); } //create the process and start it Process process = InitProcess(); process.StartInfo.Arguments = "ftp_delete -p " + a_password + " -u " + a_username + " -f " + a_filename; process.Start(); string stdout = ""; string error = ""; ReadStandardStreams(process, ref stdout, ref error); process.Dispose(); //check if an error occurred if (!error.Equals(string.Empty)) { throw new ApplicationException("Error during ftp_file_list:\n" + error); } } #endregion ----------------- End XML RPC Calls -------------------------- //*********************************************************************** #region -------------------- Other Methods ------------------------------ private Process InitProcess() { Process process = new System.Diagnostics.Process(); process.StartInfo.FileName = m_OrigoSettings.ClientPath; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; return process; } //----------------------------------------------------------------------- private void ReadStandardStreams(Process a_process, ref string stdout, ref string stderror) { stdout = ""; stderror = ""; while (!a_process.HasExited) { stdout += a_process.StandardOutput.ReadToEnd(); stderror = a_process.StandardError.ReadToEnd(); } stdout += a_process.StandardOutput.ReadToEnd(); stderror += a_process.StandardError.ReadToEnd(); stdout = stdout.Replace("\r", ""); stderror = stderror.Replace("\r", ""); } //----------------------------------------------------------------------- private string ReadStringUntil(ref string a_string, char a_separator) { int index = a_string.IndexOf(a_separator); string result; //the character was not found if (index == -1) { result = a_string; a_string = ""; } else { result = a_string.Substring(0, index); a_string = a_string.Remove(0, index + 1); } return result; } //----------------------------------------------------------------------- private string ReadTextBlock(ref string a_string) { //read text block, to do that you first have to read the length of the text which is terminated by ':' int length = int.Parse(ReadStringUntil(ref a_string, ':')); string text = a_string.Substring(0, length); a_string = a_string.Remove(0, length); //read the terminating \n string emptyLine = ReadStringUntil(ref a_string, '\n'); Debug.Assert(emptyLine.Equals(string.Empty)); return text; } //----------------------------------------------------------------------- private IssueWorkitem ReadIssueWorkitem(ref string a_string, bool readDetails) { IssueWorkitem workitem = new IssueWorkitem(); FillGeneralWorkitem(workitem, ref a_string); workitem.projectIssueId = int.Parse(ReadStringUntil(ref a_string, '\n')); workitem.title = ReadStringUntil(ref a_string, '\n'); workitem.description = ReadTextBlock(ref a_string); workitem.url = ReadStringUntil(ref a_string, '\n'); workitem.links.Add(new LinkLabel.Link(0, 0, workitem.url)); workitem.isNew = ReadStringUntil(ref a_string, '\n').Equals("1"); if (readDetails) { workitem.isDetailed = true; } return workitem; } //----------------------------------------------------------------------- private ReleaseWorkitem ReadReleaseWorkitem(ref string a_string, bool readDetails) { ReleaseWorkitem workitem = new ReleaseWorkitem(); FillGeneralWorkitem(workitem, ref a_string); workitem.name = ReadStringUntil(ref a_string, '\n'); workitem.version = ReadStringUntil(ref a_string, '\n'); workitem.description = ReadTextBlock(ref a_string); if (readDetails) { workitem.isDetailed = true; int fileCount = int.Parse(ReadStringUntil(ref a_string, '\n')); string[] parts; char[] separator = { ':' }; workitem.platforms = new List(); workitem.files = new Dictionary>(); for (int i = 0; i < fileCount; i++) { //parts[0] is the filename and parts[1] the platform parts = ReadStringUntil(ref a_string, '\n').Split(separator); Debug.Assert(parts.Length == 2); //check if it's the first file of this platform and add the necessary data if (!workitem.files.ContainsKey(parts[1])) { workitem.platforms.Add(parts[1]); workitem.files.Add(parts[1], new List()); } workitem.files[parts[1]].Add(parts[0]); } } return workitem; } //----------------------------------------------------------------------- private CommitWorkitem ReadCommitWorkitem(ref string a_string, bool readDetails) { CommitWorkitem workitem = new CommitWorkitem(); FillGeneralWorkitem(workitem, ref a_string); //read commit specific data workitem.revision = int.Parse(ReadStringUntil(ref a_string, '\n')); workitem.log = ReadTextBlock(ref a_string); if (readDetails) { workitem.isDetailed = true; workitem.diff = ReadTextBlock(ref a_string); } return workitem; } //----------------------------------------------------------------------- private WikiWorkitem ReadWikiWorkitem(ref string a_string, bool readDetails) { WikiWorkitem workitem = new WikiWorkitem(); FillGeneralWorkitem(workitem, ref a_string); workitem.title = ReadStringUntil(ref a_string, '\n'); workitem.links.Add(new LinkLabel.Link(0, 0, ReadStringUntil(ref a_string, '\n'))); //check if it's a new entry or a page change string diffUrl = ReadStringUntil(ref a_string, '\n'); if (diffUrl.Equals(string.Empty)) { workitem.isNew = true; } else { workitem.isNew = false; workitem.links.Add(new LinkLabel.Link(0, 0, diffUrl)); } if (readDetails) { workitem.isDetailed = true; workitem.revision = int.Parse(ReadStringUntil(ref a_string, '\n')); workitem.oldRevision = int.Parse(ReadStringUntil(ref a_string, '\n')); workitem.diff = ReadTextBlock(ref a_string); } return workitem; } //----------------------------------------------------------------------- private BlogWorkitem ReadBlogWorkitem(ref string a_string, bool readDetails) { BlogWorkitem workitem = new BlogWorkitem(); FillGeneralWorkitem(workitem, ref a_string); workitem.title = ReadStringUntil(ref a_string, '\n'); workitem.links.Add(new LinkLabel.Link(0, 0, ReadStringUntil(ref a_string, '\n'))); //check if it's a new entry or a page change string diffUrl = ReadStringUntil(ref a_string, '\n'); if (diffUrl.Equals(string.Empty)) { workitem.isNew = true; } else { workitem.isNew = false; workitem.links.Add(new LinkLabel.Link(0, 0, diffUrl)); } if (readDetails) { workitem.isDetailed = true; workitem.revision = int.Parse(ReadStringUntil(ref a_string, '\n')); workitem.oldRevision = int.Parse(ReadStringUntil(ref a_string, '\n')); workitem.diff = ReadTextBlock(ref a_string); } return workitem; } //----------------------------------------------------------------------- private CommentWorkitem ReadCommentWorkitem(ref string a_string, bool readDetails) { CommentWorkitem workitem = new CommentWorkitem(); FillGeneralWorkitem(workitem, ref a_string); workitem.title = ReadStringUntil(ref a_string, '\n'); workitem.url = ReadStringUntil(ref a_string, '\n'); workitem.links.Add(new LinkLabel.Link(0, 0, workitem.url)); if (readDetails) { workitem.isDetailed = true; workitem.text = ReadTextBlock(ref a_string); } return workitem; } //----------------------------------------------------------------------- private void FillGeneralWorkitem(Workitem a_workitem, ref string a_string) { a_workitem.workitemId = int.Parse(ReadStringUntil(ref a_string, '\n')); string line = ReadStringUntil(ref a_string, '\n'); a_workitem.creationTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); double sec = double.Parse(line); a_workitem.creationTime = a_workitem.creationTime.AddSeconds(sec); a_workitem.projectId = int.Parse(ReadStringUntil(ref a_string, '\n')); a_workitem.project = ReadStringUntil(ref a_string, '\n'); a_workitem.user = ReadStringUntil(ref a_string, '\n'); } #endregion ----------------- End Other Methods -------------------------- } }