mirror of
https://github.com/norohind/ED-livery-tracker-advanced.git
synced 2025-04-12 15:27:16 +03:00
233 lines
7.5 KiB
Python
233 lines
7.5 KiB
Python
#!/usr/bin/python3
|
|
"""
|
|
It is old version of livery_tracker, bugged in alerting part
|
|
"""
|
|
import json
|
|
import logging
|
|
import queue
|
|
import sys
|
|
import threading
|
|
import time
|
|
|
|
import requests
|
|
|
|
# Dump new raw jsons?
|
|
DUMP = True
|
|
|
|
url = "" # DEMB
|
|
url2 = "" # KISQ
|
|
# url = "" # DEV
|
|
# url2 = "" # DEV 2
|
|
|
|
# setting up logging
|
|
logger = logging.getLogger()
|
|
logger.setLevel(logging.INFO)
|
|
stdout_handler = logging.StreamHandler(sys.stdout)
|
|
logger.addHandler(stdout_handler)
|
|
|
|
localdb_file = "local_storage.json"
|
|
images_base_url = "https://dlc.elitedangerous.com/images/med/"
|
|
|
|
|
|
class Messages_sender(threading.Thread):
|
|
"""Sending message to discord asynchronously"""
|
|
|
|
def __init__(self, url, messages_queue=queue.Queue()):
|
|
threading.Thread.__init__(self)
|
|
self.queue = messages_queue
|
|
self.url = url
|
|
self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}
|
|
|
|
def put(self, message): # put message into queue
|
|
self.queue.put(message)
|
|
|
|
def exit(self, lock=False): # stop messages_sender thread
|
|
self.queue.put('exit')
|
|
if lock:
|
|
self.join()
|
|
|
|
def run(self):
|
|
isStopped = False
|
|
while True:
|
|
if isStopped:
|
|
logger.debug("Got exit message")
|
|
break
|
|
|
|
message_from_queue = self.queue.get()
|
|
|
|
if message_from_queue == "exit":
|
|
logger.debug("Got exit message")
|
|
break
|
|
|
|
message = requests.utils.quote(message_from_queue)
|
|
|
|
try:
|
|
while True:
|
|
logger.debug('===BEGIN OF MESSAGE DUMP===\n' + str(
|
|
f"content={message}".encode('utf-8')) + '\n===END OF MESSAGE DUMP===')
|
|
r = requests.post(self.url, data=f"content={message}".encode('utf-8'), headers=self.headers)
|
|
|
|
if r.status_code == 204: # If success
|
|
logger.debug("Successful sent, status code: " + str({r.status_code}) + ", text: " + r.text)
|
|
time.sleep(1)
|
|
break
|
|
|
|
if r.status_code == 429:
|
|
# We are rate limited, see https://discord.com/developers/docs/topics/rate-limits
|
|
retry_after = int(r.headers["retry-after"]) / 1000
|
|
retry_time = time.time() + retry_after
|
|
logger.debug(
|
|
f"We are rate limited, text: {r.text}\n Will retry after {int(retry_time - time.time())}")
|
|
|
|
while time.time() < retry_time:
|
|
time.sleep(retry_after)
|
|
|
|
continue
|
|
|
|
if r.status_code != 204: # Any others cases
|
|
logger.error(f"Status code: {r.status_code}! {r.text}\nMessage: {message}")
|
|
break
|
|
|
|
except Exception as e:
|
|
logger.warning(f"Got exception in sender thread\n{e}")
|
|
|
|
|
|
# setting up messages sender
|
|
messages_sender = Messages_sender(url)
|
|
messages_sender.start()
|
|
|
|
messages_sender2 = Messages_sender(url2)
|
|
messages_sender2.start()
|
|
|
|
# def get_onlinestore_data():
|
|
# with open("store_sample.json") as store_sample:
|
|
# items = list()
|
|
# for item in json.load(store_sample):
|
|
# items.append({"name": item["title"], "cur_price": item["current_price"], "orig_price": item["original_price"]})
|
|
# return items
|
|
|
|
|
|
def on_exit():
|
|
try:
|
|
with open(localdb_file, "w") as dbfile:
|
|
dbfile.write(json.dumps(online_items))
|
|
except Exception as e:
|
|
logger.error("Got exception on_exit() on file saving:\n" + str(e))
|
|
logger.debug("Waiting for sender thread")
|
|
messages_sender.exit(lock=True)
|
|
messages_sender2.exit(lock=True)
|
|
exit()
|
|
|
|
|
|
def get_onlinestore_data():
|
|
logger.debug("Getting online store data")
|
|
items = list()
|
|
for item in json.loads(requests.get("https://api.zaonce.net/3.0/store/product").text):
|
|
items.append(dict(name=item["title"], cur_price=item["current_price"], orig_price=item["original_price"],
|
|
image=item["image"]))
|
|
logger.debug(f"Got {len(items)} items")
|
|
return items
|
|
|
|
|
|
def get_localstore_data():
|
|
logger.debug("Getting local data")
|
|
try:
|
|
with open(localdb_file) as local:
|
|
data = json.load(local)
|
|
logger.debug(f"Found local data file with {len(data)} items")
|
|
return data
|
|
except FileNotFoundError:
|
|
logger.debug("Didn't found local data file")
|
|
return None
|
|
|
|
|
|
online_items = get_onlinestore_data()
|
|
local_items = get_localstore_data()
|
|
|
|
if local_items is None:
|
|
logger.info("No local data file, creating new one")
|
|
on_exit()
|
|
|
|
if str(online_items) != str(local_items):
|
|
logger.debug("Different data")
|
|
if DUMP:
|
|
logger.debug("DUMP is True, dumping raw json")
|
|
with open(f"{int(time.time())}.json", "w") as file:
|
|
file.write(json.dumps(online_items))
|
|
else:
|
|
logger.debug("No new data, exiting")
|
|
on_exit()
|
|
|
|
for online_item in online_items:
|
|
if online_item not in local_items: # updated or even new item in store
|
|
logger.debug(f"Updated or even new item in store: {online_item}")
|
|
|
|
online_item_name = online_item[
|
|
"name"] # lets try to find item with this name in local db but with different price
|
|
|
|
for local_item in local_items:
|
|
local_item_name = local_item["name"]
|
|
|
|
if online_item_name == local_item_name: # updated price for existing item
|
|
logger.debug(f"Found this item with different price: {local_item}")
|
|
local_item_cur_price = local_item["cur_price"]
|
|
local_item_orig_price = local_item["orig_price"]
|
|
|
|
online_item_item_cur_price = online_item["cur_price"]
|
|
online_item_item_orig_price = online_item["orig_price"]
|
|
|
|
image_url = images_base_url + online_item["image"]
|
|
|
|
message = f"```Change price for known item: {online_item_name}\n\tcurrent price: {local_item_cur_price} -> {online_item_item_cur_price}\n\torig price: {local_item_orig_price} -> {online_item_item_orig_price}\n```\nlink to item image: {image_url}"
|
|
messages_sender.put(message)
|
|
messages_sender2.put(message)
|
|
local_items.remove(local_item)
|
|
find = True
|
|
break
|
|
else: # new item in store. Works if we didn't break line in for
|
|
image_url = images_base_url + online_item["image"]
|
|
message = f"```New item: {online_item['name']}\n\tcurrent price: {online_item['cur_price']}\n\torig price: {online_item['orig_price']}\n```\nlink to item image: {image_url}"
|
|
messages_sender.put(message)
|
|
messages_sender2.put(message)
|
|
continue
|
|
|
|
if find:
|
|
continue
|
|
|
|
local_items.remove(online_item)
|
|
|
|
for removed_item in local_items: # Detecting removed items from store
|
|
message = f"```Item removed: {removed_item['name']}\nLast known prices:\n\tcurrent price: {removed_item['cur_price']}\n\torig_price: {removed_item['orig_price']}```"
|
|
messages_sender.put(message)
|
|
messages_sender2.put(message)
|
|
|
|
on_exit()
|
|
|
|
"""
|
|
livery_tracker.service
|
|
[Unit]
|
|
Description=track frontier livery store for ED
|
|
After=syslog.target
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
User=user2
|
|
WorkingDirectory=/home/user2/livery_tracker
|
|
ExecStart=/home/user2/livery_tracker/livery_tracker.py
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
livery_tracker.timer
|
|
[Unit]
|
|
Description=run livery_tracker
|
|
|
|
[Timer]
|
|
OnCalendar=hourly
|
|
Persistent=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
"""
|