Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
Got first set of market data added to database. Got item database filled. Fixed some routing issues.
  • Loading branch information
maryjng authored Feb 1, 2022
1 parent 99fd955 commit c5464f2
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 101 deletions.
80 changes: 67 additions & 13 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import os
import requests

from flask import Flask, render_template, flash, redirect, session, g
from flask import Flask, render_template, flash, redirect, session, g, url_for
from flask_debugtoolbar import DebugToolbarExtension
from key import API_KEY, SECRET_KEY

from forms import UserAddForm, LoginForm, TrackItemForm
from models import db, connect_db, User, Item, Shops, Shops_Item, PriceHistory
from models import db, connect_db, User, Item, Shops, Shops_Item, user_item

BASE_URL = "https://api.originsro.org/api/v1/market/list"

Expand All @@ -25,6 +26,8 @@
toolbar = DebugToolbarExtension(app)

connect_db(app)


#########################################################################

@app.before_request
Expand All @@ -38,11 +41,56 @@ def add_user_to_g():
g.user = None


@app.route("/")
@app.route("/home", methods=["GET"])
def index():


return render_template("home.html")


@app.route("/tracking", methods=["GET"])
def trackings():
if g.user:
user = g.user
item_ids = [item.id for item in user.tracked_items]
all_shops = []

for id in item_ids:
shops = (Shops_Item
.query
.filter_by(item_id=id)
.order_by(Shops_Item.price)
.limit(1)
.all())
#ORDER BY price ASC LIMIT 1
item = Item.query.get(id)

shop = {"item_name": item.name,
"item_id": shops.item_id,
"price": shops.price,
"timestamp": shops.timestamp}

all_shops.append(shop)

return render_template("trackings.html", shops=all_shops)

return redirect(url_for("login"))


@app.route("/tracking/<id>", methods=["GET"])
def track_item(id):

if not g.user:
flash("Access unauthorized.", "danger")
return redirect("/login")

user = g.user
prices = db.session.query(Shops_Item).filter(item_id=id).order_by(asc(Shops_Item.price)).all()

return render_template("item_tracking.html", prices=prices)


@app.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm()
Expand All @@ -53,7 +101,7 @@ def login():

session[CURR_USER_KEY] = user.id

return redirect("home.html")
return redirect(url_for("index"))

return render_template("login.html", form=form)

Expand All @@ -62,7 +110,7 @@ def login():
def register():
form = UserAddForm()

