Skip to content

Commit 995aede

Browse files
committed
Remove Shanghai Silver website scraping
- Removed goldsilver.ai price fetching code - Removed get_shanghai_silver_price() and _extract_price_after() - Removed SSILVER handling from get_price() - Removed SHANGHAISILVER from DISPLAY_NAME_MAP - Using working commit 4f9e415 as base
1 parent aa7942c commit 995aede

1 file changed

Lines changed: 28 additions & 79 deletions

File tree

price_service.py

Lines changed: 28 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Price fetching service using Pyth Network API.
33
"""
4+
45
import logging
56
import os
67
import re
@@ -11,85 +12,37 @@
1112
logger = logging.getLogger(__name__)
1213

1314
HERMES_API_URL = "https://hermes.pyth.network/api/latest_price_feeds"
14-
GOLDSILVER_AI_URL = "https://goldsilver.ai/metal-prices/shanghai-silver-price"
1515

1616

1717
class PriceService:
1818
def __init__(self):
1919
self.feeds = self._load_feeds()
2020
self.session: Optional[aiohttp.ClientSession] = None
21-
21+
2222
def _load_feeds(self) -> dict:
2323
"""Load feed IDs from environment."""
2424
feeds_str = os.environ.get(
2525
"CRYPTO_FEEDS",
2626
"BTC:0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43,"
2727
"ETH:0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace,"
28-
"SOL:0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"
28+
"SOL:0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d",
2929
)
30-
30+
3131
feeds = {}
3232
for pair in feeds_str.split(","):
3333
if ":" in pair:
3434
name, feed_id = pair.split(":", 1)
3535
feeds[name.strip().upper()] = feed_id.strip()
36-
36+
3737
logger.info(f"Loaded {len(feeds)} price feeds")
3838
return feeds
39-
39+
4040
async def _get_session(self) -> aiohttp.ClientSession:
4141
if self.session is None or self.session.closed:
4242
timeout = aiohttp.ClientTimeout(total=15)
4343
self.session = aiohttp.ClientSession(timeout=timeout)
4444
return self.session
45-
46-
async def get_shanghai_silver_price(self) -> Optional[float]:
47-
"""Fetch Shanghai Silver price from goldsilver.ai."""
48-
try:
49-
session = await self._get_session()
50-
headers = {
51-
"User-Agent": "RustyMcPriceface/1.0 (crypto price bot)",
52-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
53-
"Accept-Language": "en-US,en;q=0.9",
54-
}
55-
async with session.get(GOLDSILVER_AI_URL, headers=headers) as resp:
56-
if resp.status != 200:
57-
logger.warning(f"goldsilver.ai returned {resp.status}")
58-
return None
59-
60-
text = await resp.text()
61-
62-
# Extract number after "Shanghai Spot" and "$"
63-
shanghai_price = self._extract_price_after(text, "Shanghai Spot")
64-
if shanghai_price and shanghai_price > 10:
65-
logger.info(f"Shanghai Silver: ${shanghai_price}")
66-
return shanghai_price
67-
68-
logger.warning("Could not extract valid Shanghai price")
69-
return None
70-
71-
except Exception as e:
72-
logger.error(f"Failed to fetch Shanghai Silver: {e}")
73-
return None
74-
75-
def _extract_price_after(self, html: str, prefix: str) -> Optional[float]:
76-
"""Extract dollar amount after a prefix."""
77-
pos = html.find(prefix)
78-
if pos == -1:
79-
return None
80-
81-
after = html[pos:pos+200]
82-
83-
# Find $ followed by number
84-
match = re.search(r'\$([0-9,]+\.?[0-9]*)', after)
85-
if match:
86-
price_str = match.group(1).replace(",", "")
87-
try:
88-
return float(price_str)
89-
except ValueError:
90-
return None
91-
return None
92-
45+
9346
async def get_yahoo_price(self, ticker: str) -> Optional[float]:
9447
"""Fetch price from Yahoo Finance API."""
9548
try:
@@ -102,79 +55,75 @@ async def get_yahoo_price(self, ticker: str) -> Optional[float]:
10255
if resp.status != 200:
10356
logger.warning(f"Yahoo returned {resp.status} for {ticker}")
10457
return None
105-
58+
10659
data = await resp.json()
107-
60+
10861
# Extract price from Yahoo Finance JSON structure
10962
result = data.get("chart", {}).get("result", [])
11063
if not result:
11164
logger.warning(f"No result from Yahoo for {ticker}")
11265
return None
113-
66+
11467
meta = result[0].get("meta", {})
11568
price = meta.get("regularMarketPrice")
116-
69+
11770
if price:
11871
logger.info(f"Yahoo {ticker}: {price}")
11972
return float(price)
120-
73+
12174
logger.warning(f"No price in Yahoo response for {ticker}")
12275
return None
123-
76+
12477
except Exception as e:
12578
logger.error(f"Failed to fetch {ticker} from Yahoo: {e}")
12679
return None
127-
80+
12881
async def get_price(self, crypto: str) -> Optional[float]:
12982
"""Get price for a single cryptocurrency."""
13083
crypto = crypto.upper()
131-
132-
# Special handling for Shanghai Silver (not in Pyth feeds)
133-
if crypto == "SSILVER":
134-
return await self.get_shanghai_silver_price()
135-
84+
13685
# Special handling for DXY (Yahoo Finance)
13786
if crypto == "DXY":
13887
return await self.get_yahoo_price("DX-Y.NYB")
139-
88+
14089
if crypto not in self.feeds:
14190
logger.warning(f"No feed ID for {crypto}")
14291
return None
143-
92+
14493
feed_id = self.feeds[crypto]
14594
url = f"{HERMES_API_URL}?ids[]={feed_id}"
146-
95+
14796
try:
14897
session = await self._get_session()
14998
async with session.get(url) as resp:
15099
if resp.status != 200:
151100
logger.warning(f"Pyth API returned {resp.status} for {crypto}")
152101
return None
153-
102+
154103
data = await resp.json()
155104
if not data or not isinstance(data, list):
156105
return None
157-
106+
158107
price_data = data[0].get("price", {})
159108
price_str = price_data.get("price")
160109
expo = price_data.get("expo", 0)
161-
110+
162111
if price_str is None:
163112
return None
164-
165-
price = int(price_str) * (10 ** expo)
166-
113+
114+
price = int(price_str) * (10**expo)
115+
167116
if price <= 0:
168117
logger.warning(f"Invalid price {price} for {crypto}")
169118
return None
170-
119+
171120
logger.debug(f"Fetched {crypto} price: ${price}")
172121
return float(price)
173-
122+
174123
except Exception as e:
175124
logger.error(f"Failed to fetch {crypto} price: {e}")
176125
return None
177-
126+
178127
async def get_all_prices(self) -> dict:
179128
"""Get prices for all configured cryptocurrencies."""
180129
results = {}
@@ -183,7 +132,7 @@ async def get_all_prices(self) -> dict:
183132
if price:
184133
results[crypto] = price
185134
return results
186-
135+
187136
async def close(self):
188137
"""Close the HTTP session."""
189138
if self.session and not self.session.closed:

0 commit comments

Comments
 (0)