folder rename; future commits make sense after this

This commit is contained in:
CamTheGeek 2018-09-05 12:30:18 -04:00
parent 09d0f09d8e
commit f473a4234e
71 changed files with 0 additions and 0 deletions

0
funding/bin/__init__.py Normal file
View file

210
funding/bin/anti_xss.py Normal file
View file

@ -0,0 +1,210 @@
# -*- coding: utf-8 -*-
"""
Python 富文本XSS过滤类
@package XssHtml
@version 0.1
@link http://phith0n.github.io/python-xss-filter
@since 20150407
@copyright (c) Phithon All Rights Reserved
Based on native Python module HTMLParser purifier of HTML, To Clear all javascript in html
You can use it in all python web framework
Written by Phithon <root@leavesongs.com> in 2015 and placed in the public domain.
phithon <root@leavesongs.com> 编写于20150407
From: XDSEC <www.xdsec.org> & 离别歌 <www.leavesongs.com>
GitHub Pages: https://github.com/phith0n/python-xss-filter
Usage:
parser = XssHtml()
parser.feed('<html code>')
parser.close()
html = parser.getHtml()
print html
Requirements
Python 2.6+ or 3.2+
Cannot defense xss in browser which is belowed IE7
浏览器版本IE7+ 或其他浏览器无法防御IE6及以下版本浏览器中的XSS
"""
import re
try:
from html.parser import HTMLParser
except:
from HTMLParser import HTMLParser
class XssHtml(HTMLParser):
allow_tags = ['a', 'img', 'br', 'strong', 'b', 'code', 'pre',
'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4',
'h5', 'h6', 'blockquote', 'ul', 'ol', 'tr', 'th', 'td',
'hr', 'li', 'u', 'embed', 's', 'table', 'thead', 'tbody',
'caption', 'small', 'q', 'sup', 'sub']
common_attrs = ["style", "class", "name"]
nonend_tags = ["img", "hr", "br", "embed"]
tags_own_attrs = {
"img": ["src", "width", "height", "alt", "align"],
"a": ["href", "target", "rel", "title"],
"embed": ["src", "width", "height", "type", "allowfullscreen", "loop", "play", "wmode", "menu"],
"table": ["border", "cellpadding", "cellspacing"],
}
_regex_url = re.compile(r'^(http|https|ftp)://.*', re.I | re.S)
_regex_style_1 = re.compile(r'(\\|&#|/\*|\*/)', re.I)
_regex_style_2 = re.compile(r'e.*x.*p.*r.*e.*s.*s.*i.*o.*n', re.I | re.S)
def __init__(self, allows=[]):
HTMLParser.__init__(self)
self.allow_tags = allows if allows else self.allow_tags
self.result = []
self.start = []
self.data = []
def getHtml(self):
"""
Get the safe html code
"""
for i in range(0, len(self.result)):
self.data.append(self.result[i])
return ''.join(self.data)
def handle_startendtag(self, tag, attrs):
self.handle_starttag(tag, attrs)
def handle_starttag(self, tag, attrs):
if tag not in self.allow_tags:
return
end_diagonal = ' /' if tag in self.nonend_tags else ''
if not end_diagonal:
self.start.append(tag)
attdict = {}
for attr in attrs:
attdict[attr[0]] = attr[1]
attdict = self._wash_attr(attdict, tag)
if hasattr(self, "node_%s" % tag):
attdict = getattr(self, "node_%s" % tag)(attdict)
else:
attdict = self.node_default(attdict)
attrs = []
for (key, value) in attdict.items():
attrs.append('%s="%s"' % (key, self._htmlspecialchars(value)))
attrs = (' ' + ' '.join(attrs)) if attrs else ''
self.result.append('<' + tag + attrs + end_diagonal + '>')
def handle_endtag(self, tag):
if self.start and tag == self.start[len(self.start) - 1]:
self.result.append('</' + tag + '>')
self.start.pop()
def handle_data(self, data):
self.result.append(self._htmlspecialchars(data))
def handle_entityref(self, name):
if name.isalpha():
self.result.append("&%s;" % name)
def handle_charref(self, name):
if name.isdigit():
self.result.append("&#%s;" % name)
def node_default(self, attrs):
attrs = self._common_attr(attrs)
return attrs
def node_a(self, attrs):
attrs = self._common_attr(attrs)
attrs = self._get_link(attrs, "href")
attrs = self._set_attr_default(attrs, "target", "_blank")
attrs = self._limit_attr(attrs, {
"target": ["_blank", "_self"]
})
return attrs
def node_embed(self, attrs):
attrs = self._common_attr(attrs)
attrs = self._get_link(attrs, "src")
attrs = self._limit_attr(attrs, {
"type": ["application/x-shockwave-flash"],
"wmode": ["transparent", "window", "opaque"],
"play": ["true", "false"],
"loop": ["true", "false"],
"menu": ["true", "false"],
"allowfullscreen": ["true", "false"]
})
attrs["allowscriptaccess"] = "never"
attrs["allownetworking"] = "none"
return attrs
def _true_url(self, url):
if self._regex_url.match(url):
return url
else:
return "http://%s" % url
def _true_style(self, style):
if style:
style = self._regex_style_1.sub('_', style)
style = self._regex_style_2.sub('_', style)
return style
def _get_style(self, attrs):
if "style" in attrs:
attrs["style"] = self._true_style(attrs.get("style"))
return attrs
def _get_link(self, attrs, name):
if name in attrs:
attrs[name] = self._true_url(attrs[name])
return attrs
def _wash_attr(self, attrs, tag):
if tag in self.tags_own_attrs:
other = self.tags_own_attrs.get(tag)
else:
other = []
_attrs = {}
if attrs:
for (key, value) in attrs.items():
if key in self.common_attrs + other:
_attrs[key] = value
return _attrs
def _common_attr(self, attrs):
attrs = self._get_style(attrs)
return attrs
def _set_attr_default(self, attrs, name, default=''):
if name not in attrs:
attrs[name] = default
return attrs
def _limit_attr(self, attrs, limit={}):
for (key, value) in limit.items():
if key in attrs and attrs[key] not in value:
del attrs[key]
return attrs
def _htmlspecialchars(self, html):
return html.replace("<", "&lt;")\
.replace(">", "&gt;")\
.replace('"', "&quot;")\
.replace("'", "&#039;")
def such_xss(inp):
"""Very ghetto anti-xss countermeasures. Possibly unsafe! :D
Needs testing, or a proper solution. wow."""
parser = XssHtml()
parser.feed(inp)
parser.close()
result = parser.getHtml()
# oh noes teh markdown blockquotes
lines = result.split('\n')
_lines = []
for line in lines:
if line.startswith('&gt;'):
line = line[4:]
line = '>%s' % line
_lines.append(line)
return "\n".join(_lines)