if form.validate_on_submit:
if form.validate_on_submit():
try:
User.signup(
username = form.username.data,
Expand All @@ -75,18 +123,18 @@ def register():

except:
flash("Invalid ")
return redirect("register.html")
return render_template("register.html", form=form)

return redirect("home.html")

return render_template("register.html", form=form)


@app.route("/logout", methods=["POST"])
@app.route("/logout")
def logout():
if CURR_USER_KEY in session:
del session[CURR_USER_KEY]
redirect("/index.html")
return redirect(url_for("index"))


@app.route("/add", methods=["GET", "POST"])
Expand All @@ -97,21 +145,27 @@ def add_item():
flash("Access unauthorized.", "danger")
return redirect("/")

user = User.query.get_or_404(id)
# dropdown menu of items in database
items = [(i.id, i.name) for i in Item.query.all()]
form.item_name.choices = items

if form.validate_on_submit:
item_id = form.item_id.data
if form.validate_on_submit():
item_id = form.item_name.data
tracked_items = g.user.tracked_items

item = Item.query.get(item_id)

if item_id not in tracked_items:
g.user.tracked_items.append(item)
tracked_items.append(item)
db.session.commit()

return render_template("home.html")
return render_template("trackings.html")

return render_template("add_item.html", form=form)

##########################################################

return render_template("trackings.html", form=form)
def create_app():
app = Flask(__name__)
db.init_app(app)
return app
2 changes: 1 addition & 1 deletion forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, TextAreaField, IntegerField
from wtforms import StringField, PasswordField, TextAreaField, IntegerField, SelectField
from wtforms.validators import DataRequired, Email, Length

class UserAddForm(FlaskForm):
Expand Down
81 changes: 45 additions & 36 deletions func.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import requests

from key import API_KEY
from models import db, connect_db, Item, Shops, Shops_Item, PriceHistory
from models import db, connect_db, Item, Shops, Shops_Item, User

###############################################################################

items = [{'item_id': 504, 'name': 'White Potion'}, {'item_id': 505, 'name': 'Blue Potion'}, {'item_id': 506, 'name': 'Green Potion'}, {'item_id': 547, 'name': 'Condensed White Potion'}, {'item_id': 1061, 'name': 'Witch Starsand'}, {'item_id': 12016, 'name': 'Speed Potion'}, {'item_id': 602, 'name': 'Butterfly Wing'}, {'item_id': 605, 'name': 'Anodyne'}, {'item_id': 606, 'name': 'Aloevera'}, {'item_id': 607, 'name': 'Yggdrasil Berry'}, {'item_id': 608, 'name': 'Yggdrasil Seed'}, {'item_id': 645, 'name': 'Concentration Potion'}, {'item_id': 656, 'name': 'Awakening Potion'}, {'item_id': 657, 'name': 'Berserk Potion'}, {'item_id': 662, 'name': 'Authoritative Badge'}, {'item_id': 518, 'name': 'Honey'}, {'item_id': 520, 'name': 'Hinalle Leaflet'}, {'item_id': 521, 'name': 'Aloe Leaflet'}, {'item_id': 522, 'name': 'Mastela Fruit'}, {'item_id': 523, 'name': 'Holy Water'}, {'item_id': 525, 'name': 'Panacea'}, {'item_id': 526, 'name': 'Royal Jelly'}, {'item_id': 678, 'name': 'Poison Bottle'}, {'item_id': 12027, 'name': 'Giggling Box'}, {'item_id': 12028, 'name': 'Box of Thunder'}, {'item_id': 12029, 'name': 'Box of Gloom'}, {'item_id': 12030, 'name': 'Box of Resentment'}, {'item_id': 12031, 'name': 'Box of Drowsiness'}, {'item_id': 12032, 'name': 'Box of Storms'}, {'item_id': 12033, 'name': 'Box of Sunlight'}, {'item_id': 12034, 'name': 'Box of Panting'}, {'item_id': 578, 'name': 'Strawberry'}, {'item_id': 715, 'name': 'Yellow Gemstone'}, {'item_id': 716, 'name': 'Red Gemstone'}, {'item_id': 717, 'name': 'Blue Gemstone'}, {'item_id': 7135, 'name': 'Bottle Grenade'}, {'item_id': 7136, 'name': 'Acid Bottle'}, {'item_id': 7139, 'name': 'Glistening Coat'}, {'item_id': 1025, 'name': 'Cobweb'}, {'item_id': 12041, 'name': 'Fried Grasshopper Legs'}, {'item_id': 12042, 'name': 'Seasoned Sticky Webfoot'}, {'item_id': 12043, 'name': 'Bomber Steak'}, {'item_id': 12044, 'name': 'Herb Marinade Beef'}, {'item_id': 12045, 'name': "Lutie Lady's Pancake"}, {'item_id': 12046, 'name': 'Grape Juice Herbal Tea'}, {'item_id': 12047, 'name': 'Autumn Red Tea'}, {'item_id': 12048, 'name': 'Honey Herbal Tea'}, {'item_id': 12049, 'name': 'Morroc Fruit Wine'}, {'item_id': 12050, 'name': 'Mastela Fruit Wine'}, {'item_id': 12051, 'name': 'Steamed Crab Nippers'}, {'item_id': 12052, 'name': 'Assorted Seafood'}, {'item_id': 12053, 'name': 'Clam Soup'}, {'item_id': 12054, 'name': 'Seasoned Jellyfish'}, {'item_id': 12055, 'name': 'Spicy Fried Bao'}, {'item_id': 12056, 'name': 'Frog Egg and Squid Ink Soup'}, {'item_id': 12057, 'name': 'Smooth Noodle'}, {'item_id': 12058, 'name': 'Tentacle and Cheese Gratin'}, {'item_id': 12059, 'name': 'Lutie Cold Noodle'}, {'item_id': 12060, 'name': 'Steamed Bat Wing in Pumpkin'}, {'item_id': 12061, 'name': 'Honey Grape Juice'}, {'item_id': 12062, 'name': 'Chocolate Mousse Cake'}, {'item_id': 12063, 'name': 'Fruit Mix'}, {'item_id': 12064, 'name': 'Cream Sandwich'}, {'item_id': 12065, 'name': 'Green Salad'}, {'item_id': 12066, 'name': 'Fried Monkey Tails'}, {'item_id': 12067, 'name': 'Mixed Juice'}, {'item_id': 12068, 'name': 'Fried Sweet Potato'}, {'item_id': 12069, 'name': 'Steamed Ancient Lips'}, {'item_id': 12070, 'name': 'Fried Scorpion Tails'}, {'item_id': 12071, 'name': 'Shiny Marinade Beef'}, {'item_id': 12072, 'name': 'Whole Roast'}, {'item_id': 12073, 'name': 'Bearfoot Special'}, {'item_id': 12074, 'name': 'Tendon Satay'}, {'item_id': 12075, 'name': 'Steamed Tongue'}, {'item_id': 12076, 'name': 'Red Mushroom Wine'}, {'item_id': 12077, 'name': 'Special Royal Jelly Herbal Tea'}, {'item_id': 12078, 'name': 'Royal Family Tea'}, {'item_id': 12079, 'name': 'Tristan XII'}, {'item_id': 12080, 'name': 'Dragon Breath Cocktail'}, {'item_id': 12081, 'name': 'Awfully Bitter Bracer'}, {'item_id': 12082, 'name': 'Sumptuous Feast'}, {'item_id': 12083, 'name': 'Giant Burrito'}, {'item_id': 12084, 'name': 'Ascending Dragon Soup'}, {'item_id': 12085, 'name': 'Immortal Stew'}, {'item_id': 12086, 'name': 'Chile Shrimp Gratin'}, {'item_id': 12087, 'name': 'Steamed Alligator with Vegetables'}, {'item_id': 12088, 'name': 'Incredibly Spicy Curry'}, {'item_id': 12089, 'name': 'Special Meat Stew'}, {'item_id': 12090, 'name': 'Steamed Desert Scorpions'}, {'item_id': 12091, 'name': 'Peach Cake'}, {'item_id': 12092, 'name': 'Soul Haunted Bread'}, {'item_id': 12093, 'name': 'Special Toast'}, {'item_id': 12094, 'name': 'Heavenly Fruit Juice'}, {'item_id': 12095, 'name': "Hvergelmir's Tonic"}, {'item_id': 12096, 'name': 'Lucky Soup'}, {'item_id': 12097, 'name': 'Assorted Shish Kebob'}, {'item_id': 12098, 'name': 'Strawberry Flavored Rice Ball'}, {'item_id': 12099, 'name': 'Blood Flavored Soda'}, {'item_id': 12100, 'name': "Cooked Nine Tail's Tails"}, {'item_id': 4133, 'name': 'Raydric Card'}, {'item_id': 4058, 'name': 'Thara Frog Card'}, {'item_id': 4105, 'name': 'Marc Card'}, {'item_id': 4044, 'name': 'Smokie Card'}, {'item_id': 4045, 'name': 'Horn Card'}, {'item_id': 4035, 'name': 'Hydra Card'}, {'item_id': 4252, 'name': 'Alligator Card'}, {'item_id': 4092, 'name': 'Skeleton Worker Card'}, {'item_id': 4082, 'name': 'Desert Wolf Card'}, {'item_id': 4381, 'name': 'Green Ferus Card'}, {'item_id': 4160, 'name': 'Firelock Soldier Card'}, {'item_id': 4170, 'name': 'Dark Frame Card'}, {'item_id': 4107, 'name': 'Verit Card'}, {'item_id': 4064, 'name': 'Zerom Card'}, {'item_id': 4088, 'name': 'Frilldora Card'}, {'item_id': 4097, 'name': 'Matyr Card'}, {'item_id': 4098, 'name': 'Dokebi Card'}, {'item_id': 4099, 'name': 'Pasana Card'}, {'item_id': 4089, 'name': 'Swordfish Card'}, {'item_id': 2115, 'name': "Valkyrja's Shield"}, {'item_id': 2289, 'name': 'Poo Poo Hat'}, {'item_id': 2291, 'name': 'Masquerade'}, {'item_id': 1261, 'name': 'Infiltrator'}, {'item_id': 1264, 'name': 'Specialty Jur'}, {'item_id': 1265, 'name': 'Bloody Roar'}, {'item_id': 2353, 'name': "Odin's Blessing"}, {'item_id': 5128, 'name': "Goibne's Helm"}, {'item_id': 2354, 'name': "Goibne's Armor"}, {'item_id': 2520, 'name': "Goibne's Spaulders"}, {'item_id': 2419, 'name': "Goibne's Greaves"}, {'item_id': 2604, 'name': 'Glove'}, {'item_id': 2624, 'name': 'Glove'}, {'item_id': 2605, 'name': 'Brooch'}, {'item_id': 2625, 'name': 'Brooch'}, {'item_id': 2608, 'name': 'Rosary'}, {'item_id': 2626, 'name': 'Rosary'}, {'item_id': 2607, 'name': 'Clip'}, {'item_id': 2619, 'name': 'Bow Thimble'}, {'item_id': 2671, 'name': 'Bow Thimble'}, {'item_id': 1228, 'name': 'Combat Knife'}, {'item_id': 1525, 'name': 'Long Mace'}, {'item_id': 2502, 'name': 'Hood'}, {'item_id': 2504, 'name': 'Muffler'}, {'item_id': 2506, 'name': 'Manteau'}, {'item_id': 2402, 'name': 'Sandals'}, {'item_id': 2404, 'name': 'Shoes'}, {'item_id': 2406, 'name': 'Boots'}, {'item_id': 2102, 'name': 'Guard'}, {'item_id': 2104, 'name': 'Buckler'}, {'item_id': 2106, 'name': 'Shield'}, {'item_id': 2107, 'name': 'Mirror Shield'}, {'item_id': 2108, 'name': 'Mirror Shield'}, {'item_id': 2121, 'name': 'Memory Book'}, {'item_id': 5170, 'name': 'Feather Beret'}, {'item_id': 2513, 'name': 'Heavenly Maiden Robe'}, {'item_id': 2523, 'name': 'Undershirt'}, {'item_id': 2322, 'name': 'Silk Robe'}, {'item_id': 1705, 'name': 'Composite Bow'}, {'item_id': 1408, 'name': 'Pike'}, {'item_id': 1520, 'name': 'Chain'}, {'item_id': 1208, 'name': 'Main Gauche'}, {'item_id': 1117, 'name': 'Katana'}]

item_ids = [item.item_id for item in items]

# def ping_API():
# return requests.get("https://api.originsro.org/api/v1/ping")
#
Expand All @@ -18,7 +23,6 @@
# for item in items_res["items"]:
# dict = {}
# dict["item_id"] = item["item_id"]
# dict["unique_name"] = item["unique_name"]
# dict["name"] = item["name"]
#
# items_data.append(dict)
Expand All @@ -33,58 +37,63 @@ def populate_items_db():
db.session.add(row)
db.session.commit()

#automate this request to occur at set intervals

def get_current_data():
shops = requests.get("https://api.originsro.org/api/v1/market/list", params={"api_key": API_KEY})
shops_res = shops.json()

return shops_res

def organize_results(res):

def store_results(res):
shops = requests.get("https://api.originsro.org/api/v1/market/list", params={"api_key": API_KEY})
shops_res = shops.json()

shops_data = []
prices_data = []

#get Shops data
for shop in res["shops"]:
shops = {}
location = shop["location"]

shops["map_location"] = location["map"]
shops["map_x"] = location["x"]
shops["map_y"] = location["y"]
shops["title"] = shop["title"]
shops["owner"] = shop["owner"]
for shop in shops_res["shops"]:
for item in shop["items"]:
if item["item_id"] in item_ids:

shops_data.append(shops)
location = shop["location"]
#
# try:
db.session.add(Shops(owner=shop["owner"],
title=shop["title"],
map_location=location["map"],
map_x=location["x"],
map_y=location["y"])
)

#get PriceHistory data
for item in res["items"]:
prices = {}
# except:
# print(f"Failed to add {shop_obj} to the Shops table.")

prices["item_id"] = item["item_id"]
prices["cost"] = item["price"]
prices["owner"] = shop["owner"]
prices["timestamp"] = res["generation_timestamp"]
#get price history data
# for item in shops_res["items"]:

prices_data.append(prices)
# try:
db.session.add(Shops_Item(item_id=item["item_id"],
price=item["price"],
owner=shop["owner"],
timestamp=shop["creation_date"])
)

return (shops_data, prices_data)
break
# except:
# print(f"Failed to add {shop_item} to the Shops_Item table.")

def store_res_data((shops, prices)):
all_shops = [Shops(shop) for shop in shops]
all_prices = [PriceHistory(price) for price in prices]
db.session.commit()

try:
db.session.add(all_shops)
db.session.add(all_prices)
db.session.commit()
except:
print("Did not work")

def request_and_store_data():
res = get_current_data()
(shops_data, prices_data) = organize_results(res)
store_res_data((shops_data, prices_data))
print("Done.")
store_results(res)

#delete rows where timestamp < DATEADD(d, -30, GETDATE())

print("done running")

schedule.every(15).minutes.do(request_and_store_data)
#automate the above request and data storage for every 15 mins
# schedule.every(15).minutes.do(request_and_store_data)
48 changes: 28 additions & 20 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,25 @@
bcrypt = Bcrypt()
db = SQLAlchemy()

#table showing relationships between User and Item tables
user_item = db.Table('user_item',
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('item_id', db.Integer, db.ForeignKey('items.id'))
)

class User(db.Model):
__tablename__ = 'users'
__tablename__ = "users"

id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.Text, nullable=False, unique=True)
username = db.Column(db.Text, nullable=False, unique=True)
password = db.Column(db.Text, nullable=False)

