post and get slates
This commit is contained in:
commit
bb960d99fd
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
*__pycache__*
|
||||||
|
settings.py
|
||||||
|
.cache
|
||||||
|
.env
|
||||||
|
htmlcov
|
||||||
|
.coverage
|
||||||
|
funding/static/qr/*
|
||||||
|
yourvirtualenviornment/
|
||||||
|
venv/
|
||||||
|
.idea/
|
9
LICENSE
Normal file
9
LICENSE
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
Version 2, December 2004
|
||||||
|
|
||||||
|
Copyright (C) 2018 Wownero Inc., a Monero Enterprise Alliance partner company
|
||||||
|
|
||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. You just DO WHAT THE FUCK YOU WANT TO.
|
48
README.md
Normal file
48
README.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Epic Post
|
||||||
|
|
||||||
|
A simple alternative to epic box.
|
||||||
|
|
||||||
|
### Install postgres
|
||||||
|
```
|
||||||
|
sudo apt install aptitude
|
||||||
|
sudo aptitude install postgresql postgresql-contrib
|
||||||
|
```
|
||||||
|
https://tecadmin.net/how-to-install-postgresql-in-ubuntu-20-04/
|
||||||
|
|
||||||
|
|
||||||
|
### Web application
|
||||||
|
|
||||||
|
Download application and configure.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
sudo apt install libjpeg-dev libpng-dev python3 redis-server postgresql-server-dev-*
|
||||||
|
sudo apt install python3-virtualenv
|
||||||
|
sudo apt install python3-venv
|
||||||
|
git clone https://github.com/firoorg/fcs.git
|
||||||
|
cd epicpost
|
||||||
|
python3 -m venv yourvirtualenviornment
|
||||||
|
source yourvirtualenviornment/bin/activate
|
||||||
|
pip uninstall pillow
|
||||||
|
pip install wheel
|
||||||
|
pip install -r requirements.txt
|
||||||
|
CC="cc -mavx2" pip install -U --force-reinstall pillow-simd
|
||||||
|
cp settings.py_example settings.py
|
||||||
|
- change settings.py accordingly
|
||||||
|
```
|
||||||
|
eg change the psql_pass to your database password, psql_db to your database name
|
||||||
|
|
||||||
|
Run the application:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python run_dev.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Beware `run_dev.py` is meant as a development server.
|
||||||
|
|
||||||
|
When running behind nginx/apache, inject `X-Forwarded-For`.
|
||||||
|
|
||||||
|
|
||||||
|
### License
|
||||||
|
|
||||||
|
© 2022 WTFPL – Do What the Fuck You Want to Public License
|
0
funding/__init__.py
Normal file
0
funding/__init__.py
Normal file
0
funding/bin/__init__.py
Normal file
0
funding/bin/__init__.py
Normal file
7
funding/bin/utils.py
Normal file
7
funding/bin/utils.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from datetime import datetime, date
|
||||||
|
|
||||||
|
|
||||||
|
def json_encoder(obj):
|
||||||
|
if isinstance(obj, (datetime, date)):
|
||||||
|
return obj.isoformat()
|
||||||
|
raise TypeError("Type %s not serializable" % type(obj))
|
28
funding/bin/utils_request.py
Normal file
28
funding/bin/utils_request.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from flask import request
|
||||||
|
import settings
|
||||||
|
from funding.factory import app, db
|
||||||
|
|
||||||
|
|
||||||
|
@app.before_request
|
||||||
|
def before_request():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def after_request(res):
|
||||||
|
res.headers.add('Accept-Ranges', 'bytes')
|
||||||
|
|
||||||
|
if request.full_path.startswith('/api/'):
|
||||||
|
res.headers.add('Access-Control-Allow-Origin', '*')
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
res.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
|
||||||
|
res.headers['Pragma'] = 'no-cache'
|
||||||
|
res.headers['Expires'] = '0'
|
||||||
|
res.headers['Cache-Control'] = 'public, max-age=0'
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def error(err):
|
||||||
|
return 'Error', 404
|
163
funding/bin/utils_time.py
Normal file
163
funding/bin/utils_time.py
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
from datetime import datetime, date
|
||||||
|
from dateutil import parser
|
||||||
|
import math
|
||||||
|
import calendar
|
||||||
|
|
||||||
|
|
||||||
|
class TimeMagic():
|
||||||
|
def __init__(self):
|
||||||
|
self.now = datetime.now()
|
||||||
|
self.weekdays_en = {
|
||||||
|
0: 'monday',
|
||||||
|
1: 'tuesday',
|
||||||
|
2: 'wednesday',
|
||||||
|
3: 'thursday',
|
||||||
|
4: 'friday',
|
||||||
|
5: 'saturday',
|
||||||
|
6: 'sunday'
|
||||||
|
}
|
||||||
|
self.months_en = {
|
||||||
|
0: 'january',
|
||||||
|
1: 'february',
|
||||||
|
2: 'march',
|
||||||
|
3: 'april',
|
||||||
|
4: 'may',
|
||||||
|
5: 'june',
|
||||||
|
6: 'july',
|
||||||
|
7: 'august',
|
||||||
|
8: 'september',
|
||||||
|
9: 'october',
|
||||||
|
10: 'november',
|
||||||
|
11: 'december'
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_weekday_from_datetime(self, dt):
|
||||||
|
n = dt.today().weekday()
|
||||||
|
return n
|
||||||
|
|
||||||
|
def week_number_get(self):
|
||||||
|
now = datetime.now()
|
||||||
|
return int(now.strftime("%V"))
|
||||||
|
|
||||||
|
def week_number_verify(self, week_nr):
|
||||||
|
if week_nr > 0 or week_nr <= 53:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_weeknr_from_date(self, date):
|
||||||
|
return date.strftime("%V")
|
||||||
|
|
||||||
|
def year_verify(self, year):
|
||||||
|
if isinstance(year, str):
|
||||||
|
try:
|
||||||
|
year = int(year)
|
||||||
|
except Exception as ex:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if 2000 <= year <= 2030:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_day_number(self):
|
||||||
|
dt = datetime.now()
|
||||||
|
return dt.today().weekday()
|
||||||
|
|
||||||
|
def get_month_nr(self):
|
||||||
|
return datetime.now().strftime("%m")
|
||||||
|
|
||||||
|
def get_daynr_from_weekday(self, weekday):
|
||||||
|
for k, v in self.weekdays_en.items():
|
||||||
|
if v == weekday:
|
||||||
|
return k
|
||||||
|
|
||||||
|
def get_day_from_daynr(self, nr):
|
||||||
|
return self.weekdays_en[nr]
|
||||||
|
|
||||||
|
def get_month_from_weeknr(self, nr):
|
||||||
|
nr = float(nr) / float(4)
|
||||||
|
if nr.is_integer():
|
||||||
|
nr -= 1
|
||||||
|
else:
|
||||||
|
nr = math.floor(nr)
|
||||||
|
if nr < 0:
|
||||||
|
nr = 0
|
||||||
|
|
||||||
|
return self.months_en[nr]
|
||||||
|
|
||||||
|
def get_month_nr_from_month(self, month):
|
||||||
|
for k, v in self.months_en.items():
|
||||||
|
if v == month:
|
||||||
|
return k
|
||||||
|
|
||||||
|
def get_year(self):
|
||||||
|
return date.today().year
|
||||||
|
|
||||||
|
def get_month(self):
|
||||||
|
return date.today().month
|
||||||
|
|
||||||
|
def get_amount_of_days_from_month_nr(self, month_nr):
|
||||||
|
try:
|
||||||
|
max_days = calendar.monthrange(self.get_year(), int(month_nr))[1]
|
||||||
|
return max_days
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def from_till(self):
|
||||||
|
m = self.get_month()
|
||||||
|
d = self.get_amount_of_days_from_month_nr(m)
|
||||||
|
y = self.get_year()
|
||||||
|
|
||||||
|
if len(str(d)) == 1:
|
||||||
|
d = '0' + str(d)
|
||||||
|
else:
|
||||||
|
d = str(d)
|
||||||
|
|
||||||
|
if len(str(m)) == 1:
|
||||||
|
m = '0' + str(m)
|
||||||
|
else:
|
||||||
|
m = str(m)
|
||||||
|
|
||||||
|
f = '%s/01/%s' % (m, y)
|
||||||
|
t = '%s/%s/%s' % (m, d, y)
|
||||||
|
|
||||||
|
return {'date_from': f, 'date_till': t}
|
||||||
|
|
||||||
|
def ago_dt(self, datetime):
|
||||||
|
return self.ago(datetime)
|
||||||
|
|
||||||
|
def ago_str(self, date_str):
|
||||||
|
date = parser.parse(date_str)
|
||||||
|
return self.ago(date)
|
||||||
|
|
||||||
|
def ago(self, datetime=None, epoch=None):
|
||||||
|
import math
|
||||||
|
|
||||||
|
if epoch:
|
||||||
|
td = int(epoch)
|
||||||
|
else:
|
||||||
|
if datetime:
|
||||||
|
td = (self.now - datetime).total_seconds()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if td < 60:
|
||||||
|
if td == 1:
|
||||||
|
return '%s second ago'
|
||||||
|
else:
|
||||||
|
return 'Just now'
|
||||||
|
elif 60 <= td < 3600:
|
||||||
|
if 60 <= td < 120:
|
||||||
|
return '1 minute ago'
|
||||||
|
else:
|
||||||
|
return '%s minutes ago' % str(int(math.floor(td / 60)))
|
||||||
|
elif 3600 <= td < 86400:
|
||||||
|
if 3600 <= td < 7200:
|
||||||
|
return '1 hour ago'
|
||||||
|
else:
|
||||||
|
return '%s hours ago' % str(int(math.floor(td / 60 / 60)))
|
||||||
|
elif td >= 86400:
|
||||||
|
if td <= 86400 < 172800:
|
||||||
|
return '1 day ago'
|
||||||
|
else:
|
||||||
|
x = int(math.floor(td / 24 / 60 / 60))
|
||||||
|
if x == 1:
|
||||||
|
return '1 day ago'
|
||||||
|
return '%s days ago' % str(x)
|
47
funding/cache.py
Normal file
47
funding/cache.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import redis
|
||||||
|
from flask_session import RedisSessionInterface
|
||||||
|
|
||||||
|
import settings
|
||||||
|
from funding.bin.utils import json_encoder
|
||||||
|
|
||||||
|
|
||||||
|
def redis_args():
|
||||||
|
args = {
|
||||||
|
"host": settings.REDIS_HOST,
|
||||||
|
"port": settings.REDIS_PORT,
|
||||||
|
'socket_connect_timeout': 2,
|
||||||
|
'socket_timeout': 2,
|
||||||
|
'retry_on_timeout': True,
|
||||||
|
'decode_responses': True
|
||||||
|
}
|
||||||
|
if settings.REDIS_PASSWD:
|
||||||
|
args["password"] = settings.REDIS_PASSWD
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
class JsonRedisSerializer:
|
||||||
|
@staticmethod
|
||||||
|
def loads(val):
|
||||||
|
try:
|
||||||
|
return json.loads(val).get("wow", {})
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dumps(val):
|
||||||
|
try:
|
||||||
|
return json.dumps({"wow": val})
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class JsonRedis(RedisSessionInterface):
|
||||||
|
serializer = JsonRedisSerializer
|
||||||
|
|
||||||
|
def __init__(self, key_prefix, use_signer=False, decode_responses=True):
|
||||||
|
super(JsonRedis, self).__init__(
|
||||||
|
redis=redis.Redis(**redis_args()),
|
||||||
|
key_prefix=key_prefix,
|
||||||
|
use_signer=use_signer)
|
81
funding/factory.py
Normal file
81
funding/factory.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import settings
|
||||||
|
from flask import Flask
|
||||||
|
from flask_caching import Cache
|
||||||
|
from flask_session import Session
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
import redis
|
||||||
|
|
||||||
|
app = None
|
||||||
|
cache = None
|
||||||
|
db = None
|
||||||
|
bcrypt = None
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_cache(app: Flask):
|
||||||
|
global cache
|
||||||
|
|
||||||
|
cache_config = {
|
||||||
|
"CACHE_TYPE": "redis",
|
||||||
|
"CACHE_DEFAULT_TIMEOUT": 60,
|
||||||
|
"CACHE_KEY_PREFIX": "wow_cache_",
|
||||||
|
"CACHE_REDIS_PORT": settings.REDIS_PORT
|
||||||
|
}
|
||||||
|
|
||||||
|
if settings.REDIS_PASSWD:
|
||||||
|
cache_config["CACHE_REDIS_PASSWORD"] = settings.REDIS_PASSWD
|
||||||
|
|
||||||
|
app.config.from_mapping(cache_config)
|
||||||
|
cache = Cache(app)
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_session(app: Flask):
|
||||||
|
app.config['SESSION_TYPE'] = 'redis'
|
||||||
|
app.config['SESSION_COOKIE_NAME'] = 'bar'
|
||||||
|
app.config['SESSION_REDIS'] = redis.from_url(settings.REDIS_URI)
|
||||||
|
Session(app) # defaults to timedelta(days=31)
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_db(app: Flask):
|
||||||
|
global db
|
||||||
|
uri = 'postgresql+psycopg2://{user}:{pw}@{url}/{db}'.format(
|
||||||
|
user=settings.PSQL_USER,
|
||||||
|
pw=settings.PSQL_PASS,
|
||||||
|
url=settings.PSQL_HOST,
|
||||||
|
db=settings.PSQL_DB)
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = uri
|
||||||
|
db = SQLAlchemy(app)
|
||||||
|
import funding.orm
|
||||||
|
db.create_all()
|
||||||
|
|
||||||
|
|
||||||
|
def create_app():
|
||||||
|
global app
|
||||||
|
global db
|
||||||
|
global cache
|
||||||
|
global bcrypt
|
||||||
|
|
||||||
|
app = Flask(import_name=__name__,
|
||||||
|
static_folder='static',
|
||||||
|
template_folder='templates')
|
||||||
|
app.config.from_object(settings)
|
||||||
|
app.config['PERMANENT_SESSION_LIFETIME'] = 2678400
|
||||||
|
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
|
||||||
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 30
|
||||||
|
app.secret_key = settings.SECRET
|
||||||
|
|
||||||
|
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
|
||||||
|
|
||||||
|
_setup_cache(app)
|
||||||
|
_setup_session(app)
|
||||||
|
_setup_db(app)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# import routes
|
||||||
|
from funding import routes
|
||||||
|
from funding.bin import utils_request
|
||||||
|
|
||||||
|
app.app_context().push()
|
||||||
|
return app
|
114
funding/orm.py
Normal file
114
funding/orm.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import string
|
||||||
|
import random
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from sqlalchemy.orm import relationship, backref
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.orm import scoped_session, sessionmaker, relationship
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
|
from sqlalchemy.types import Float
|
||||||
|
from sqlalchemy_json import MutableJson
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
|
||||||
|
import settings
|
||||||
|
from funding.factory import db, cache
|
||||||
|
|
||||||
|
base = declarative_base(name="Model")
|
||||||
|
|
||||||
|
|
||||||
|
def val_address(address):
|
||||||
|
if len(address) != 52 or address[0] != 'e' or address[1] != 's':
|
||||||
|
raise Exception("invalid epic address")
|
||||||
|
|
||||||
|
|
||||||
|
class Address(db.Model):
|
||||||
|
__tablename__ = "addresses"
|
||||||
|
id = db.Column('user_id', db.Integer, primary_key=True)
|
||||||
|
address = db.Column(db.String(52), unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_address(cls, address):
|
||||||
|
from funding.factory import db
|
||||||
|
q = cls.query
|
||||||
|
q = q.filter(Address.address == address)
|
||||||
|
result = q.first()
|
||||||
|
if not result:
|
||||||
|
return
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Address(address='%s')>" % (
|
||||||
|
self.address)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add(cls, address):
|
||||||
|
from funding.factory import db
|
||||||
|
|
||||||
|
try:
|
||||||
|
previous = cls.query.filter(Address.address == address).first()
|
||||||
|
if previous is not None:
|
||||||
|
print("was inputted before")
|
||||||
|
return
|
||||||
|
# validate incoming username/email
|
||||||
|
val_address(address)
|
||||||
|
new_address = Address(address=address)
|
||||||
|
db.session.add(new_address)
|
||||||
|
db.session.commit()
|
||||||
|
db.session.flush()
|
||||||
|
return new_address
|
||||||
|
except Exception as ex:
|
||||||
|
db.session.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
class Slate(db.Model):
|
||||||
|
__tablename__ = "slates"
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
slate = db.Column(db.String())
|
||||||
|
# TODO: clear slatse that have been in the database past a certain time
|
||||||
|
posted_time = db.Column(db.DateTime)
|
||||||
|
receivingAddress = db.Column(db.String(52), db.ForeignKey('addresses.address'), nullable=False)
|
||||||
|
|
||||||
|
def __init__(self, slate, receivingAddress):
|
||||||
|
from funding.factory import bcrypt
|
||||||
|
self.slate = slate
|
||||||
|
self.receivingAddress = receivingAddress
|
||||||
|
self.posted_time = datetime.utcnow()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Slate(slate='%s', receivingAddress='%s', posted_time='%s)>" % (
|
||||||
|
self.slate, self.receivingAddress, self.posted_time)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_slates(cls, address):
|
||||||
|
q = cls.query
|
||||||
|
q = q.filter(Slate.receivingAddress == address)
|
||||||
|
result = q.all()
|
||||||
|
print(f'{result}')
|
||||||
|
list_slates = []
|
||||||
|
for slate_db in result:
|
||||||
|
list_slates.append(slate_db.slate)
|
||||||
|
return list_slates
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add(cls, slate, receivingAddress):
|
||||||
|
from funding.factory import db
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
previous = cls.query.filter(Slate.slate == slate).first()
|
||||||
|
if previous is not None:
|
||||||
|
print("was inputted before")
|
||||||
|
return
|
||||||
|
# put in new one
|
||||||
|
new_slate = Slate(slate=slate, receivingAddress=receivingAddress)
|
||||||
|
db.session.add(new_slate)
|
||||||
|
db.session.commit()
|
||||||
|
db.session.flush()
|
||||||
|
return new_slate
|
||||||
|
except Exception as ex:
|
||||||
|
db.session.rollback()
|
||||||
|
raise
|
64
funding/routes.py
Normal file
64
funding/routes.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import uuid
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from flask import request, redirect, render_template, url_for, flash, make_response, send_from_directory, jsonify
|
||||||
|
from flask_yoloapi import endpoint, parameter
|
||||||
|
import json
|
||||||
|
|
||||||
|
import settings
|
||||||
|
from funding.factory import app, db, cache
|
||||||
|
from funding.orm import Address, Slate
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return redirect(url_for('about'))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/about')
|
||||||
|
def about():
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/postSlate', methods=['POST'])
|
||||||
|
@endpoint.api(
|
||||||
|
parameter('receivingAddress', type=str, required=True),
|
||||||
|
parameter('slate', type=str, required=True),
|
||||||
|
)
|
||||||
|
def postSlate(receivingAddress, slate):
|
||||||
|
try:
|
||||||
|
if receivingAddress is None or slate is None:
|
||||||
|
return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")}))
|
||||||
|
|
||||||
|
try:
|
||||||
|
Address.add(address=receivingAddress)
|
||||||
|
except Exception as ex:
|
||||||
|
print(f'{ex}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
Slate.add(slate=slate, receivingAddress=receivingAddress)
|
||||||
|
except Exception as ex:
|
||||||
|
print(f'{ex}')
|
||||||
|
|
||||||
|
return make_response(jsonify({'status': 'success'}))
|
||||||
|
except Exception as ex:
|
||||||
|
print(f'{ex}')
|
||||||
|
return make_response(jsonify({'status': 'failure', 'error': str(ex)}))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/getSlates', methods=['POST'])
|
||||||
|
@endpoint.api(
|
||||||
|
parameter('receivingAddress', type=str, required=True),
|
||||||
|
)
|
||||||
|
def getSlates(receivingAddress):
|
||||||
|
try:
|
||||||
|
if receivingAddress is None:
|
||||||
|
return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")}))
|
||||||
|
|
||||||
|
slates = Slate.find_slates(address=receivingAddress)
|
||||||
|
return make_response(jsonify({'status': 'success', 'slates': slates}))
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
print(f'{ex}')
|
||||||
|
return make_response(jsonify({'status': 'failure', 'error': str(ex)}))
|
17
requirements.txt
Normal file
17
requirements.txt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
sqlalchemy==1.3.4
|
||||||
|
flask
|
||||||
|
flask-yoloapi==0.1.5
|
||||||
|
flask_session
|
||||||
|
flask-login
|
||||||
|
flask-bcrypt
|
||||||
|
redis
|
||||||
|
gunicorn
|
||||||
|
psycopg2
|
||||||
|
markdown2
|
||||||
|
requests
|
||||||
|
pyqrcode
|
||||||
|
pypng
|
||||||
|
pillow-simd
|
||||||
|
Flask-Caching
|
||||||
|
flask-sqlalchemy
|
||||||
|
sqlalchemy_json
|
8
run_dev.py
Normal file
8
run_dev.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from funding.factory import create_app
|
||||||
|
import settings
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = create_app()
|
||||||
|
app.run(host=settings.BIND_HOST, port=settings.BIND_PORT,
|
||||||
|
debug=settings.DEBUG, use_reloader=False)
|
36
settings.py_example
Normal file
36
settings.py_example
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
import collections
|
||||||
|
import os
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
SECRET = ''
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
COINCODE = ''
|
||||||
|
PSQL_HOST = "127.0.0.1:5432"
|
||||||
|
PSQL_DB = ''
|
||||||
|
PSQL_USER = 'postgres'
|
||||||
|
PSQL_PASS = ''
|
||||||
|
|
||||||
|
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI', 'postgresql://{user}:{pw}@localhost/{db}').format(user=PSQL_USER, pw=PSQL_PASS, db=PSQL_DB)
|
||||||
|
|
||||||
|
SESSION_COOKIE_NAME = os.environ.get('{coincode}_SESSION_COOKIE_NAME', '{coincode}_id').format(coincode=COINCODE.upper())
|
||||||
|
SESSION_PREFIX = os.environ.get('{coincode}_SESSION_PREFIX', 'session:').format(coincode=COINCODE.upper())
|
||||||
|
|
||||||
|
REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
|
||||||
|
REDIS_PORT = int(os.environ.get('REDIS_PORT', 6379))
|
||||||
|
REDIS_PASSWD = os.environ.get('REDIS_PASSWD', None)
|
||||||
|
REDIS_URI = "redis://"
|
||||||
|
if REDIS_PASSWD:
|
||||||
|
REDIS_URI += f":{REDIS_PASSWD}"
|
||||||
|
REDIS_URI += f"@{REDIS_HOST}:{REDIS_PORT}"
|
||||||
|
|
||||||
|
BIND_HOST = os.environ.get("BIND_HOST", "0.0.0.0")
|
||||||
|
if not BIND_HOST:
|
||||||
|
raise Exception("BIND_HOST missing")
|
||||||
|
BIND_PORT = os.environ.get("BIND_PORT", 5004)
|
||||||
|
if not BIND_PORT:
|
||||||
|
raise Exception("BIND_PORT missing")
|
||||||
|
|
||||||
|
HOSTNAME = os.environ.get("{coincode}_HOSTNAME", socket.gethostname()).format(coincode=COINCODE.upper())
|
Loading…
Reference in New Issue
Block a user