Skip to content

Commit c1c30b0

Browse files
committed
big refactoring of server, api versioning
1 parent fbccd81 commit c1c30b0

File tree

10 files changed

+265
-158
lines changed

10 files changed

+265
-158
lines changed

main.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ async def proxy_counter():
4343

4444

4545
if __name__ == "__main__":
46+
loop = asyncio.get_event_loop()
47+
4648
proxy_processor = Processor()
4749

48-
proxy_provider_server = ProxyProviderServer.get_proxy_provider_server(
50+
proxy_provider_server = ProxyProviderServer(
4951
settings.PROXY_PROVIDER_SERVER_ADDRESS['HOST'],
5052
settings.PROXY_PROVIDER_SERVER_ADDRESS['PORT'],
51-
None, # proxy_processor,
53+
proxy_processor,
5254
)
5355

54-
loop = asyncio.get_event_loop()
5556
loop.run_until_complete(proxy_provider_server.start(loop))
57+
5658
loop.run_until_complete(asyncio.wait([
5759
proxy_processor.exec(),
5860
proxy_counter(),

proxy_py/_settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,5 @@
7070
IPInfoIOChecker(PROXY_CHECKING_TIMEOUT),
7171
D3DInfoChecker(PROXY_CHECKING_TIMEOUT),
7272
]
73+
74+
TEMPLATES_PATH = "server/templates"

server/api_request_handler.py renamed to server/api_v1/api_request_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from server.requests_to_models.request_parser import RequestParser, ParseError
2-
from server.requests_to_models.request_executor import RequestExecutor, ExecutionError
1+
from .requests_to_models.request_parser import RequestParser, ParseError
2+
from .requests_to_models.request_executor import RequestExecutor, ExecutionError
33
from proxy_py import settings
44

55

server/api_v1/app.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from server.base_app import BaseApp
2+
from .api_request_handler import ApiRequestHandler
3+
from aiohttp import web
4+
5+
import json
6+
import aiohttp
7+
8+
9+
class App(BaseApp):
10+
def __init__(self, *args, **kwargs):
11+
super(App, self).__init__(*args, **kwargs)
12+
13+
self.request_handler = ApiRequestHandler(self.logger)
14+
15+
async def setup_router(self):
16+
self.app.router.add_post('/', self.post)
17+
18+
async def post(self, request):
19+
client_address = request.transport.get_extra_info('peername')
20+
host, port = (None, None)
21+
22+
if client_address is not None:
23+
host, port = client_address
24+
else:
25+
client_address = (host, port)
26+
27+
data = await request.read()
28+
29+
with open("logs/apiv1_server_connections", 'a') as f:
30+
f.write("client - {}:{}, data - {}\n".format(host, port, data))
31+
32+
try:
33+
data = json.loads(data.decode())
34+
35+
response = await self.request_handler.handle(client_address, data)
36+
except ValueError:
37+
response = {
38+
'status': 'error',
39+
'status_code': 400,
40+
'error_message': "Your request doesn't look like request",
41+
}
42+
43+
if 'status_code' in response:
44+
status_code = response['status_code']
45+
else:
46+
if response['status'] != 'ok':
47+
status_code = 500
48+
else:
49+
status_code = 200
50+
51+
response['status_code'] = status_code
52+
53+
return aiohttp.web.json_response(response, status=status_code)

server/requests_to_models/request_executor.py renamed to server/api_v1/requests_to_models/request_executor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from proxy_py import settings
22
from models import db
3-
from server.requests_to_models.request import Request, GetRequest, CountRequest, FetchRequest
3+
from ..requests_to_models.request import Request, GetRequest, CountRequest, FetchRequest
44
import importlib
55

66

server/requests_to_models/request_parser.py renamed to server/api_v1/requests_to_models/request_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from server.requests_to_models.request import Request, GetRequest, CountRequest
1+
from ..requests_to_models.request import Request, GetRequest, CountRequest
22

33
import string
44
import copy

server/base_app.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import asyncio
2+
3+
from proxy_py import settings
4+
from aiohttp import web
5+
6+
import abc
7+
import json
8+
import aiohttp
9+
import aiohttp_jinja2
10+
import jinja2
11+
12+
13+
class BaseApp:
14+
def __init__(self, logger=None):
15+
self.logger = logger
16+
self._app = web.Application()
17+
18+
aiohttp_jinja2.setup(self.app, loader=jinja2.FileSystemLoader(
19+
settings.TEMPLATES_PATH
20+
))
21+
22+
async def init(self):
23+
"""Call it before anything else"""
24+
await self.setup_router()
25+
await self.setup_middlewares()
26+
27+
@abc.abstractmethod
28+
async def setup_router(self):
29+
pass
30+
31+
async def setup_middlewares(self):
32+
pass
33+
34+
@property
35+
def app(self):
36+
return self._app

server/frontend/app.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from proxy_py import settings
2+
from models import db, Proxy, ProxyCountItem, CollectorState
3+
from server.base_app import BaseApp
4+
from aiohttp import web
5+
6+
import time
7+
import datetime
8+
import functools
9+
import aiohttp_jinja2
10+
11+
12+
def get_response_wrapper(template_name):
13+
def decorator_wrapper(func):
14+
@functools.wraps(func)
15+
@aiohttp_jinja2.template(template_name)
16+
async def wrap(self, *args, **kwargs):
17+
good_proxies_count = await db.count(
18+
Proxy.select().where(Proxy.number_of_bad_checks == 0)
19+
)
20+
21+
bad_proxies_count = await db.count(
22+
Proxy.select().where(
23+
Proxy.number_of_bad_checks > 0,
24+
Proxy.number_of_bad_checks < settings.DEAD_PROXY_THRESHOLD,
25+
)
26+
)
27+
28+
dead_proxies_count = await db.count(
29+
Proxy.select().where(
30+
Proxy.number_of_bad_checks >= settings.DEAD_PROXY_THRESHOLD,
31+
)
32+
)
33+
34+
response = {
35+
"bad_proxies_count": bad_proxies_count,
36+
"good_proxies_count": good_proxies_count,
37+
"dead_proxies_count": dead_proxies_count,
38+
}
39+
40+
response.update(await func(self, *args, **kwargs))
41+
42+
return response
43+
return wrap
44+
45+
return decorator_wrapper
46+
47+
48+
class App(BaseApp):
49+
async def setup_router(self):
50+
self.app.router.add_get('/get/proxy/', self.get_proxies_html)
51+
self.app.router.add_get('/get/proxy_count_item/', self.get_proxy_count_items_html)
52+
self.app.router.add_get('/get/collector_state/', self.get_collector_state_html)
53+
self.app.router.add_get('/get/best/http/proxy/', self.get_best_http_proxy)
54+
55+
@get_response_wrapper("collector_state.html")
56+
async def get_collector_state_html(self, request):
57+
return {
58+
"collector_states": list(await db.execute(CollectorState.select())),
59+
}
60+
61+
@get_response_wrapper("proxies.html")
62+
async def get_proxies_html(self, request):
63+
proxies = await db.execute(
64+
Proxy.select().where(Proxy.number_of_bad_checks == 0).order_by(Proxy.response_time)
65+
)
66+
proxies = list(proxies)
67+
current_timestamp = time.time()
68+
69+
return {
70+
"proxies": [{
71+
"address": proxy.address,
72+
"response_time": proxy.response_time / 1000 if proxy.response_time is not None else None,
73+
"uptime": datetime.timedelta(
74+
seconds=int(current_timestamp - proxy.uptime)) if proxy.uptime is not None else None,
75+
"bad_uptime": datetime.timedelta(
76+
seconds=int(current_timestamp - proxy.bad_uptime)) if proxy.bad_uptime is not None else None,
77+
"last_check_time": proxy.last_check_time,
78+
"checking_period": proxy.checking_period,
79+
"number_of_bad_checks": proxy.number_of_bad_checks,
80+
"bad_proxy": proxy.bad_proxy,
81+
"white_ipv4": proxy.white_ipv4,
82+
"city": proxy.city,
83+
"region": proxy.region,
84+
"country_code": proxy.country_code,
85+
} for proxy in proxies]
86+
}
87+
88+
@get_response_wrapper("proxy_count_items.html")
89+
async def get_proxy_count_items_html(self, request):
90+
return {
91+
"proxy_count_items": list(await db.execute(ProxyCountItem.select().order_by(ProxyCountItem.timestamp)))
92+
}
93+
94+
async def get_best_http_proxy(self, request):
95+
proxy_address = (await db.get(
96+
Proxy.select().where(
97+
Proxy.number_of_bad_checks == 0,
98+
Proxy.raw_protocol == Proxy.PROTOCOLS.index("http"),
99+
).order_by(Proxy.response_time)
100+
)).address
101+
102+
return web.Response(text=proxy_address)

0 commit comments

Comments
 (0)