tracked_items = db.relationship("Item")
tracked_items = db.relationship(
"Item",
secondary="user_item",
backref="following_users"
)

@classmethod
def signup(cls, username, email, password):
Expand Down Expand Up @@ -44,44 +54,42 @@ def authenticate(cls, username, password):

return False


class Item(db.Model):
"""All items in the game"""
""" All items in the game """

__tablename__ = "items"

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, nullable=False)
unique_name = db.Column(db.Text, nullable=False)

current_shops = db.relationship("Shops_Item", backref="Item")
current_shops = db.relationship("Shops", secondary="shops_item", backref="item")


class Shops(db.Model):
"""Shops currently open."""
""" Shops currently open """

__tablename__ = "shops"

owner = db.Column(db.Text, primary_key=True)
title = db.Column(db.Text, nullable=False)
map_location = db.Column(db.Text, nullable=False)
map_x = db.Column(db.Integer, nullable=False)
map_y = db.Column(db.Integer, nullable=False)

items = db.relationship("Shops_Item", backref="Shops")
#need to somehow include cost for each item
items = db.relationship("Item", secondary="shops_item", backref="shops")

class Shops_Item(db.Model):
"""Items currently in shops and their prices"""

owner = db.Column(db.ForeignKey(Shops.owner), primary_key=True)
item_id = db.Column(db.ForeignKey(Item.id), primary_key=True)
price = db.Column(db.Integer, nullable=False)
class Shops_Item(db.Model):
""" Items currently in shops and their prices plus when the shop was opened """

class PriceHistory(db.Model):
"""Historical prices for all items"""
__tablename__ = "shops_item"

item_id = db.Column(db.Text, nullable=False)
owner = db.Column(db.ForeignKey("shops.owner"), primary_key=True)
item_id = db.Column(db.ForeignKey("items.id"), primary_key=True)
price = db.Column(db.Integer, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False)
#timestamp is WHEN the data was REQUESTED
cost = db.Column(db.Integer, nullable=False)
owner = db.Column(db.ForeignKey(Shops.owner), primary_key=True)

#only care about shop data if shops are from most recent request

def connect_db(app):
db.app = app
Expand Down
15 changes: 6 additions & 9 deletions templates/add_item.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
<form method="POST" id="TrackItemForm">
{{ form.csrf_token }}
<div>
{% if form.text.errors %}
{% for error in form.text.errors %}
<span class="text-danger">
{{ error }}
</span>
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{% for error in field.errors %}
<span class="text-danger">{{ error }}</span>
{% endfor %}
{% endif %}

{{ form.text }}

{{ field(placeholder=field.label.text, class="form-control") }}
{% endfor %}
</div>
<button class>Add Item</button>
</form>
Expand Down
Loading

0 comments on commit c5464f2

Please sign in to comment.