implemented csv export, fixed broken msgboxes

This commit is contained in:
Lynne Megido 2020-09-05 15:02:37 +10:00
parent 9913c3118f
commit 4c212c4c21
Signed by: lynnesbian
GPG key ID: F0A184B5213D9F90
5 changed files with 114 additions and 33 deletions

View file

@ -24,14 +24,16 @@ using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Net; using System.Net;
using System.Linq;
using System.Diagnostics; using System.Diagnostics;
using CsvHelper;
using Gtk; using Gtk;
namespace Buypeeb { namespace Buypeeb {
class MainWindow : Window { class MainWindow : Window {
private string location; private string location;
private JsonSerializerOptions jsonOptions;
private ListStore items; private ListStore items;
private Settings settings; private Settings settings;
@ -66,6 +68,11 @@ namespace Buypeeb {
public MainWindow() : this(new Builder("main.glade")) { } public MainWindow() : this(new Builder("main.glade")) { }
private MainWindow(Builder builder) : base(builder.GetObject("wndMain").Handle) { private MainWindow(Builder builder) : base(builder.GetObject("wndMain").Handle) {
this.jsonOptions = new JsonSerializerOptions {
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All)
};
if (Environment.OSVersion.Platform == PlatformID.Win32NT) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
// C:\Users\Beebus\AppData\Roaming\Lynnear Software\buypeeb // C:\Users\Beebus\AppData\Roaming\Lynnear Software\buypeeb
this.location = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%APPDATA%"), "Lynnear Software", "buypeeb"); this.location = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%APPDATA%"), "Lynnear Software", "buypeeb");
@ -153,7 +160,7 @@ namespace Buypeeb {
} }
private void SaveSettings() { private void SaveSettings() {
string j = JsonSerializer.Serialize(this.settings); string j = JsonSerializer.Serialize(this.settings, this.jsonOptions);
string p = System.IO.Path.Combine(this.location, "userdata.json"); string p = System.IO.Path.Combine(this.location, "userdata.json");
Console.WriteLine(j); Console.WriteLine(j);
if (!Directory.Exists(this.location)) { if (!Directory.Exists(this.location)) {
@ -181,8 +188,9 @@ namespace Buypeeb {
using (WebClient client = new WebClient()) { using (WebClient client = new WebClient()) {
// TODO: download should have timeout // TODO: download should have timeout
item.Update(client.DownloadString(item.url)); // item.Update(client.DownloadString(item.url));
// item.Update(File.ReadAllText("yahoo.html")); Thread.Sleep(5000);
item.Update(File.ReadAllText("yahoo.html"));
} }
Gtk.Application.Invoke(delegate { Gtk.Application.Invoke(delegate {
@ -272,11 +280,11 @@ namespace Buypeeb {
var info = new Dictionary<string, string> { var info = new Dictionary<string, string> {
{ "Name", item.name }, { "Name", item.name },
{ "YahooName", item.originalName }, { "YahooName", item.originalName },
{ "Price", item.PriceJPY() }, { "Price", item.priceJPY },
{ "PriceAUD", item.PriceAUD() }, { "PriceAUD", item.priceAUD },
{ "Ending", "..." }, { "Ending", "..." },
{ "Bids", $"{item.bids}" }, { "Bids", $"{item.bids}" },
{ "BuyItNow", item.winPrice == 0 ? "No" : $"¥{item.PriceJPY(true)} (${item.PriceAUD(true)})" }, { "BuyItNow", item.winPrice == 0 ? "No" : $"{item.winPriceJPY} ({item.winPriceAUD})" },
{ "AutoExtension", item.autoExtension ? "Yes" : "No" }, { "AutoExtension", item.autoExtension ? "Yes" : "No" },
{ "LastUpdated", "Last updated: heeeenlo" } { "LastUpdated", "Last updated: heeeenlo" }
}; };
@ -359,8 +367,8 @@ namespace Buypeeb {
private void RenderList() { private void RenderList() {
this.items.Clear(); this.items.Clear();
foreach (var item in this.settings.watchlist) { foreach (var item in this.settings.watchlist.Values) {
items.AppendValues(item.Value); items.AppendValues(item);
} }
} }
@ -441,7 +449,9 @@ namespace Buypeeb {
} }
catch (Exception e) { catch (Exception e) {
Console.WriteLine(e); Console.WriteLine(e);
MsgBox($"Failed to load {od.Filename}!\n{e.Message}"); var md = MsgBox($"Failed to load {od.Filename}!\n{e.Message}", ButtonsType.Ok);
md.Run();
md.Dispose();
} }
} }
od.Dispose(); od.Dispose();
@ -472,7 +482,52 @@ namespace Buypeeb {
var fs = File.CreateText(sd.Filename); var fs = File.CreateText(sd.Filename);
fs.Close(); fs.Close();
} }
File.WriteAllText(sd.Filename, JsonSerializer.Serialize(this.settings)); File.WriteAllText(sd.Filename, JsonSerializer.Serialize(this.settings, jsonOptions));
}
catch (Exception e) {
Console.WriteLine(e);
var md = MsgBox($"Failed to write {sd.Filename}!\n{e.Message}.", ButtonsType.Ok);
md.Run();
md.Dispose();
}
}
sd.Dispose();
}
private void ButtonExportClicked(object sender, EventArgs a) {
var readyQuery = from item in this.settings.watchlist.Values.ToList() where !item.ready select item;
foreach (var item in readyQuery) {
Console.WriteLine(item.name);
}
if (readyQuery.Count() != 0) {
var md = MsgBox("Please wait for all items to update before exporting a CSV.", ButtonsType.Ok);
md.Run();
md.Dispose();
return;
}
var sd = new FileChooserDialog(
title: "Export watchlist as CSV",
parent: this,
action: FileChooserAction.Save,
"Cancel", ResponseType.Cancel, "Save", ResponseType.Accept
);
sd.CurrentName = "buypeeb.csv";
var sdf = new FileFilter();
sdf.Name = "CSV files";
sdf.AddMimeType("text/csv");
sdf.AddPattern("*.csv");
sd.AddFilter(sdf);
if (sd.Run() == (int)ResponseType.Accept) {
try {
using (var writer = new StreamWriter(sd.Filename))
using (var csv = new CsvWriter(writer, System.Globalization.CultureInfo.InvariantCulture)) {
csv.WriteRecords(this.settings.watchlist);
}
} }
catch (Exception e) { catch (Exception e) {
Console.WriteLine(e); Console.WriteLine(e);
@ -594,12 +649,12 @@ namespace Buypeeb {
private void RenderColumnPriceYen(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) { private void RenderColumnPriceYen(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) {
YahooAuctionsItem item = (YahooAuctionsItem)model.GetValue(iter, 0); YahooAuctionsItem item = (YahooAuctionsItem)model.GetValue(iter, 0);
(cell as Gtk.CellRendererText).Text = item.ready ? item.PriceJPY() : "..."; (cell as Gtk.CellRendererText).Text = item.ready ? item.priceJPY : "...";
} }
private void RenderColumnPriceAUD(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) { private void RenderColumnPriceAUD(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) {
YahooAuctionsItem item = (YahooAuctionsItem)model.GetValue(iter, 0); YahooAuctionsItem item = (YahooAuctionsItem)model.GetValue(iter, 0);
(cell as Gtk.CellRendererText).Text = item.ready ? item.PriceAUD() : "..."; (cell as Gtk.CellRendererText).Text = item.ready ? item.priceAUD : "...";
} }
private void RenderColumnEnding(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) { private void RenderColumnEnding(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) {

View file

@ -18,15 +18,7 @@ namespace Buypeeb {
if (this.watchlist == null) { if (this.watchlist == null) {
// either this is the first time the program has been run, or there's something wrong with userdata.json // either this is the first time the program has been run, or there's something wrong with userdata.json
this.watchlist = new Dictionary<string, YahooAuctionsItem>(); this.watchlist = new Dictionary<string, YahooAuctionsItem>();
// this.Watch("https://buypeeb.biz/whatever/k12345", "my thingy");
// this.Watch("https://buypeeb.biz/whatever/z09876", "your thingy");
// this.Watch("https://buypeeb.biz/whatever/h55555", "our thingy");
// for (int i = 0; i < 10; i++) {
// this.Watch($"https://buypeeb.biz/whatever/x{i * 123}", $"filler {i}");
// }
// this.watchlist["k12345"].Update();
} }
} }
public YahooAuctionsItem Watch(string url, string name) { public YahooAuctionsItem Watch(string url, string name) {

View file

@ -25,7 +25,7 @@ namespace Buypeeb {
// there's not really a need for it i guess but it's my program and i can do what i want // there's not really a need for it i guess but it's my program and i can do what i want
public string id { get; set; } public string id { get; set; }
public string name { get; set; } public string name { get; set; }
public int price = 0; private int price = 0;
public int winPrice; public int winPrice;
public string originalName { get; set; } public string originalName { get; set; }
public string notes { get; set; } public string notes { get; set; }
@ -45,6 +45,32 @@ namespace Buypeeb {
} }
} }
public string priceJPY {
get {
return $"¥{this.price}";
}
}
public string winPriceJPY {
get {
return $"¥{this.winPrice}";
}
}
public string priceAUD {
get {
double aud = this.price / 75.0;
return $"${aud:f2}";
}
}
public string winPriceAUD {
get {
double aud = this.winPrice / 75.0;
return $"${aud:f2}";
}
}
private bool success { get; set; } // TODO: custom setter that throws an exception if set to false or something idk private bool success { get; set; } // TODO: custom setter that throws an exception if set to false or something idk
public YahooAuctionsItem(string id, string name) { public YahooAuctionsItem(string id, string name) {
@ -103,14 +129,5 @@ namespace Buypeeb {
this.autoExtension = (m.Groups[1].Value == "あり"); this.autoExtension = (m.Groups[1].Value == "あり");
} }
} }
public string PriceAUD(bool win = false) {
double aud = win ? this.winPrice / 75.0 : this.price / 75.0;
return $"${aud:f2}";
}
public string PriceJPY(bool win = false) {
return win ? $"¥{this.winPrice}" : $"¥{this.price}";
}
} }
} }

View file

@ -14,6 +14,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CsvHelper" Version="15.0.5" />
<PackageReference Include="GtkSharp" Version="3.22.25.128" /> <PackageReference Include="GtkSharp" Version="3.22.25.128" />
</ItemGroup> </ItemGroup>

View file

@ -185,11 +185,27 @@
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Export as...</property> <property name="tooltip_text" translatable="yes">Save as...</property>
<property name="label" translatable="yes">Export as...</property> <property name="label" translatable="yes">Save as...</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="stock_id">gtk-save-as</property> <property name="stock_id">gtk-save-as</property>
<signal name="clicked" handler="ButtonSaveAsClicked" swapped="no"/> <signal name="clicked" handler="ButtonSaveAsClicked" swapped="no"/>
<accelerator key="s" signal="clicked" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Export</property>
<property name="label" translatable="yes">Export</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-convert</property>
<signal name="clicked" handler="ButtonExportClicked" swapped="no"/>
<accelerator key="e" signal="clicked" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/> <accelerator key="e" signal="clicked" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
</object> </object>
<packing> <packing>