52
funding/bin/daemon.py Normal file
View file

@ -0,0 +1,52 @@
import settings
import requests
class WowneroDaemon:
def __init__(self):
self.url = settings.RPC_LOCATION
self.headers = {"User-Agent": "Mozilla"}
def create_address(self, label_name):
data = {
'method': 'create_address',
'params': {'account_index': 0, 'label': label_name},
'jsonrpc': '2.0',
'id': '0'
}
return self._make_request(data)
def get_address(self, index):
data = {
'method': 'get_address',
'params': {'address_index': [index], 'account_index': 0},
'jsonrpc': '2.0',
'id': '0'
}
try:
result = self._make_request(data)
return next(z for z in result['result']['addresses'] if z['address_index'] == index)
except:
return
def get_transfers_in(self, index):
data = {
"method":"get_transfers",
"params": {"pool": True, "in": True, "account_index": 0, "subaddr_indices": [index]},
"jsonrpc": "2.0",
"id": "0",
}
data = self._make_request(data)
data = data['result'].get('in', [])
for d in data:
d['amount_human'] = float(d['amount'])/1e11
return {
'sum': sum([float(z['amount'])/1e11 for z in data]),
'txs': data
}
def _make_request(self, data):
r = requests.post(self.url, json=data, headers=self.headers)
r.raise_for_status()
return r.json()

