2020-08-10 09:34:24 +00:00
|
|
|
import requests
|
|
|
|
|
|
|
|
import re, json
|
|
|
|
from datetime import datetime, timezone, timedelta
|
|
|
|
|
2020-08-21 10:52:03 +00:00
|
|
|
import functions
|
|
|
|
|
2020-08-10 09:34:24 +00:00
|
|
|
JST = timezone(timedelta(hours = 9))
|
|
|
|
|
2020-08-21 10:32:43 +00:00
|
|
|
class YahooAuctionsItem:
|
2020-08-23 10:03:08 +00:00
|
|
|
"""
|
|
|
|
A class for handling items on Yahoo! Auctions Japan
|
|
|
|
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
----------
|
|
|
|
name : str
|
|
|
|
The name given to the auction item by the user.
|
|
|
|
|
|
|
|
original_name : str
|
|
|
|
The name as it appears on Y!A,
|
|
|
|
|
|
|
|
favourite : bool
|
|
|
|
Whether or not the user has "favourited" this item.
|
|
|
|
|
|
|
|
url : bool
|
|
|
|
The URL this item was added from. If not provided, defaults to https://buyee.jp/item/yahoo/auction/{id}.
|
|
|
|
|
|
|
|
id : str
|
|
|
|
The ID of the item, found at the end of the URL.
|
|
|
|
|
|
|
|
last_checked : datetime
|
|
|
|
The time that the item's status was last checked by buypeeb.
|
|
|
|
|
|
|
|
available : bool
|
|
|
|
Whether or not the item is still available (if the auction is still available)
|
|
|
|
|
|
|
|
ready : bool
|
|
|
|
Whether or not the object is ready. If not, some of the data (price, available, etc.) may be out of date or unset.
|
|
|
|
|
|
|
|
updating : bool
|
|
|
|
If true, the object is currently being updated. Should never be true if ready is true.
|
|
|
|
|
|
|
|
price : float
|
|
|
|
The price of the item in yen.
|
|
|
|
|
|
|
|
bids : int
|
|
|
|
The number of bids that have been placed on the item.
|
|
|
|
|
|
|
|
start_date : datetime
|
|
|
|
The start date and time of the item in JST.
|
|
|
|
|
|
|
|
end_date : datetime
|
|
|
|
The end date and time of the item in JST.
|
|
|
|
"""
|
2020-08-23 14:47:40 +00:00
|
|
|
def __init__(self, url: str, id: str, name: str = "", from_json: dict = None):
|
2020-08-21 10:52:03 +00:00
|
|
|
# note - incoming url is not validated in any way!
|
|
|
|
self.name = name
|
2020-08-23 11:18:11 +00:00
|
|
|
self.price = 0
|
2020-08-23 14:47:40 +00:00
|
|
|
self.original_name = ""
|
2020-08-23 11:18:11 +00:00
|
|
|
self.favourite = None
|
2020-08-23 11:29:53 +00:00
|
|
|
self.end_date = None
|
2020-08-23 12:40:43 +00:00
|
|
|
self.bids = 0
|
2020-08-24 08:09:46 +00:00
|
|
|
self.auto_extension = None
|
|
|
|
self.rate = 75.0
|
2020-08-23 11:18:11 +00:00
|
|
|
|
2020-08-22 09:26:09 +00:00
|
|
|
if url == None and from_json != None and id != None:
|
|
|
|
self.id = id
|
2020-08-22 08:55:15 +00:00
|
|
|
self.name = from_json['name']
|
2020-08-23 15:00:05 +00:00
|
|
|
self.original_name = from_json['original_name']
|
2020-08-23 14:47:40 +00:00
|
|
|
if self.name == "":
|
|
|
|
self.name = self.original_name
|
2020-08-22 08:55:15 +00:00
|
|
|
self.favourite = from_json['favourite']
|
|
|
|
self.url = f"https://buyee.jp/item/yahoo/auction/{self.id}"
|
|
|
|
|
2020-08-22 09:26:09 +00:00
|
|
|
elif url != None and id != None:
|
|
|
|
self.url = url
|
|
|
|
self.id = id
|
2020-08-22 08:55:15 +00:00
|
|
|
|
2020-08-22 09:26:09 +00:00
|
|
|
else:
|
|
|
|
raise RuntimeError
|
2020-08-22 08:55:15 +00:00
|
|
|
|
2020-08-21 10:52:03 +00:00
|
|
|
self.last_checked = datetime.fromisoformat('1970-01-01')
|
|
|
|
self.available = True
|
2020-08-23 10:03:08 +00:00
|
|
|
self.ready = False
|
|
|
|
self.updating = False
|
2020-08-10 09:34:24 +00:00
|
|
|
|
|
|
|
def update(self):
|
2020-08-23 11:18:11 +00:00
|
|
|
self.updating = True
|
2020-08-10 09:34:24 +00:00
|
|
|
try:
|
2020-08-21 10:52:03 +00:00
|
|
|
# the good news is, yahoo japan returns all the data we need in handy json format
|
|
|
|
# the bad news is that the only way to get that json format is to download the whole auction page and grep it
|
|
|
|
|
2020-08-23 12:36:41 +00:00
|
|
|
r = requests.get(f"https://page.auctions.yahoo.co.jp/jp/auction/{self.id}").text
|
|
|
|
# r = open("yahoo.html").read()
|
2020-08-10 09:34:24 +00:00
|
|
|
j = json.loads(re.match(r'.*var pageData ?= ?(\{.*?\});', r, re.DOTALL).group(1))
|
2020-08-24 07:41:23 +00:00
|
|
|
ae = re.match(r'自動延長.+\n.+>(.+)<.+', r)
|
|
|
|
if ae != None:
|
|
|
|
ae = re.group(1)
|
2020-08-24 08:09:46 +00:00
|
|
|
self.auto_extension = (ae == "あり")
|
2020-08-24 07:41:23 +00:00
|
|
|
|
2020-08-10 09:34:24 +00:00
|
|
|
except:
|
|
|
|
raise
|
|
|
|
|
|
|
|
j = j['items']
|
|
|
|
self.price = float(j['price'])
|
2020-08-24 08:09:46 +00:00
|
|
|
self.win_price = float(j['winPrice'])
|
2020-08-10 09:34:24 +00:00
|
|
|
self.bids = j['bids']
|
|
|
|
self.start_date = datetime.fromisoformat(j['starttime']).replace(tzinfo = JST)
|
|
|
|
self.end_date = datetime.fromisoformat(j['endtime']).replace(tzinfo = JST)
|
|
|
|
self.last_checked = datetime.now(JST)
|
2020-08-22 08:55:15 +00:00
|
|
|
self.original_name = j['productName']
|
2020-08-23 14:47:40 +00:00
|
|
|
if self.name == None or self.name == "":
|
2020-08-22 08:55:15 +00:00
|
|
|
self.name = j['productName']
|
2020-08-10 09:34:24 +00:00
|
|
|
|
2020-08-23 11:18:11 +00:00
|
|
|
self.ready = True
|
|
|
|
self.updating = False
|
|
|
|
|
2020-08-23 14:47:40 +00:00
|
|
|
return self.id, self
|
2020-08-23 13:28:48 +00:00
|
|
|
|
2020-08-24 08:09:46 +00:00
|
|
|
def price_jpy(self, win = False):
|
|
|
|
p = self.price
|
|
|
|
if win:
|
|
|
|
p = self.win_price
|
|
|
|
return f"¥{p:.0f}"
|
2020-08-10 09:34:24 +00:00
|
|
|
|
2020-08-24 08:09:46 +00:00
|
|
|
def price_aud(self, rate = 0, win = False):
|
|
|
|
if rate == 0:
|
|
|
|
rate = self.rate
|
|
|
|
else:
|
|
|
|
self.rate = rate
|
|
|
|
|
|
|
|
p = self.price
|
|
|
|
if win:
|
|
|
|
p = self.win_price
|
2020-08-10 09:34:24 +00:00
|
|
|
return f"${self.price / rate:.2f}"
|
2020-08-23 12:17:33 +00:00
|
|
|
|
|
|
|
def ending_in(self):
|
|
|
|
return "heenlo"
|
2020-08-23 12:59:56 +00:00
|
|
|
|
|
|
|
def ending_at(self):
|
|
|
|
now = datetime.now()
|
|
|
|
ndate = now.strftime("%d %b")
|
|
|
|
if self.end_date != None:
|
|
|
|
idate, itime = self.end_date.strftime("%d %b"), self.end_date.strftime("%H:%M")
|
|
|
|
if idate == ndate:
|
|
|
|
return itime
|
|
|
|
else:
|
|
|
|
return f"{idate} {itime}"
|