This commit is contained in:
Izalia Mae 2022-02-22 19:30:46 -05:00
parent 185d204bdc
commit c44fa09b7d
21 changed files with 181 additions and 149 deletions

View file

@ -1,7 +1,30 @@
__software__ = 'Barkshark Async HTTP'
__version__ = '0.0.1'
from . import client
from .client import (
Client,
ClientRequest,
ClientResponse
)
try: from . import server
except ImportError: pass
try:
from .server import (
Application,
Blueprint,
MediaCacheControl,
ServerRequest,
ServerResponse,
Static,
View
)
except:
pass
try:
from .color import Color
from .template import Template
except: pass
try: from jinja2.exceptions import TemplateNotFound
except: pass

View file

@ -2,12 +2,10 @@ import json, mimetypes, traceback
from datetime import datetime, timezone
from functools import partial
from izzylib import DateString, DotDict, Url, boolean
from typing import Union
from xml.etree.ElementTree import fromstring
from .dotdict import DotDict
from .misc import DateString, Url, boolean
pubstr = 'https://www.w3.org/ns/activitystreams#Public'
actor_types = ['Application', 'Group', 'Organization', 'Person', 'Service']

View file

@ -1,5 +1,5 @@
__version__ = '0.1.0'
from .client import Client
from .request import Request
from .response import Response
from .request import ClientRequest
from .response import ClientResponse

View file

@ -5,7 +5,7 @@ from functools import partial
from .config import Config
from .. import __version__
from ..http_utils import methods
from ..utils import methods
class Client:

View file

@ -1,21 +1,21 @@
from izzylib import (
BaseConfig,
LowerdotDict
LowerDotDict
)
from .request import Request
from .response import Response
from .request import ClientRequest
from .response import ClientResponse
from .. import __version__
from ..http_utils import AsyncTransport
from ..utils import AsyncTransport
class Config(BaseConfig):
def __init__(self, **kwargs):
super().__init__(
headers = LowerDotDict({'User-Agent': f'IzzyLib/{__version__}'}),
request_class = Request,
response_class = Response,
request_class = ClientRequest,
response_class = ClientResponse,
transport_class = AsyncTransport,
timeout = 60
)

View file

