Create local repo when fetching Apps

This commit is contained in:
CreepyCrafter24 2019-10-20 15:18:21 +02:00
parent c91573cff9
commit be9f76879c
5 changed files with 213 additions and 176 deletions

View File

@ -11,4 +11,5 @@
- app
- __APPFILES
- info.xml
- Version
- Version
- Repo

View File

@ -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
Decent updater
Do not refetch Repos after install/update (save local repo in main info.xml)

View File

@ -13,7 +13,6 @@ namespace UpTool2
{
public partial class DownloadDialog : Form
{
WebClient client;
bool close;
public DownloadDialog(string uri, string file)
{

View File

@ -16,173 +16,7 @@ namespace UpTool2
{
public partial class MainForm : Form
{
Dictionary<Guid, App> apps = new Dictionary<Guid, App>();
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<App> tmp_appslist = new List<App>(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<App> tmp_appslist = fetchRepos();
apps.Clear();
tmp_appslist.ForEach(s => apps.Add(s.ID, s));
}
List<App> 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<App> tmp_appslist = new List<App>(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<App>
{
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<Guid, App> apps = new Dictionary<Guid, App>();
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
}
}

View File

@ -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)