Source code for scylla.web.server
import math
import os
from playhouse.shortcuts import model_to_dict
from sanic import Sanic
from sanic.request import Request
from sanic.response import json
from sanic_cors import CORS
from scylla.database import ProxyIP
from scylla.loggings import logger
app = Sanic()
CORS(app)
base_path = os.path.abspath(os.path.join(__file__, os.pardir, os.pardir))
app.static('/assets/*', base_path + '/assets')
app.static('/', base_path + '/assets/index.html')
app.static('/*', base_path + '/assets/index.html')
def _parse_str_to_int(s: str) -> int:
try:
return int(s)
except ValueError:
return 0
def _get_valid_proxies_query():
return ProxyIP.select().where(ProxyIP.latency > 0).where(ProxyIP.latency < 9999) \
.where(ProxyIP.is_valid == True)
[docs]@app.route('/api/v1/proxies')
async def api_v1_proxies(request: Request):
args = request.raw_args
limit = 20
page = 1
is_anonymous = 2 # 0: no, 1: yes, 2: any
if 'limit' in args:
int_limit = _parse_str_to_int(args['limit'])
limit = int_limit if int_limit else 20
if 'page' in args:
int_page = _parse_str_to_int(args['page'])
page = int_page if int_page > 0 else 1
if 'anonymous' in args:
str_anonymous = args['anonymous']
if str_anonymous == 'true':
is_anonymous = 1
elif str_anonymous == 'false':
is_anonymous = 0
else:
is_anonymous = 2
str_https = None
if 'https' in args:
str_https = args['https']
country_list = []
if 'countries' in args:
countries = args['countries']
country_list = countries.split(',')
proxy_initial_query = _get_valid_proxies_query()
proxy_query = proxy_initial_query
if is_anonymous != 2:
if is_anonymous == 1:
proxy_query = proxy_initial_query.where(ProxyIP.is_anonymous == True)
elif is_anonymous == 0:
proxy_query = proxy_initial_query.where(ProxyIP.is_anonymous == False)
if str_https:
if str_https == 'true':
proxy_query = proxy_initial_query.where(ProxyIP.is_https == True)
elif str_https == 'false':
proxy_query = proxy_initial_query.where(ProxyIP.is_https == False)
if country_list and len(country_list) > 0:
proxy_query = proxy_query.where(ProxyIP.country << country_list)
count = proxy_query.count() # count before sorting
proxies = proxy_query.order_by(ProxyIP.updated_at.desc(), ProxyIP.latency).offset((page - 1) * limit).limit(limit)
logger.debug('Perform SQL query: {}'.format(proxy_query.sql()))
proxy_list = []
for p in proxies:
proxy_list.append(model_to_dict(p))
return json({
'proxies': proxy_list,
'count': count,
'per_page': limit,
'page': page,
'total_page': math.ceil(count / limit),
})
[docs]@app.route('/api/v1/stats')
async def api_v1_stats(request: Request):
median_query: ProxyIP = ProxyIP.raw("""SELECT latency
FROM proxy_ips
WHERE is_valid = 1
ORDER BY latency
LIMIT 1
OFFSET (
SELECT COUNT(*) FROM proxy_ips WHERE is_valid = 1
) / 2""").get()
median = median_query.latency
mean_query: ProxyIP = ProxyIP.raw("""SELECT AVG(latency) as latency
FROM proxy_ips
WHERE is_valid = 1 AND latency < 9999""").get()
mean = mean_query.latency
valid_count = _get_valid_proxies_query().count()
total_count = ProxyIP.select().count()
return json({
'median': median,
'valid_count': valid_count,
'total_count': total_count,
'mean': mean,
})
[docs]def start_web_server(host='0.0.0.0', port=8899):
app.run(host=host, port=port)