@ -1,9 +1,9 @@
import json
from datetime import datetime
from izzylib import url
from izzylib import Url
from ..http_utils import (
from ..utils import (
Headers,
Cookies,
convert_to_bytes,
@ -17,7 +17,7 @@ try: from ..http_signatures import sign_request
except ImportError: sign_request = None
class Request:
class ClientRequest:
def __init__(self, url, body=None, headers={}, cookies={}, method='GET'):
method = method.upper()

View file

@ -2,12 +2,12 @@ from asyncio.exceptions import TimeoutError
from io import BytesIO
from izzylib import DotDict
from ..http_utils import (
from ..utils import (
Cookies,
Headers
)
class Response:
class ClientResponse:
def __init__(self, transport, status, message, version, headers, cookies):
self._body = BytesIO()

View file

@ -0,0 +1,80 @@
from colour import Color as Colour
class Color(Colour):
def __init__(self, color):
if isinstance(color, str):
super().__init__(f'#{str(color)}' if not color.startswith('#') else color)
elif isinstance(color, Colour):
super().__init__(str(color))
else:
raise TypeError(f'Color has to be a string or Color class, not {type(color)}')
def __repr__(self):
return self.__str__()
def __str__(self):
return self.hex_l
def lighten(self, multiplier):
return self.alter('lighten', multiplier)
def darken(self, multiplier):
return self.alter('darken', multiplier)
def saturate(self, multiplier):
return self.alter('saturate', multiplier)
def desaturate(self, multiplier):
return self.alter('desaturate', multiplier)
def rgba(self, multiplier):
return self.alter('rgba', multiplier)
def multi(self, multiplier):
if multiplier >= 100:
return 100
elif multiplier <= 0:
return 0
return multiplier / 100
def alter(self, action, multiplier):
new_color = Color(self)
if action == 'lighten':
new_color.luminance += ((1 - self.luminance) * self.multi(multiplier))
elif action == 'darken':
new_color.luminance -= (self.luminance * self.multi(multiplier))
elif action == 'saturate':
new_color.saturation += ((1 - self.saturation) * self.multi(multiplier))
elif action == 'desaturate':
new_color.saturation -= (self.saturation * self.multi(multiplier))
elif action == 'rgba':
red = self.red*255
green = self.green*255
blue = self.blue*255
trans = self.multi(multiplier)
return f'rgba({red:0.2f}, {green:0.2f}, {blue:0.2f}, {trans})'
return new_color
def color_func(action, color, multi):
return Color(color).alter(action, multi)

View file

@ -1,6 +1,6 @@
import argon2, os
from .misc import time_function_pprint
from izzylib import time_function_pprint
class PasswordHasher:

View file

@ -17,6 +17,6 @@ def create_app(appname, **kwargs):
from .application import Application, Blueprint
from .middleware import MediaCacheControl
from .request import Request
from .response import Response
from .request import ServerRequest
from .response import ServerResponse
from .view import View, Static

View file

@ -0,0 +1,12 @@
import os
from .application import Application
app = Application(tpl_default=False)
app.add_static(os.getcwd() + '/', '/')
try:
app.start()
except KeyboardInterrupt:
app.stop()

View file

@ -12,12 +12,12 @@ from jinja2.exceptions import TemplateNotFound
from . import http_methods, error, __file__ as module_root
from .config import Config
from .response import Response
from .response import ServerResponse
#from .router import Router
from .view import Static, Manifest, Robots, Style
from ..exceptions import MethodNotHandledException, NoBlueprintForPath
from ..http_utils import AsyncTransport
from ..utils import AsyncTransport
from ..template import Template
try:
@ -26,7 +26,7 @@ except ImportError:
Database = NotImplementedError('Failed to import SQL database class')
frontend = Path(module_root).parent.join('frontend')
frontend = Path(module_root).join('../../frontend').resolve()
class ApplicationBase:
@ -133,8 +133,9 @@ class ApplicationBase:
async def handle_request(self, request, response, path=None):
if request.host not in self.cfg.hosts and not request.path.startswith('/framework'):
raise error.BadRequest(f'Host not handled on this server: {request.host}')
if self.cfg.check_host:
if request.host not in self.cfg.hosts and not request.path.startswith('/framework'):
raise error.BadRequest(f'Host not handled on this server: {request.host}')
handler = self.get_route(path or request.path, request.method)
request._params = handler.params
@ -150,7 +151,7 @@ class ApplicationBase:
if isinstance(handler_response, dict):
response = self.cfg.response_class(**handler_response)
elif isinstance(handler_response, Response):
elif isinstance(handler_response, ServerResponse):
response = handler_response
elif not handler_response:
@ -366,7 +367,7 @@ class Application(ApplicationBase):
if not response.streaming:
## Don't use a custom response class here just in case it caused the error
response = Response(request=request).set_error('Server Error', 500)
response = ServerResponse(request=request).set_error('Server Error', 500)
if not response.streaming:
try:
@ -395,4 +396,4 @@ def set_response(request, resp_class, func, *args, **kwargs):
return getattr(resp_class, func)(*args, **kwargs)
except:
traceback.print_exc()
return Response(request=request).set_error('Server Error', 500)
return ServerResponse(request=request).set_error('Server Error', 500)

View file

@ -1,11 +1,14 @@
from .request import Request
from .response import Response
from izzylib import (
BaseConfig,
LowerDotDict,
boolean
)
from .request import ServerRequest
from .response import ServerResponse
from .. import __version__
from ..config import BaseConfig
from ..dotdict import LowerDotDict
from ..http_client_async import HttpClient
from ..misc import boolean
from ..client import Client
class Config(BaseConfig):
@ -22,13 +25,14 @@ class Config(BaseConfig):
host = None,
web_host = None,
alt_hosts = [],
check_host = False,
port = 8080,
proto = 'http',
access_log = True,
timeout = 60,
default_headers = LowerDotDict(),
request_class = Request,
response_class = Response,
request_class = ServerRequest,
response_class = ServerResponse,
sig_handler = None,
sig_handler_args = [],
sig_handler_kwargs = {},
@ -38,7 +42,7 @@ class Config(BaseConfig):
tpl_autoescape = True,
tpl_default = True,
tpl_favicon_path = '/framework/static/icon64.png',
client_class = HttpClient,
client_class = Client,
client_args = [],
client_kwargs = {}
)
@ -92,10 +96,10 @@ class Config(BaseConfig):
elif key == 'tpl_context' and not getattr(value, '__call__', None):
raise TypeError(f'{key} must be a callable')
elif key == 'request_class' and not issubclass(value, Request):
raise TypeError(f'{key} must be a subclass of izzylib.http_server_async.Request')
elif key == 'request_class' and not issubclass(value, ServerRequest):
raise TypeError(f'{key} must be a subclass of barkshark_http_async.ServerRequest')
elif key == 'response_class' and not issubclass(value, Response):
raise TypeError(f'{key} must be a subclass of izzylib.http_server_async.Response')
elif key == 'response_class' and not issubclass(value, ServerResponse):
raise TypeError(f'{key} must be a subclass of barkshark_http_async.ServerResponse')
return value

View file

@ -1,8 +1,5 @@
from datetime import datetime, timezone, timedelta
from .. import logging, boolean
from ..dotdict import DotDict
from ..path import Path
from izzylib import DotDict, Path, boolean, logging
UtcTime = timezone.utc

View file

@ -1,14 +1,12 @@
import asyncio, email, traceback
from datetime import datetime, timezone
from izzylib import DotDict, MultiDotDict, Url
from urllib.parse import unquote_plus
from .misc import Cookies, Headers, CookieItem
from ..dotdict import DotDict, MultiDotDict
from ..misc import Url
try: from ..http_signatures import verify_headers
try: from ..signatures import verify_headers
except ImportError: verify_headers = None
@ -16,7 +14,7 @@ UtcTime = timezone.utc
LocalTime = datetime.now(UtcTime).astimezone().tzinfo
class Request:
class ServerRequest:
__slots__ = [
'_body', '_form', '_method', '_app', '_params',
'address', 'path', 'version', 'headers', 'cookies',

View file

@ -1,15 +1,15 @@
import json, traceback
from datetime import datetime
from izzylib import MultiDotDict
from . import get_app
from .misc import Cookies, Headers, CookieItem
from ..dotdict import MultiDotDict
from ..http_utils import convert_to_bytes, create_message, first_line
from ..utils import convert_to_bytes, create_message, first_line
class Response:
class ServerResponse:
__slots__ = ['_app', '_body', 'headers', 'cookies', 'status', 'request', 'version']

View file

@ -1,6 +1,6 @@
import asyncio
from ..dotdict import DotDict
from izzylib import DotDict
class Transport:

View file

@ -1,9 +1,9 @@
import mimetypes
from izzylib import DotDict, Path
from . import http_methods, error
from ..dotdict import DotDict
from ..path import Path
from ..exceptions import (
InvalidMethodException,
MethodNotHandledException

View file

@ -6,12 +6,9 @@ from Crypto.Signature import PKCS1_v1_5
from base64 import b64decode, b64encode
from datetime import datetime
from functools import lru_cache
from izzylib import DefaultDotDict, DotDict, Url, izzylog
from tldextract import extract
from . import izzylog
from .dotdict import DefaultDotDict, DotDict
from .misc import Url
def generate_rsa_key():
privkey = RSA.generate(2048)

View file

@ -1,16 +1,14 @@
import codecs, traceback, os, json, xml
from colour import Color as Colour
from functools import partial
from hamlish_jinja import HamlishExtension
from izzylib import DotDict, Path, izzylog
from jinja2 import Environment, FileSystemLoader, ChoiceLoader, select_autoescape, Markup
from os import listdir, makedirs
from os.path import isfile, isdir, getmtime, abspath
from xml.dom import minidom
from . import izzylog
from .dotdict import DotDict
from .path import Path
from .color import Color, color_func
try:
from sanic import response as Response
@ -151,82 +149,3 @@ class Template(Environment):
html = self.render(tpl, request=request, **kwargs)
return Response.HTTPResponse(body=html, status=status, content_type=ctype, headers=kwargs.get('headers', {}))
class Color(Colour):
def __init__(self, color):
if isinstance(color, str):
super().__init__(f'#{str(color)}' if not color.startswith('#') else color)
elif isinstance(color, Colour):
super().__init__(str(color))
else:
raise TypeError(f'Color has to be a string or Color class, not {type(color)}')
def __repr__(self):
return self.__str__()
def __str__(self):
return self.hex_l
def lighten(self, multiplier):
return self.alter('lighten', multiplier)
def darken(self, multiplier):
return self.alter('darken', multiplier)
def saturate(self, multiplier):
return self.alter('saturate', multiplier)
def desaturate(self, multiplier):
return self.alter('desaturate', multiplier)
def rgba(self, multiplier):
return self.alter('rgba', multiplier)
def multi(self, multiplier):
if multiplier >= 100:
return 100
elif multiplier <= 0:
return 0
return multiplier / 100
def alter(self, action, multiplier):
new_color = Color(self)
if action == 'lighten':
new_color.luminance += ((1 - self.luminance) * self.multi(multiplier))
elif action == 'darken':
new_color.luminance -= (self.luminance * self.multi(multiplier))
elif action == 'saturate':
new_color.saturation += ((1 - self.saturation) * self.multi(multiplier))
elif action == 'desaturate':
new_color.saturation -= (self.saturation * self.multi(multiplier))
elif action == 'rgba':
red = self.red*255
green = self.green*255
blue = self.blue*255
trans = self.multi(multiplier)
return f'rgba({red:0.2f}, {green:0.2f}, {blue:0.2f}, {trans})'
return new_color
def color_func(action, color, multi):
return Color(color).alter(action, multi)

View file

@ -2,12 +2,15 @@ import asyncio, json
from datetime import datetime, timezone
from io import BytesIO
from izzylib import (
DateString,
DotDict,
Url
)
from .dotdict import DotDict
from .misc import DateString, Url
try:
from .http_signatures import sign_headers, verify_headers
from .signatures import sign_headers, verify_headers
except ImportError:
sign_headers = None
verify_headers = None