updating actually works, would you look at that
This commit is contained in:
parent
a84e585d21
commit
7bff17c859
4 changed files with 92 additions and 36 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ BuypeebApp.exe
|
|||
bin/
|
||||
obj/
|
||||
out/
|
||||
yahoo.html
|
59
Listing.cs
59
Listing.cs
|
@ -1,9 +1,16 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Buypeeb {
|
||||
class Listing {
|
||||
public string url { get; set; }
|
||||
public string url {
|
||||
get {
|
||||
return $"https://page.auctions.yahoo.co.jp/jp/auction/{this.id}";
|
||||
}
|
||||
}
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public int price = 0;
|
||||
|
@ -15,24 +22,54 @@ namespace Buypeeb {
|
|||
public bool auto_extension;
|
||||
public bool ready;
|
||||
|
||||
public Listing(string url, string id, string name) {
|
||||
this.url = url;
|
||||
private bool success { get; set; } // TODO: custom setter that throws an exception if set to false or something idk
|
||||
|
||||
public Listing(string id, string name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.ready = false;
|
||||
}
|
||||
|
||||
public Listing() {
|
||||
// parameterless constructur for deserialisation
|
||||
// parameterless constructor for deserialisation
|
||||
}
|
||||
|
||||
public void Update() {
|
||||
// use fake values for now
|
||||
var rnd = new Random();
|
||||
this.price = rnd.Next(100, 5000);
|
||||
this.bids = rnd.Next(0, 15);
|
||||
this.name = "testing";
|
||||
this.original_name = "testing";
|
||||
public void Update(string html) {
|
||||
var rx = new Regex(@"var pageData ?= ?(\{.+?\});", RegexOptions.Singleline); // TODO: maybe compile and match the regex in another thread
|
||||
var m = rx.Match(html);
|
||||
if (m == null) {
|
||||
Console.WriteLine("no sir i don't like it");
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, Dictionary<string, string>> j_full;
|
||||
try {
|
||||
// master forgive me, but i must go all out, just this once...
|
||||
j_full = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(m.Groups[1].Value);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
var j = j_full["items"];
|
||||
this.original_name = j["productName"];
|
||||
this.success = int.TryParse(j["price"], out this.price);
|
||||
this.success = int.TryParse(j["winPrice"], out this.win_price);
|
||||
this.success = int.TryParse(j["bids"], out this.bids);
|
||||
|
||||
if (String.IsNullOrWhiteSpace(this.name)) {
|
||||
this.name = this.original_name;
|
||||
}
|
||||
|
||||
// as far as i can tell, neither the `pageData` nor the `conf` variables in the html seem to store whether or not the auction uses automatic extension
|
||||
// the `conf` variable *does* store whether or not the auction has the "early end" feature enabled, in the key `earlyed`.
|
||||
// unfortunately, it seems like the only way to get the auto extension info is to scrape the page for the info column that displays the auto ext status
|
||||
// and check whether or not it's equal to "ari" (japanese for "yes").
|
||||
var autoExtensionCheck = new Regex(@"自動延長.+\n.+>(.+)<");
|
||||
m = rx.Match(html);
|
||||
if (m.Groups[1].Value != null) {
|
||||
this.auto_extension = (m.Groups[1].Value == "あり");
|
||||
}
|
||||
}
|
||||
|
||||
public string PriceAUD() {
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace Buypeeb {
|
|||
class MainWindow : Window {
|
||||
|
||||
private string location;
|
||||
// private Queue<string> statuses;
|
||||
|
||||
private ListStore items;
|
||||
private Settings settings;
|
||||
|
@ -116,6 +117,25 @@ namespace Buypeeb {
|
|||
this.statusLabel.Text = status ?? "Buypeeb";
|
||||
}
|
||||
|
||||
private (TreePath path, TreeIter iter) GetRow(string id) {
|
||||
// TODO: surely there's a better way to do this
|
||||
TreeIter iter;
|
||||
this.itemTreeView.Model.GetIterFirst(out iter);
|
||||
|
||||
for (int i = 0; i < this.itemTreeView.Model.IterNChildren(); i++) {
|
||||
var x = (Listing)this.itemTreeView.Model.GetValue(iter, 0);
|
||||
if (x.id == id) {
|
||||
return (this.itemTreeView.Model.GetPath(iter), iter);
|
||||
}
|
||||
else {
|
||||
this.itemTreeView.Model.IterNext(ref iter);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Couldn't find {id}!");
|
||||
return (null, iter);
|
||||
}
|
||||
|
||||
private void SaveSettings() {
|
||||
string j = JsonSerializer.Serialize(this.settings);
|
||||
string p = System.IO.Path.Combine(this.location, "userdata.json");
|
||||
|
@ -135,33 +155,32 @@ namespace Buypeeb {
|
|||
// set item.ready to false to show that it's still being updated
|
||||
// this changes a few behaviours, such as displaying the price as "..." instead of whatever's currently stored
|
||||
item.ready = false;
|
||||
// TODO: actually download the data
|
||||
Thread.Sleep(3000);
|
||||
string html = "Heeenlo";
|
||||
item.name = html;
|
||||
|
||||
Gtk.Application.Invoke(delegate {
|
||||
// TODO: find a way to not have to do this. i think we need to avoid actually modifying the items outside of the main thread :/
|
||||
var pathAndIter = this.GetRow(id);
|
||||
this.items.EmitRowChanged(pathAndIter.path, pathAndIter.iter);
|
||||
});
|
||||
|
||||
using (WebClient client = new WebClient()) {
|
||||
// TODO: download should have timeout
|
||||
item.Update(client.DownloadString(item.url));
|
||||
// item.Update(File.ReadAllText("yahoo.html"));
|
||||
}
|
||||
|
||||
Gtk.Application.Invoke(delegate {
|
||||
var pathAndIter = this.GetRow(id);
|
||||
this.items.EmitRowChanged(pathAndIter.path, pathAndIter.iter);
|
||||
});
|
||||
|
||||
item.ready = true;
|
||||
Console.WriteLine($"{id} updated.");
|
||||
Gtk.Application.Invoke(delegate {
|
||||
// TODO: surely there's a better way to do this
|
||||
TreeIter iter;
|
||||
this.itemTreeView.Model.GetIterFirst(out iter);
|
||||
|
||||
for (int i = 0; i < this.itemTreeView.Model.IterNChildren(); i++) {
|
||||
var x = (Listing)this.itemTreeView.Model.GetValue(iter, 0);
|
||||
if (x.id == id) {
|
||||
this.items.EmitRowChanged(this.itemTreeView.Model.GetPath(iter), iter);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
this.itemTreeView.Model.IterNext(ref iter);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateItem(string id) {
|
||||
// don't start a new task if there are more than [tasklimit] tasks currently running
|
||||
// this makes sure we don't make 1000 simultaneous requests to yahoo auctions if there are 1000 items on the watchlist
|
||||
this.settings.watchlist[id].ready = false;
|
||||
tasklimit.Wait();
|
||||
var t = Task.Factory.StartNew(() => {
|
||||
this.UpdateThread(id);
|
||||
|
@ -238,7 +257,6 @@ namespace Buypeeb {
|
|||
}
|
||||
|
||||
private void ButtonSaveClicked(object sender, EventArgs a) {
|
||||
Console.WriteLine("ButtonSaveClicked");
|
||||
this.SaveSettings();
|
||||
}
|
||||
|
||||
|
@ -281,17 +299,17 @@ namespace Buypeeb {
|
|||
|
||||
private void RenderColumnPriceYen(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) {
|
||||
Listing item = (Listing)model.GetValue(iter, 0);
|
||||
(cell as Gtk.CellRendererText).Text = 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) {
|
||||
Listing item = (Listing)model.GetValue(iter, 0);
|
||||
(cell as Gtk.CellRendererText).Text = 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) {
|
||||
Listing item = (Listing)model.GetValue(iter, 0);
|
||||
(cell as Gtk.CellRendererText).Text = "whatever";
|
||||
(cell as Gtk.CellRendererText).Text = item.ready ? "whatever" : "...";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Buypeeb {
|
|||
public void Watch(string url, string name) {
|
||||
string id = BuypeebApp.IDFromURL(url);
|
||||
Console.WriteLine(id);
|
||||
this.watchlist[id] = new Listing(url, id, name);
|
||||
this.watchlist[id] = new Listing(id, name);
|
||||
|
||||
foreach (KeyValuePair<string, Listing> entry in this.watchlist) {
|
||||
Console.WriteLine("{0} - {1}", entry.Value.name, entry.Value.price);
|
||||
|
|
Loading…
Reference in a new issue