117 lines
4.1 KiB
C#
117 lines
4.1 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Text.RegularExpressions;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json;
|
|
|
|
namespace Buypeeb {
|
|
class YahooAuctionsItem {
|
|
public string url {
|
|
get {
|
|
return $"https://page.auctions.yahoo.co.jp/jp/auction/{this.id}";
|
|
}
|
|
}
|
|
|
|
public string buyeeUrl {
|
|
get {
|
|
return $"https://buyee.jp/item/yahoo/auction/{this.id}";
|
|
}
|
|
}
|
|
|
|
// any items with a getter will be saved to userdata.json
|
|
// anything that's configurable by the user, such as the custom name, should be saved
|
|
// the id *must* be saved!
|
|
// i'm also saving the original name to make it easier to tell what the items are in the userdata.json
|
|
// 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 name { get; set; }
|
|
public int price = 0;
|
|
public int winPrice;
|
|
public string originalName { get; set; }
|
|
public string notes { get; set; }
|
|
public bool favourite { get; set; } = false;
|
|
public DateTime startDate;
|
|
public DateTime endDate;
|
|
public DateTime lastUpdated;
|
|
public int bids;
|
|
public bool autoExtension;
|
|
public bool ready;
|
|
public bool available;
|
|
|
|
public bool updatedRecently {
|
|
get {
|
|
var later = this.lastUpdated.AddSeconds(15);
|
|
return DateTime.Compare(later, this.lastUpdated) < 0;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
this.id = id;
|
|
this.name = name;
|
|
this.ready = false;
|
|
}
|
|
|
|
public YahooAuctionsItem() {
|
|
// parameterless constructor for deserialisation
|
|
}
|
|
|
|
public void Update(string html) {
|
|
// TODO: handle all the parsing errors and weird interpretation that could possibly happen here
|
|
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) {
|
|
Console.WriteLine("oh jeez oh man oh jeez oh man oh jeez oh man");
|
|
Console.WriteLine(m.Groups[1].Value);
|
|
throw e;
|
|
}
|
|
|
|
var jst = TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo");
|
|
|
|
var j = j_full["items"];
|
|
this.originalName = j["productName"];
|
|
this.startDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.ParseExact(j["starttime"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), jst);
|
|
this.endDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.ParseExact(j["endtime"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), jst);
|
|
this.lastUpdated = DateTime.UtcNow;
|
|
this.available = j["isClosed"] == "0";
|
|
|
|
this.success = int.TryParse(j["price"], out this.price);
|
|
this.success = int.TryParse(j["winPrice"], out this.winPrice);
|
|
this.success = int.TryParse(j["bids"], out this.bids);
|
|
|
|
if (String.IsNullOrWhiteSpace(this.name)) {
|
|
this.name = this.originalName;
|
|
}
|
|
|
|
// 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.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}";
|
|
}
|
|
}
|
|
}
|