updating actually works, would you look at that

This commit is contained in:
Lynne Megido 2020-09-04 02:09:19 +10:00
parent a84e585d21
commit 7bff17c859
Signed by: lynnesbian
GPG Key ID: F0A184B5213D9F90
4 changed files with 92 additions and 36 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ BuypeebApp.exe
bin/
obj/
out/
yahoo.html

View File

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

View File

@ -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" : "...";
}
}

View File

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