diff --git a/FolderLayout.txt b/FolderLayout.txt index e7f2735..71b25c4 100644 --- a/FolderLayout.txt +++ b/FolderLayout.txt @@ -11,4 +11,5 @@ - app - __APPFILES - info.xml - - Version \ No newline at end of file + - Version + - Repo \ No newline at end of file diff --git a/ToDo.txt b/ToDo.txt index 7abf797..2b8cb91 100644 --- a/ToDo.txt +++ b/ToDo.txt @@ -1,4 +1,5 @@ More Icons for Apps More apps: Laptop Sim (when done) Use local info when building GUI (Except name/description) -Decent updater \ No newline at end of file +Decent updater +Do not refetch Repos after install/update (save local repo in main info.xml) \ No newline at end of file diff --git a/UpTool2/DownloadDialog.cs b/UpTool2/DownloadDialog.cs index 8b5f36e..2c724c6 100644 --- a/UpTool2/DownloadDialog.cs +++ b/UpTool2/DownloadDialog.cs @@ -13,7 +13,6 @@ namespace UpTool2 { public partial class DownloadDialog : Form { - WebClient client; bool close; public DownloadDialog(string uri, string file) { diff --git a/UpTool2/MainForm.cs b/UpTool2/MainForm.cs index 9337996..f398493 100644 --- a/UpTool2/MainForm.cs +++ b/UpTool2/MainForm.cs @@ -16,173 +16,7 @@ namespace UpTool2 { public partial class MainForm : Form { - Dictionary apps = new Dictionary(); - enum Status { Not_Installed = 1, Updatable = 2, Installed = 4, Local = 8, All = 15 } - string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; - public MainForm() - { - InitializeComponent(); - filterBox.DataSource = Enum.GetValues(typeof(Status)); - reloadElements(); - if (!Directory.Exists(dir + @"\Apps")) - Directory.CreateDirectory(dir + @"\Apps"); - } - - private void MainForm_Load(object sender, EventArgs e) - { - Program.splash.Hide(); - BringToFront(); - } - - void reloadElements() - { - //remove - toolTip.RemoveAll(); - clearSelection(); - infoPanel_Title.Invalidate(); - infoPanel_Description.Invalidate(); - int F = sidebarPanel.Controls.Count; - for (int i = 0; i < F; i++) - { - sidebarPanel.Controls[0].Dispose(); - } - apps.Clear(); - //add - toolTip.SetToolTip(controls_settings, "Settings"); - toolTip.SetToolTip(controls_reload, "Refresh repositories"); - toolTip.SetToolTip(controls_upload, "Install package from disk"); - toolTip.SetToolTip(filterBox, "Filter"); - toolTip.SetToolTip(action_install, "Install"); - toolTip.SetToolTip(action_remove, "Remove"); - toolTip.SetToolTip(action_update, "Update"); - toolTip.SetToolTip(action_run, "Run"); - WebClient client = new WebClient(); - for (int i = 0; i < Settings.Default.Repos.Count; i++) - { -#if !DEBUG - try - { -#endif - //get info - XDocument repo = XDocument.Load(Settings.Default.Repos[i]); - foreach (XElement el in repo.Element("repo").Elements("app")) - { - int version = int.Parse(el.Element("Version").Value); - Guid ID = Guid.Parse(el.Element("ID").Value); - if (!(apps.ContainsKey(ID) && apps[ID].version >= version)) - { - string name = el.Element("Name").Value; - string description = el.Element("Description").Value; - string file = el.Element("File").Value; - string hash = el.Element("Hash").Value; - bool runnable = el.Element("MainFile") != null; - string mainFile = ""; - if (runnable) - mainFile = el.Element("MainFile").Value; - Color color = ColorTranslator.FromHtml(el.Element("Color").Value); - Image icon = el.Element("Icon") == null ? Resources.C_64.ToBitmap() : Image.FromStream(client.OpenRead(el.Element("Icon").Value)); - apps[ID] = new App(name, description, version, file, false, hash, ID, color, icon, runnable, mainFile); - } - } -#if !DEBUG - } - catch (Exception e) - { - MessageBox.Show(e.ToString(), "Failed to load repo: " + Settings.Default.Repos[i]); - } -#endif - } - string[] localApps = Directory.GetDirectories(dir + @"\Apps\"); - for (int i = 0; i < localApps.Length; i++) - { - Guid tmp = Guid.Parse(Path.GetFileName(localApps[i])); - if (!apps.ContainsKey(tmp)) - { - XElement data = XDocument.Load(dir + @"\Apps\" + tmp.ToString() + @"\info.xml").Element("app"); - apps.Add(tmp, new App("(local) " + data.Element("Name").Value, data.Element("Description").Value, -1, "", true, "", tmp, Color.Red, Resources.C_64.ToBitmap(), data.Element("MainFile") != null, data.Element("MainFile") == null ? "" : data.Element("MainFile").Value)); - } - } - List tmp_appslist = new List(apps.Values); - tmp_appslist.Sort((x, y) => x.name.CompareTo(y.name)); - foreach ((App app, Panel sidebarIcon) in from App app in tmp_appslist let sidebarIcon = new Panel() select (app, sidebarIcon)) - { - sidebarIcon.Tag = app; - sidebarIcon.BackColor = app.color; - sidebarIcon.Size = new Size(70, 70); - sidebarIcon.BackgroundImage = app.icon; - sidebarIcon.BackgroundImageLayout = ImageLayout.Stretch; - sidebarIcon.Click += (object sender, EventArgs e) => { - infoPanel_Title.Text = app.name; - infoPanel_Title.ForeColor = app.local ? Color.Red : Color.Black; - infoPanel_Description.Text = app.description; - action_install.Tag = app; - action_install.Enabled = !(app.local || Directory.Exists(dir + @"\Apps\" + app.ID.ToString())); - action_remove.Tag = app; - action_remove.Enabled = Directory.Exists(dir + @"\Apps\" + app.ID.ToString()); - action_update.Tag = app; - string xml = dir + @"\Apps\" + app.ID.ToString() + @"\info.xml"; - action_update.Enabled = (!app.local) && File.Exists(xml) && int.Parse(XDocument.Load(xml).Element("app").Element("Version").Value) < app.version; - action_run.Tag = app; - action_run.Enabled = (!app.local) && app.runnable && Directory.Exists(dir + @"\Apps\" + app.ID.ToString()); - }; - toolTip.SetToolTip(sidebarIcon, app.name); - sidebarPanel.Controls.Add(sidebarIcon); - } - client.Dispose(); - updateSidebarV(null, null); - } - - private void Controls_settings_Click(object sender, EventArgs e) => new SettingsForm().Show(); - - private void Controls_reload_Click(object sender, EventArgs e) => reloadElements(); - - private void Action_run_Click(object sender, EventArgs e) - { - string app = dir + @"\Apps\" + ((App)action_run.Tag).ID.ToString(); - Process.Start(new ProcessStartInfo { FileName = app + "\\app\\" + ((App)action_run.Tag).mainFile, WorkingDirectory = app + @"\app" }); - } - - bool relE = true; - private void Action_remove_Click(object sender, EventArgs e) - { - try - { - string app = dir + @"\Apps\" + ((App)action_remove.Tag).ID.ToString(); - string tmp = dir + @"\tmp"; - if (Directory.Exists(tmp)) - Directory.Delete(tmp, true); - Directory.CreateDirectory(tmp); - ZipFile.ExtractToDirectory(app + @"\package.zip", tmp); - Process.Start(new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/C \"" + tmp + "\\Remove.bat\"", WorkingDirectory = app + @"\app" }).WaitForExit(); - Directory.Delete(tmp, true); - Directory.Delete(app, true); - if (relE) - reloadElements(); - } - catch (Exception e1) - { - if (!relE) - throw; - MessageBox.Show(e1.ToString(), "Removal failed"); - } - } - - private void Action_update_Click(object sender, EventArgs e) - { - try - { - relE = false; - Action_remove_Click(sender, e); - Action_install_Click(sender, e); - } - catch (Exception e1) - { - MessageBox.Show(e1.ToString(), "Install failed"); - } - reloadElements(); - relE = true; - } - + #region Install/Remove/Upload (Main local app management) private void Action_install_Click(object sender, EventArgs e) { string app = ""; @@ -220,7 +54,29 @@ namespace UpTool2 #endif Directory.Delete(tmp, true); } - + private void Action_remove_Click(object sender, EventArgs e) + { + try + { + string app = dir + @"\Apps\" + ((App)action_remove.Tag).ID.ToString(); + string tmp = dir + @"\tmp"; + if (Directory.Exists(tmp)) + Directory.Delete(tmp, true); + Directory.CreateDirectory(tmp); + ZipFile.ExtractToDirectory(app + @"\package.zip", tmp); + Process.Start(new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/C \"" + tmp + "\\Remove.bat\"", WorkingDirectory = app + @"\app" }).WaitForExit(); + Directory.Delete(tmp, true); + Directory.Delete(app, true); + if (relE) + reloadElements(); + } + catch (Exception e1) + { + if (!relE) + throw; + MessageBox.Show(e1.ToString(), "Removal failed"); + } + } private void controls_upload_Click(object sender, EventArgs e) { string app = ""; @@ -261,7 +117,6 @@ namespace UpTool2 if (tmp != "" && Directory.Exists(tmp)) Directory.Delete(tmp, true); } - void completeInstall(string app, App appI) { try @@ -279,7 +134,165 @@ namespace UpTool2 } catch { throw; } } + #endregion + #region Repo management + void reloadElements() + { + //remove + toolTip.RemoveAll(); + clearSelection(); + infoPanel_Title.Invalidate(); + infoPanel_Description.Invalidate(); + int F = sidebarPanel.Controls.Count; + for (int i = 0; i < F; i++) + { + sidebarPanel.Controls[0].Dispose(); + } + apps.Clear(); + //add + toolTip.SetToolTip(controls_settings, "Settings"); + toolTip.SetToolTip(controls_reload, "Refresh repositories"); + toolTip.SetToolTip(controls_upload, "Install package from disk"); + toolTip.SetToolTip(filterBox, "Filter"); + toolTip.SetToolTip(action_install, "Install"); + toolTip.SetToolTip(action_remove, "Remove"); + toolTip.SetToolTip(action_update, "Update"); + toolTip.SetToolTip(action_run, "Run"); + getLiveRepos(); + foreach (App app in apps.Values) + { + Panel sidebarIcon = new Panel(); + sidebarIcon.Tag = app; + sidebarIcon.BackColor = app.color; + sidebarIcon.Size = new Size(70, 70); + sidebarIcon.BackgroundImage = app.icon; + sidebarIcon.BackgroundImageLayout = ImageLayout.Stretch; + sidebarIcon.Click += (object sender, EventArgs e) => { + infoPanel_Title.Text = app.name; + infoPanel_Title.ForeColor = app.local ? Color.Red : Color.Black; + infoPanel_Description.Text = app.description; + action_install.Tag = app; + action_install.Enabled = !(app.local || Directory.Exists(dir + @"\Apps\" + app.ID.ToString())); + action_remove.Tag = app; + action_remove.Enabled = Directory.Exists(dir + @"\Apps\" + app.ID.ToString()); + action_update.Tag = app; + string xml = dir + @"\Apps\" + app.ID.ToString() + @"\info.xml"; + action_update.Enabled = (!app.local) && File.Exists(xml) && int.Parse(XDocument.Load(xml).Element("app").Element("Version").Value) < app.version; + action_run.Tag = app; + action_run.Enabled = (!app.local) && app.runnable && Directory.Exists(dir + @"\Apps\" + app.ID.ToString()); + }; + toolTip.SetToolTip(sidebarIcon, app.name); + sidebarPanel.Controls.Add(sidebarIcon); + } + updateSidebarV(null, null); + } + + void getLiveRepos() + { + List tmp_appslist = fetchRepos(); + apps.Clear(); + tmp_appslist.ForEach(s => apps.Add(s.ID, s)); + } + + List fetchRepos() + { + WebClient client = new WebClient(); + for (int i = 0; i < Settings.Default.Repos.Count; i++) + { +#if !DEBUG + try + { +#endif + XDocument repo = XDocument.Load(Settings.Default.Repos[i]); + foreach (XElement el in repo.Element("repo").Elements("app")) + { + int version = int.Parse(el.Element("Version").Value); + Guid ID = Guid.Parse(el.Element("ID").Value); + if (!(apps.ContainsKey(ID) && apps[ID].version >= version)) + { + string name = el.Element("Name").Value; + string description = el.Element("Description").Value; + string file = el.Element("File").Value; + string hash = el.Element("Hash").Value; + bool runnable = el.Element("MainFile") != null; + string mainFile = ""; + if (runnable) + mainFile = el.Element("MainFile").Value; + Color color = ColorTranslator.FromHtml(el.Element("Color").Value); + Image icon = el.Element("Icon") == null ? Resources.C_64.ToBitmap() : Image.FromStream(client.OpenRead(el.Element("Icon").Value)); + App tmp_app = new App(name, description, version, file, false, hash, ID, color, icon, runnable, mainFile); + if (el.Element("Icon") != null) + tmp_app.tag = el.Element("Icon").Value; + apps[ID] = tmp_app; + } + } +#if !DEBUG + } + catch (Exception e) + { + MessageBox.Show(e.ToString(), "Failed to load repo: " + Settings.Default.Repos[i]); + } +#endif + client.Dispose(); + } + string[] localApps = Directory.GetDirectories(dir + @"\Apps\"); + for (int i = 0; i < localApps.Length; i++) + { + Guid tmp = Guid.Parse(Path.GetFileName(localApps[i])); + if (!apps.ContainsKey(tmp)) + { + XElement data = XDocument.Load(dir + @"\Apps\" + tmp.ToString() + @"\info.xml").Element("app"); + apps.Add(tmp, new App("(local) " + data.Element("Name").Value, data.Element("Description").Value, -1, "", true, "", tmp, Color.Red, Resources.C_64.ToBitmap(), data.Element("MainFile") != null, data.Element("MainFile") == null ? "" : data.Element("MainFile").Value)); + } + } + List tmp_appslist = new List(apps.Values); + tmp_appslist.Sort((x, y) => x.name.CompareTo(y.name)); + string xml = dir + @"\info.xml"; + XElement meta = XDocument.Load(xml).Element("meta"); + if (meta.Element("Repo") == null) + meta.Add(new XElement("Repo")); + meta.Save(xml); + XElement repos = meta.Element("Repo"); + repos.RemoveNodes(); + tmp_appslist.ForEach(app => { + XElement el = new XElement(app.ID.ToString(), + new XElement("Name", app.name), + new XElement("Description", app.description), + new XElement("Version", app.version), + new XElement("File", app.file), + new XElement("Hash", app.hash), + new XElement("MainFile", app.mainFile), + new XElement("Color", string.Format("{0:x6}", app.color.ToArgb() & 0xFFFFFF))); + repos.Add(el); + if (app.tag != null) + el.Add(new XElement("Icon", (string)app.tag)); + }); + meta.Save(xml); + return tmp_appslist; + } + #endregion + #region Run/Update/Reload/Settings (Small links to other stuff) + private void Action_run_Click(object sender, EventArgs e) => _ = Process.Start(new ProcessStartInfo { FileName = getDataPath((App)action_run.Tag) + "\\" + ((App)action_run.Tag).mainFile, WorkingDirectory = getDataPath((App)action_run.Tag) }); + private void Action_update_Click(object sender, EventArgs e) + { + try + { + relE = false; + Action_remove_Click(sender, e); + Action_install_Click(sender, e); + } + catch (Exception e1) + { + MessageBox.Show(e1.ToString(), "Install failed"); + } + reloadElements(); + relE = true; + } + private void Controls_reload_Click(object sender, EventArgs e) => reloadElements(); + private void Controls_settings_Click(object sender, EventArgs e) => new SettingsForm().Show(); + #endregion + #region GUI (stuff only present for GUI) void clearSelection() { action_install.Enabled = false; @@ -289,7 +302,6 @@ namespace UpTool2 infoPanel_Title.Text = ""; infoPanel_Description.Text = ""; } - private void updateSidebarV(object sender, EventArgs e) { Enum.TryParse(filterBox.SelectedValue.ToString(), out Status status); @@ -301,7 +313,21 @@ namespace UpTool2 } clearSelection(); } - + public MainForm() + { + InitializeComponent(); + filterBox.DataSource = Enum.GetValues(typeof(Status)); + reloadElements(); + if (!Directory.Exists(appsPath)) + Directory.CreateDirectory(appsPath); + } + private void MainForm_Load(object sender, EventArgs e) + { + Program.splash.Hide(); + BringToFront(); + } + #endregion + #region Definitions private struct App : IEquatable { public string name; @@ -315,8 +341,9 @@ namespace UpTool2 public Image icon; public bool runnable; public string mainFile; + public object tag; - public App(string name, string description, int version, string file, bool local, string hash, Guid iD, Color color, Image icon, bool runnable, string mainFile) + public App(string name, string description, int version, string file, bool local, string hash, Guid iD, Color color, Image icon, bool runnable, string mainFile, object tag = null) { this.name = name ?? throw new ArgumentNullException(nameof(name)); this.description = description ?? throw new ArgumentNullException(nameof(description)); @@ -329,6 +356,7 @@ namespace UpTool2 this.icon = icon ?? throw new ArgumentNullException(nameof(icon)); this.runnable = runnable; this.mainFile = mainFile ?? throw new ArgumentNullException(nameof(mainFile)); + this.tag = tag; } public Status status @@ -356,5 +384,13 @@ namespace UpTool2 public static bool operator ==(App left, App right) => left.Equals(right); public static bool operator !=(App left, App right) => !(left == right); } + Dictionary apps = new Dictionary(); + enum Status { Not_Installed = 1, Updatable = 2, Installed = 4, Local = 8, All = 15 } + string dir => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; + string appsPath => dir + @"\Apps"; + string getAppPath(App app) => appsPath + @"\" + app.ID.ToString(); + string getDataPath(App app) => getAppPath(app) + @"\app"; + bool relE = true; + #endregion } } diff --git a/UpTool2/Program.cs b/UpTool2/Program.cs index c11d936..9fa2719 100644 --- a/UpTool2/Program.cs +++ b/UpTool2/Program.cs @@ -80,7 +80,7 @@ namespace UpTool2 Directory.CreateDirectory(dir + @"\Apps"); string xml = dir + @"\info.xml"; if (!File.Exists(xml)) - new XElement("meta", new XElement("Version", 0)).Save(xml); + new XElement("meta", new XElement("Version", 0), new XElement("Repo")).Save(xml); XElement meta = XDocument.Load("https://github.com/CreepyCrafter24/UpTool2/releases/download/Repo/Meta.xml").Element("meta"); int version = int.Parse(meta.Element("Version").Value); if (int.Parse(XDocument.Load(xml).Element("meta").Element("Version").Value) < version)