93
funding/bin/utils.py Normal file
View file

@ -0,0 +1,93 @@
from datetime import datetime, date
import requests
from flask import g
from flask.json import JSONEncoder
import settings
def json_encoder(obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
raise TypeError ("Type %s not serializable" % type(obj))
class Summary:
@staticmethod
def fetch_prices():
if hasattr(g, 'wowfunding_prices') and g.wow_prices:
return g.wow_prices
from wowfunding.factory import cache
cache_key = 'wowfunding_prices'
data = cache.get(cache_key)
if data:
return data
data = {
'wow-btc': price_tradeogre_wow_btc(),
'btc-usd': price_cmc_btc_usd()
}
cache.set(cache_key, data=data, expiry=7200)
g.wow_prices = data
return data
@staticmethod
def fetch_stats(purge=False):
from wowfunding.factory import db_session
from wowfunding.orm.orm import Proposal, User, Comment
from wowfunding.factory import cache
cache_key = 'wowfunding_stats'
data = cache.get(cache_key)
if data and not purge:
return data
categories = settings.FUNDING_CATEGORIES
statuses = settings.FUNDING_STATUSES.keys()
for cat in categories:
q = db_session.query(Proposal)
q = q.filter(Proposal.category == cat)
res = q.count()
data.setdefault('cats', {})
data['cats'][cat] = res
for status in statuses:
q = db_session.query(Proposal)
q = q.filter(Proposal.status == status)
res = q.count()
data.setdefault('statuses', {})
data['statuses'][status] = res
data.setdefault('users', {})
data['users']['count'] = db_session.query(User.id).count()
cache.set(cache_key, data=data, expiry=300)
return data
def price_cmc_btc_usd():
headers = {'User-Agent': 'Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0'}
try:
r = requests.get('https://api.coinmarketcap.com/v2/ticker/1/?convert=USD', headers=headers)
r.raise_for_status()
return r.json().get('data', {}).get('quotes', {}).get('USD', {}).get('price')
except:
return
def price_tradeogre_wow_btc():
headers = {'User-Agent': 'Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0'}
try:
r = requests.get('https://tradeogre.com/api/v1/ticker/BTC-WOW', headers=headers)
r.raise_for_status()
return float(r.json().get('high'))
except:
return
def wow_to_usd(wows: float, usd_per_btc: float, btc_per_wow: float):
try:
return round(usd_per_btc / (1.0 / (wows * btc_per_wow)), 2)
except:
pass

View file

@ -0,0 +1,48 @@
from datetime import datetime
from flask import session, g
import settings
from wowfunding.bin.utils import Summary
from wowfunding.factory import app, db_session
from wowfunding.orm.orm import Proposal, User, Comment
@app.context_processor
def templating():
from flask.ext.login import current_user
recent_comments = db_session.query(Comment).filter(Comment.automated == False).order_by(Comment.date_added.desc()).limit(10).all()
summary_data = Summary.fetch_stats()
return dict(logged_in=current_user.is_authenticated,
current_user=current_user,
funding_categories=settings.FUNDING_CATEGORIES,
funding_statuses=settings.FUNDING_STATUSES,
summary_data=summary_data,
recent_comments=recent_comments)
@app.before_request
def before_request():
pass
@app.after_request
def after_request(res):
if hasattr(g, 'wowfunding_prices'):
delattr(g, 'wowfunding_prices')
res.headers.add('Accept-Ranges', 'bytes')
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.teardown_appcontext
def shutdown_session(**kwargs):
db_session.remove()
@app.errorhandler(404)
def error(err):
return 'Error', 404

163
funding/bin/utils_time.py Normal file
View 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)