Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of https://github.com/daberkow/Enstall

  • Loading branch information...
commit 8f3283ba570b57fbbdf7e6dca45843b2e0d83fbc 2 parents df877f5 + 6ab7136
@daberkow authored
View
22 client/ETUEPackage.cs
@@ -17,6 +17,8 @@ class ETUEPackage
private String fileVersion = ""; // Package version
private String versionCreated = ""; // ETUEVersion this package .xml was created in
+ private String packageTitle = ""; // The package title listed on the Enstall package list site
+
//------< Constructors >------//
//Constructs a default package
@@ -31,6 +33,12 @@ public ETUEPackage(String url)
copy( ETUEReader.parse(url) );
}
+ //Constructs a reader with the information from the .xml at url, and packageTitle pTitle
+ public ETUEPackage(String url, String pTitle) : this(url)
+ {
+ this.packageTitle = pTitle;
+ }
+
public ETUEPackage(ETUEPackage package)
{
copy(package);
@@ -93,12 +101,18 @@ public String getFileVersion()
return this.fileVersion;
}
- //Returns the ETUE version this
+ //Returns the ETUE version
public String getVersionCreated()
{
return this.versionCreated;
}
+ //Returns the package title
+ public String getPackageTitle()
+ {
+ return this.packageTitle;
+ }
+
//------< Mutators >------//
//Sets the UID of the package
@@ -149,6 +163,12 @@ public void setVersionCreated(String versionCreated)
this.versionCreated = versionCreated;
}
+ //Sets the package title
+ public void setPackageTitle(String packageTitle)
+ {
+ this.packageTitle = packageTitle;
+ }
+
//Prints the info of the package
public void printInfo()
{
View
1  client/ETUEReader.cs
@@ -13,7 +13,6 @@ public static ETUEPackage parse(String url)
{
using (XmlReader reader = XmlReader.Create(url))
{
-
ETUEPackage pack = new ETUEPackage();
//Do some basic error checking, make sure this xml is
// of the right format
View
204 client/EnstallClient.cs
@@ -0,0 +1,204 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Gtk;
+using System.Text.RegularExpressions;
+
+namespace ETUEtest
+{
+ class EnstallClient
+ {
+ //List member varaibles for packages
+ private List<ETUEPackage> packages;
+ private List<bool> inbool;
+
+ //Default width and height of the window
+ public const int DEFAULT_WIDTH = 640;
+ public const int DEFAULT_HEIGHT = 480;
+
+ //const strings for window title and regex match pattern
+ private const String winTitle = "Enstall: Because Class is Hard Enough";
+ private const String matchPattern = "id='package_title'><.*?>(?<pTitle>.*?)</a>.*?<a href='(?<pLink>.*?)'>";
+
+ //Global gui elements
+ private ListStore ls;
+ private Window clientWin;
+
+ //Default constructor:
+ public EnstallClient() : this( DEFAULT_WIDTH, DEFAULT_HEIGHT )
+ {
+
+ }
+
+ //Constructor to accpe custom width/height
+ public EnstallClient(int width, int height)
+ {
+ //Initialize the List member variables, then populate the package list from the given url
+ this.packages = new List<ETUEPackage>();
+ this.inbool = new List<bool>();
+ populateList("http://beta.ntbl.co/enstall/packages.php");
+
+ //GTK# initialization
+ Application.Init();
+
+ //Initialize the window and add gui elements
+ this.clientWin = new Window( winTitle );
+ this.clientWin.Resize(width, height);
+
+ createGUIElements();
+
+ //Show everything and finally run
+ this.clientWin.ShowAll();
+ Application.Run();
+ }
+
+ private int populateList(String url)
+ {
+ //Initialize the regex used to parse the site
+ Regex re = new Regex(matchPattern, RegexOptions.Singleline);
+
+ //Find the matches
+ MatchCollection matches = re.Matches(webUtil.GetHtmlFromUrl(url));
+ //For each match, extract the title and link, and construct a Package object from them
+ foreach (Match m in matches)
+ {
+ //Extract the package title and link from the match
+ String pTitle = m.Groups[1].ToString();
+ String pLink = m.Groups[2].ToString();
+
+ //Create and add a new ETUE package to the list
+ this.packages.Add(new ETUEPackage(pLink, pTitle));
+
+ //For now, each package will default to "not installed" so add false to the list
+ this.inbool.Add(false);
+ }
+
+ return 0; //No error
+
+ //TODO: add proper error handling
+ }
+
+ private void createGUIElements()
+ {
+ //Vertical box for organization
+ VBox vbox = new VBox();
+ vbox.Homogeneous = false;
+
+ //ScrolledWindow to handle the scrolling of the list
+ ScrolledWindow sw = new ScrolledWindow();
+
+ //The treeview that all packages will be stored in
+ TreeView tv = new TreeView();
+
+ //Add the TreeView to the ScrolledWindow
+ sw.AddWithViewport(tv);
+
+ //Self explanatory, the liststore well store rows of :
+ // ( [string], [string], [string], [string], [bool], [string] )
+ ls = new ListStore(typeof(string), typeof(string), typeof(string), typeof(string), typeof(bool), typeof(string));
+
+ //Cell Renderer for the toggle button column
+ CellRendererToggle crt = new CellRendererToggle();
+ crt.Activatable = true; //Activatable specifies whether or not users can toggle the button
+ // Here we're using these to "Mark For Installation," so we want them
+ // to be "toggleable"
+ crt.Toggled += buttonToggled; //Add the event handler for this renderer
+
+ //Add columns to the tree view (Optional)
+ // | Name | Cell Renderer | Property | Column number
+ tv.AppendColumn("Package Title", new CellRendererText(), "text", 0);
+ tv.AppendColumn("Version", new CellRendererText(), "text", 1);
+ tv.AppendColumn("Organization", new CellRendererText(), "text", 2);
+ tv.AppendColumn("Description", new CellRendererText(), "text", 3);
+ tv.AppendColumn("Install", crt, "active", 4);
+ tv.AppendColumn("", new CellRendererText(), "text", 5);
+ //Column 5 is an empty column. GTK treeview likes to stretch the last column to fit the
+ // rest of the whitespace left over. If we insert an empty column, this fixes the problem
+
+ //Loop through all packages, and add an entry for each package
+ for(int i = 0; i < packages.Count; i++)
+ {
+ //Construct the row from the package[i]'s information
+ ls.AppendValues(packages[i].getPackageTitle(), packages[i].getFileVersion(),
+ packages[i].getOrganization(), packages[i].getDescription(), inbool[i], "");
+ }
+
+ //Set the model to the ListStore
+ tv.Model = ls;
+
+ //Button to install all marked packages
+ Button installButton = new Button("Install Selected Packages");
+ installButton.Clicked += installButtonClicked;
+ installButton.HeightRequest = 30;
+
+ //Add the components to the box
+ vbox.PackStart(installButton, false, false, 0); //Add the install button to the beginning (PackStart)
+ vbox.PackEnd(sw); //Add the scrolledWindow to the end (PackEnd)
+
+ //Finally, add the box to the window
+ this.clientWin.Add(vbox);
+ }
+
+ //The togglebutton event handler:
+ // Finds the index of the button toggled, then toggles the corresponding boolean
+ private void buttonToggled(object sender, ToggledArgs args)
+ {
+ //Iterator to iterate through the model
+ TreeIter iter;
+ TreePath tp = new TreePath(args.Path);
+ //If we can found the toggled button
+ if (ls.GetIter(out iter, tp))
+ {
+ //Get the old value, and set the value to the opposite
+ bool old = (bool)ls.GetValue(iter, 4);
+ ls.SetValue(iter, 4, !old);
+
+ //This method of getting the index seems pretty janky, but it works for now
+ // In the spirit of improving TODO: Find a better way to do this
+ inbool[Convert.ToInt32(tp.ToString())] = !old;
+ }
+ }
+
+ [GLib.ConnectBefore]
+ private void installButtonClicked(object sender, EventArgs args)
+ {
+ //Loop through all of the package booleans and install all of the marked packages
+ for (int i = 0; i < this.inbool.Count; i++)
+ {
+ //If this was marked for installation
+ if (inbool[i])
+ {
+ //Run the command
+ RunCommand(packages[i].getBasicScript(), "", false);
+ }
+ }
+
+ //TODO: Handle error cases here
+ }
+
+ //Function to run commands, like the basic script and
+ static bool RunCommand(string szCmd, string szArgs, bool wait)
+ {
+ //If there is no command, simply return false
+ if (szCmd == null) return false;
+
+ //Otherwise, create a new process with the given command and arguments
+ System.Diagnostics.Process myproc = new System.Diagnostics.Process();
+ myproc.EnableRaisingEvents = false;
+ myproc.StartInfo.FileName = szCmd;
+ myproc.StartInfo.Arguments = szArgs;
+
+ //Start the process
+ if (myproc.Start())
+ {
+ //Using WaitForExit( ) allows for the host program
+ //to wait for the command its executing before it continues
+ if (wait) myproc.WaitForExit();
+ else myproc.Close();
+ return true;
+ }
+ else return false; // If the process could not start, it failed
+ }
+ }
+}
View
16 client/Program.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+
+namespace ETUEtest
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ EnstallClient ec = new EnstallClient();
+ }
+ }
+}
View
110 client/webUtil.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using System.Web;
+using System.Text;
+using System.Net;
+
+namespace ETUEtest
+{
+ class webUtil
+ {
+ public enum ResponseCategories
+ {
+ Unknown = 0,
+ Informational = 1,
+ Success = 2,
+ Redirected = 3,
+ ClientError = 4,
+ ServerError = 5
+ };
+
+ public static HttpWebRequest GenerateHttpWebRequest(string uriString)
+ {
+ //Get a URI object
+ Uri uri = new Uri(uriString);
+ //Create the initial request
+ HttpWebRequest httpRequest = (HttpWebRequest) HttpWebRequest.Create(uri);
+ //Return the request
+ return httpRequest;
+ }
+
+ public static HttpWebRequest GenerateHttpWebRequest(string uriString, string postData, string contentType)
+ {
+ //Get a URI object
+ Uri uri = new Uri(uriString);
+ //Create the initial request
+ HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
+
+ //Get the bytes for the request
+ byte[] bytes = Encoding.UTF8.GetBytes(postData);
+
+ //Set the content type of the data being posted
+ httpRequest.ContentType = contentType;
+
+ //Set the content length of the string being posted
+ httpRequest.ContentLength = postData.Length;
+
+ //Get the request stream and write the post data in
+ using (Stream requestStream = httpRequest.GetRequestStream())
+ {
+ requestStream.Write(bytes, 0, bytes.Length);
+ }
+
+ //Return the request
+ return httpRequest;
+ }
+
+ public static ResponseCategories VerifyResponse(HttpWebResponse httpResponse)
+ {
+ int statusCode = (int)httpResponse.StatusCode;
+ if(( statusCode >= 100) && (statusCode <= 199) )
+ {
+ return ResponseCategories.Informational;
+ }
+ else if(( statusCode >= 200) && (statusCode <= 299) )
+ {
+ return ResponseCategories.Success;
+ }
+ else if(( statusCode >= 300) && (statusCode <= 399) )
+ {
+ return ResponseCategories.Redirected;
+ }
+ else if(( statusCode >= 400) && (statusCode <= 499) )
+ {
+ return ResponseCategories.ClientError;
+ }
+ else if(( statusCode >= 500) && (statusCode <= 599) )
+ {
+ return ResponseCategories.ServerError;
+ }
+ return ResponseCategories.Unknown;
+ }
+
+ public static string GetHtmlFromUrl(string url)
+ {
+ if (string.IsNullOrEmpty(url))
+ throw new ArgumentNullException("url", "Parameter is null or empty");
+
+ string html = "";
+ HttpWebRequest request = GenerateHttpWebRequest(url);
+ using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
+ {
+ if (VerifyResponse(response) == ResponseCategories.Success )
+ {
+ //Get the response stream
+ Stream responseStream = response.GetResponseStream();
+ //Use a stream reader that understands UTF8
+ using(StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
+ {
+ html = reader.ReadToEnd();
+ }
+ }
+ }
+
+ //Return the html as a string
+ return html;
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.