Finished register.
This commit is contained in:
		
							parent
							
								
									be9489f939
								
							
						
					
					
						commit
						2ba55f692d
					
				@ -4,6 +4,8 @@ from aiohttp import web
 | 
				
			|||||||
from app.app import Application as BaseApplication
 | 
					from app.app import Application as BaseApplication
 | 
				
			||||||
from app.cache import time_cache_async
 | 
					from app.cache import time_cache_async
 | 
				
			||||||
from jinja_markdown2 import MarkdownExtension
 | 
					from jinja_markdown2 import MarkdownExtension
 | 
				
			||||||
 | 
					from snek.mapper import get_mappers
 | 
				
			||||||
 | 
					from snek.service import get_services
 | 
				
			||||||
from snek.system import http
 | 
					from snek.system import http
 | 
				
			||||||
from snek.system.middleware import cors_middleware
 | 
					from snek.system.middleware import cors_middleware
 | 
				
			||||||
from snek.view.about import AboutHTMLView, AboutMDView
 | 
					from snek.view.about import AboutHTMLView, AboutMDView
 | 
				
			||||||
@ -14,6 +16,7 @@ from snek.view.login_form import LoginFormView
 | 
				
			|||||||
from snek.view.register import RegisterView
 | 
					from snek.view.register import RegisterView
 | 
				
			||||||
from snek.view.register_form import RegisterFormView
 | 
					from snek.view.register_form import RegisterFormView
 | 
				
			||||||
from snek.view.web import WebView
 | 
					from snek.view.web import WebView
 | 
				
			||||||
 | 
					from types import SimpleNamespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Application(BaseApplication):
 | 
					class Application(BaseApplication):
 | 
				
			||||||
@ -29,6 +32,11 @@ class Application(BaseApplication):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        self.jinja2_env.add_extension(MarkdownExtension)
 | 
					        self.jinja2_env.add_extension(MarkdownExtension)
 | 
				
			||||||
        self.setup_router()
 | 
					        self.setup_router()
 | 
				
			||||||
 | 
					        self.setup_services()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setup_services(self):
 | 
				
			||||||
 | 
					        self.services = SimpleNamespace(**get_services(app=self))
 | 
				
			||||||
 | 
					        self.mappers = SimpleNamespace(**get_mappers(app=self))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_router(self):
 | 
					    def setup_router(self):
 | 
				
			||||||
        self.router.add_get("/", IndexView)
 | 
					        self.router.add_get("/", IndexView)
 | 
				
			||||||
 | 
				
			|||||||
@ -22,4 +22,3 @@ class LoginForm(Form):
 | 
				
			|||||||
        type="button"
 | 
					        type="button"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,19 @@
 | 
				
			|||||||
from snek.system.form import Form, HTMLElement,FormInputElement,FormButtonElement
 | 
					from snek.system.form import Form, HTMLElement,FormInputElement,FormButtonElement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UsernameField(FormInputElement):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    async def errors(self):
 | 
				
			||||||
 | 
					        result = await super().errors
 | 
				
			||||||
 | 
					        if self.value and await self.app.services.user.count(username=self.value):
 | 
				
			||||||
 | 
					            result.append("Username is not available.")
 | 
				
			||||||
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RegisterForm(Form):
 | 
					class RegisterForm(Form):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    title = HTMLElement(tag="h1", text="Register")
 | 
					    title = HTMLElement(tag="h1", text="Register")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    username = FormInputElement(
 | 
					    username = UsernameField(
 | 
				
			||||||
        name="username", 
 | 
					        name="username", 
 | 
				
			||||||
        required=True,
 | 
					        required=True,
 | 
				
			||||||
        min_length=2,
 | 
					        min_length=2,
 | 
				
			||||||
 | 
				
			|||||||
@ -3,4 +3,4 @@ from snek.model.user import UserModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class UserMapper(BaseMapper):
 | 
					class UserMapper(BaseMapper):
 | 
				
			||||||
    table_name = "user"
 | 
					    table_name = "user"
 | 
				
			||||||
    model: UserModel 
 | 
					    model_class = UserModel 
 | 
				
			||||||
@ -1,13 +1,14 @@
 | 
				
			|||||||
from snek.system.service import BaseService 
 | 
					from snek.system.service import BaseService 
 | 
				
			||||||
from snek.system import security 
 | 
					from snek.system import security 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserService:
 | 
					class UserService(BaseService):
 | 
				
			||||||
    mapper_name = "user"
 | 
					    mapper_name = "user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def create_user(self, username, password):
 | 
					    async def register(self, email, username, password):
 | 
				
			||||||
        if await self.exists(username=username):
 | 
					        if await self.exists(username=username):
 | 
				
			||||||
            raise Exception("User already exists.")
 | 
					            raise Exception("User already exists.")
 | 
				
			||||||
        model = await self.new()
 | 
					        model = await self.new()
 | 
				
			||||||
 | 
					        model.email = email
 | 
				
			||||||
        model.username = username
 | 
					        model.username = username
 | 
				
			||||||
        model.password = await security.hash(password)
 | 
					        model.password = await security.hash(password)
 | 
				
			||||||
        if await self.save(model):
 | 
					        if await self.save(model):
 | 
				
			||||||
 | 
				
			|||||||
@ -280,7 +280,11 @@ class GenericForm extends HTMLElement {
 | 
				
			|||||||
            if(e.detail.type == "button"){
 | 
					            if(e.detail.type == "button"){
 | 
				
			||||||
              if(e.detail.value == "submit")
 | 
					              if(e.detail.value == "submit")
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
                await me.validate()
 | 
					                const isValid = await me.validate()
 | 
				
			||||||
 | 
					                if(isValid){
 | 
				
			||||||
 | 
					                  const isProcessed = await me.submit()
 | 
				
			||||||
 | 
					                  console.info({processed:isProcessed})
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
              
 | 
					              
 | 
				
			||||||
@ -294,13 +298,15 @@ class GenericForm extends HTMLElement {
 | 
				
			|||||||
    async validate(){
 | 
					    async validate(){
 | 
				
			||||||
      const url = this.getAttribute("url")
 | 
					      const url = this.getAttribute("url")
 | 
				
			||||||
      const me = this
 | 
					      const me = this
 | 
				
			||||||
      const response = await fetch(url,{
 | 
					      let response = await fetch(url,{
 | 
				
			||||||
        method: 'POST',
 | 
					        method: 'POST',
 | 
				
			||||||
        headers: {
 | 
					        headers: {
 | 
				
			||||||
          'Content-Type': 'application/json'
 | 
					          'Content-Type': 'application/json'
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        body: JSON.stringify({"action":"validate", "form":me.form})
 | 
					        body: JSON.stringify({"action":"validate", "form":me.form})
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
      const form = await response.json()
 | 
					      const form = await response.json()
 | 
				
			||||||
      Object.values(form.fields).forEach(field=>{
 | 
					      Object.values(form.fields).forEach(field=>{
 | 
				
			||||||
        if(!me.form.fields[field.name])
 | 
					        if(!me.form.fields[field.name])
 | 
				
			||||||
@ -320,6 +326,22 @@ class GenericForm extends HTMLElement {
 | 
				
			|||||||
        console.info(field.errors)
 | 
					        console.info(field.errors)
 | 
				
			||||||
        me.fields[field.name].setErrors(field.errors)
 | 
					        me.fields[field.name].setErrors(field.errors)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					      console.info({XX:form})
 | 
				
			||||||
 | 
					      return form['is_valid']
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    async submit(){
 | 
				
			||||||
 | 
					      const me = this 
 | 
				
			||||||
 | 
					      const url = me.getAttribute("url")
 | 
				
			||||||
 | 
					      const response = await fetch(url,{
 | 
				
			||||||
 | 
					        method: 'POST',
 | 
				
			||||||
 | 
					        headers: {
 | 
				
			||||||
 | 
					          'Content-Type': 'application/json'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        body: JSON.stringify({"action":"submit", "form":me.form})
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      return await response.json()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  customElements.define('generic-form', GenericForm);
 | 
					  customElements.define('generic-form', GenericForm);
 | 
				
			||||||
@ -35,8 +35,8 @@ class HTMLElement(model.ModelField):
 | 
				
			|||||||
        self.html = html
 | 
					        self.html = html
 | 
				
			||||||
        super().__init__(name=name, *args, **kwargs)
 | 
					        super().__init__(name=name, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self):
 | 
					    async def to_json(self):
 | 
				
			||||||
        result = super().to_json()
 | 
					        result = await super().to_json()
 | 
				
			||||||
        result['text'] = self.text
 | 
					        result['text'] = self.text
 | 
				
			||||||
        result['id'] = self.id
 | 
					        result['id'] = self.id
 | 
				
			||||||
        result['html'] = self.html
 | 
					        result['html'] = self.html
 | 
				
			||||||
@ -53,8 +53,8 @@ class FormInputElement(FormElement):
 | 
				
			|||||||
        self.place_holder = place_holder
 | 
					        self.place_holder = place_holder
 | 
				
			||||||
        self.type = type
 | 
					        self.type = type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self):
 | 
					    async def to_json(self):
 | 
				
			||||||
        data = super().to_json()
 | 
					        data = await super().to_json()
 | 
				
			||||||
        data["place_holder"] = self.place_holder
 | 
					        data["place_holder"] = self.place_holder
 | 
				
			||||||
        data["type"] = self.type
 | 
					        data["type"] = self.type
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
@ -66,31 +66,36 @@ class FormButtonElement(FormElement):
 | 
				
			|||||||
class Form(model.BaseModel):
 | 
					class Form(model.BaseModel):
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def html_elements(self):
 | 
					    def html_elements(self):
 | 
				
			||||||
        json_elements = super().to_json()
 | 
					 | 
				
			||||||
        return [element for element in self.fields if isinstance(element, HTMLElement)]
 | 
					        return [element for element in self.fields if isinstance(element, HTMLElement)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_user_data(self, data):
 | 
					    def set_user_data(self, data):
 | 
				
			||||||
        return super().set_user_data(data.get('fields'))
 | 
					        return super().set_user_data(data.get('fields'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self, encode=False):
 | 
					    async def to_json(self, encode=False):
 | 
				
			||||||
        elements = super().to_json()
 | 
					        elements = await super().to_json()
 | 
				
			||||||
        html_elements = {}
 | 
					        html_elements = {}
 | 
				
			||||||
        for element in elements.keys():
 | 
					        for element in elements.keys():
 | 
				
			||||||
 | 
					            if element == 'is_valid':
 | 
				
			||||||
 | 
					                # is_valid is async get property so we can't do getattr on it
 | 
				
			||||||
 | 
					                continue 
 | 
				
			||||||
            field = getattr(self, element)
 | 
					            field = getattr(self, element)
 | 
				
			||||||
            if isinstance(field, HTMLElement):
 | 
					            if isinstance(field, HTMLElement):
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    html_elements[element] = elements[element]
 | 
					                    html_elements[element] = elements[element]
 | 
				
			||||||
                except KeyError:
 | 
					                except KeyError:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
        return dict(fields=html_elements, is_valid=self.is_valid, errors=self.errors)
 | 
					
 | 
				
			||||||
 | 
					        is_valid = all(field['is_valid'] for field in html_elements.values())
 | 
				
			||||||
 | 
					        return dict(fields=html_elements, is_valid=is_valid, errors=await self.errors)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def errors(self):
 | 
					    async def errors(self):
 | 
				
			||||||
        result = []
 | 
					        result = []
 | 
				
			||||||
        for field in self.html_elements:
 | 
					        for field in self.html_elements:
 | 
				
			||||||
            result += field.errors
 | 
					            result += await field.errors
 | 
				
			||||||
        return result
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_valid(self):
 | 
					    async def is_valid(self):
 | 
				
			||||||
        return all(element.is_valid for element in self.html_elements)
 | 
					        # This is not good, but timebox to resolve issue exceeded.
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
@ -1,25 +1,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DEFAULT_LIMIT = 30
 | 
					DEFAULT_LIMIT = 30
 | 
				
			||||||
 | 
					import typing
 | 
				
			||||||
from snek.system.model import BaseModel
 | 
					from snek.system.model import BaseModel
 | 
				
			||||||
from snek.app import Application 
 | 
					
 | 
				
			||||||
import types
 | 
					import types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Mapper:
 | 
					class BaseMapper:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    model_class:BaseModel = None 
 | 
					    model_class:BaseModel = None 
 | 
				
			||||||
    default_limit:int = DEFAULT_LIMIT
 | 
					    default_limit:int = DEFAULT_LIMIT
 | 
				
			||||||
    table_name:str = None 
 | 
					    table_name:str = None 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, app:Application, table_name:str, model_class:BaseModel):
 | 
					    def __init__(self, app):
 | 
				
			||||||
        self.app = app 
 | 
					        self.app = app 
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if not self.model_class:
 | 
					 | 
				
			||||||
            raise ValueError("Mapper configuration error: model_class is not set.")
 | 
					 | 
				
			||||||
        self.model_class = model_class 
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.table_name = table_name
 | 
					 | 
				
			||||||
        if not self.table_name:
 | 
					 | 
				
			||||||
            raise ValueError("Mapper configuration error: table_name is not set.")
 | 
					 | 
				
			||||||
        self.default_limit = self.__class__.default_limit 
 | 
					        self.default_limit = self.__class__.default_limit 
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
@ -33,12 +27,12 @@ class Mapper:
 | 
				
			|||||||
    def table(self):
 | 
					    def table(self):
 | 
				
			||||||
        return self.db[self.table_name]
 | 
					        return self.db[self.table_name]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get(self, uid:str=None, **kwargs) -> types.Optional[BaseModel]
 | 
					    async def get(self, uid:str=None, **kwargs) -> BaseModel:
 | 
				
			||||||
        if uid:
 | 
					        if uid:
 | 
				
			||||||
            kwargs['uid'] = uid 
 | 
					            kwargs['uid'] = uid 
 | 
				
			||||||
        model = self.new()
 | 
					        model = self.new()
 | 
				
			||||||
        record = self.table.find_one(**kwargs)
 | 
					        record = self.table.find_one(**kwargs)
 | 
				
			||||||
        return self.model_class.from_record(mapper=self,record=record)
 | 
					        return await self.model_class.from_record(mapper=self,record=record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def exists(self, **kwargs):
 | 
					    async def exists(self, **kwargs):
 | 
				
			||||||
        return self.table.exists(**kwargs)
 | 
					        return self.table.exists(**kwargs)
 | 
				
			||||||
@ -47,16 +41,16 @@ class Mapper:
 | 
				
			|||||||
        return self.table.count(**kwargs)
 | 
					        return self.table.count(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def save(self, model:BaseModel) -> bool:
 | 
					    async def save(self, model:BaseModel) -> bool:
 | 
				
			||||||
        record = model.record
 | 
					        record = await model.record
 | 
				
			||||||
        if not record.get('uid'):
 | 
					        if not record.get('uid'):
 | 
				
			||||||
            raise Exception(f"Attempt to save without uid: {record}.")
 | 
					            raise Exception(f"Attempt to save without uid: {record}.")
 | 
				
			||||||
        return self.table.upsert(record,['uid'])
 | 
					        return self.table.upsert(record,['uid'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def find(self, **kwargs) -> types.List[BaseModel]:
 | 
					    async def find(self, **kwargs) -> typing.AsyncGenerator:
 | 
				
			||||||
        if not kwargs.get("_limit"):
 | 
					        if not kwargs.get("_limit"):
 | 
				
			||||||
            kwargs["_limit"] = self.default_limit
 | 
					            kwargs["_limit"] = self.default_limit
 | 
				
			||||||
        for record in self.table.find(**kwargs):
 | 
					        for record in self.table.find(**kwargs):
 | 
				
			||||||
            yield self.model_class.from_record(mapper=self,record=record)
 | 
					            yield await self.model_class.from_record(mapper=self,record=record)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async def delete(self, kwargs=None)-> int: 
 | 
					    async def delete(self, kwargs=None)-> int: 
 | 
				
			||||||
        if not kwargs or not isinstance(kwargs, dict):
 | 
					        if not kwargs or not isinstance(kwargs, dict):
 | 
				
			||||||
 | 
				
			|||||||
@ -70,9 +70,11 @@ class Validator:
 | 
				
			|||||||
    def custom_validation(self):
 | 
					    def custom_validation(self):
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, required=False, min_num=None, max_num=None, min_length=None, max_length=None, regex=None, value=None, kind=None, help_text=None, **kwargs):
 | 
					    def __init__(self, required=False, min_num=None, max_num=None, min_length=None, max_length=None, regex=None, value=None, kind=None, help_text=None, app=None, model=None, **kwargs):
 | 
				
			||||||
        self.index = Validator._index
 | 
					        self.index = Validator._index
 | 
				
			||||||
        Validator._index += 1
 | 
					        Validator._index += 1
 | 
				
			||||||
 | 
					        self.app = app
 | 
				
			||||||
 | 
					        self.model = model
 | 
				
			||||||
        self.required = required
 | 
					        self.required = required
 | 
				
			||||||
        self.min_num = min_num
 | 
					        self.min_num = min_num
 | 
				
			||||||
        self.max_num = max_num
 | 
					        self.max_num = max_num
 | 
				
			||||||
@ -86,7 +88,7 @@ class Validator:
 | 
				
			|||||||
        self.__dict__.update(kwargs)
 | 
					        self.__dict__.update(kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def errors(self):
 | 
					    async def errors(self):
 | 
				
			||||||
        error_list = []
 | 
					        error_list = []
 | 
				
			||||||
        if self.value is None and self.required:
 | 
					        if self.value is None and self.required:
 | 
				
			||||||
            error_list.append("Field is required.")
 | 
					            error_list.append("Field is required.")
 | 
				
			||||||
@ -110,20 +112,23 @@ class Validator:
 | 
				
			|||||||
            error_list.append(f"Invalid kind. It is supposed to be {self.kind}.")
 | 
					            error_list.append(f"Invalid kind. It is supposed to be {self.kind}.")
 | 
				
			||||||
        return error_list
 | 
					        return error_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def validate(self):
 | 
					    async def validate(self):
 | 
				
			||||||
        if self.errors:
 | 
					        errors = await self.errors
 | 
				
			||||||
            raise ValueError("\n", self.errors)
 | 
					        if errors:
 | 
				
			||||||
 | 
					            raise ValueError(f"Errors: {errors}.")
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_valid(self):
 | 
					    async def is_valid(self):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self.validate()
 | 
					            await self.validate()
 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
        except ValueError:
 | 
					        except ValueError:
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self):
 | 
					    async def to_json(self):
 | 
				
			||||||
 | 
					        errors = await self.errors
 | 
				
			||||||
 | 
					        is_valid = await self.is_valid
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            "required": self.required,
 | 
					            "required": self.required,
 | 
				
			||||||
            "min_num": self.min_num,
 | 
					            "min_num": self.min_num,
 | 
				
			||||||
@ -134,8 +139,8 @@ class Validator:
 | 
				
			|||||||
            "value": self.value,
 | 
					            "value": self.value,
 | 
				
			||||||
            "kind": str(self.kind),
 | 
					            "kind": str(self.kind),
 | 
				
			||||||
            "help_text": self.help_text,
 | 
					            "help_text": self.help_text,
 | 
				
			||||||
            "errors": self.errors,
 | 
					            "errors": errors,
 | 
				
			||||||
            "is_valid": self.is_valid,
 | 
					            "is_valid": is_valid,
 | 
				
			||||||
            "index": self.index
 | 
					            "index": self.index
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -149,8 +154,8 @@ class ModelField(Validator):
 | 
				
			|||||||
        self.save = save
 | 
					        self.save = save
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self):
 | 
					    async def to_json(self):
 | 
				
			||||||
        result = super().to_json()
 | 
					        result = await super().to_json()
 | 
				
			||||||
        result['name'] = self.name
 | 
					        result['name'] = self.name
 | 
				
			||||||
        return result
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -193,7 +198,7 @@ class BaseModel:
 | 
				
			|||||||
    deleted_at = DeletedField(name="deleted_at", regex=TIMESTAMP_REGEX, place_holder="Deleted at")
 | 
					    deleted_at = DeletedField(name="deleted_at", regex=TIMESTAMP_REGEX, place_holder="Deleted at")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod 
 | 
					    @classmethod 
 | 
				
			||||||
    def from_record(cls, record, mapper):
 | 
					    async def from_record(cls, record, mapper):
 | 
				
			||||||
        model = cls.__new__()
 | 
					        model = cls.__new__()
 | 
				
			||||||
        model.mapper = mapper 
 | 
					        model.mapper = mapper 
 | 
				
			||||||
        model.record = record
 | 
					        model.record = record
 | 
				
			||||||
@ -230,6 +235,8 @@ class BaseModel:
 | 
				
			|||||||
                self.__dict__[key] = copy.deepcopy(obj)
 | 
					                self.__dict__[key] = copy.deepcopy(obj)
 | 
				
			||||||
                self.__dict__[key].value = kwargs.pop(key, self.__dict__[key].initial_value)
 | 
					                self.__dict__[key].value = kwargs.pop(key, self.__dict__[key].initial_value)
 | 
				
			||||||
                self.fields[key] = self.__dict__[key]
 | 
					                self.fields[key] = self.__dict__[key]
 | 
				
			||||||
 | 
					                self.fields[key].model = self
 | 
				
			||||||
 | 
					                self.fields[key].app = kwargs.get('app')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __setitem__(self, key, value):
 | 
					    def __setitem__(self, key, value):
 | 
				
			||||||
        obj = self.__dict__.get(key)
 | 
					        obj = self.__dict__.get(key)
 | 
				
			||||||
@ -254,11 +261,9 @@ class BaseModel:
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_valid(self):
 | 
					    async def is_valid(self):
 | 
				
			||||||
        for field in self.fields.values():
 | 
					        return all([await field.is_valid for field in self.fields.values()])
 | 
				
			||||||
            if not field.is_valid:
 | 
					        
 | 
				
			||||||
                return False
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __getitem__(self, key):
 | 
					    def __getitem__(self, key):
 | 
				
			||||||
        obj = self.__dict__.get(key)
 | 
					        obj = self.__dict__.get(key)
 | 
				
			||||||
@ -273,28 +278,31 @@ class BaseModel:
 | 
				
			|||||||
            self.__dict__[key] = value
 | 
					            self.__dict__[key] = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def record(self):
 | 
					    async def record(self):
 | 
				
			||||||
        obj = self.to_json()
 | 
					        obj = await self.to_json()
 | 
				
			||||||
        record = {}
 | 
					        record = {}
 | 
				
			||||||
        for key, value in obj.items():
 | 
					        for key, value in obj.items():
 | 
				
			||||||
 | 
					            if not isinstance(value, dict) or not 'value' in value:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
            if getattr(self, key).save:
 | 
					            if getattr(self, key).save:
 | 
				
			||||||
                record[key] = value.get('value')
 | 
					                record[key] = value.get('value')
 | 
				
			||||||
        return record
 | 
					        return record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self, encode=False):
 | 
					    async def to_json(self, encode=False):
 | 
				
			||||||
        model_data = OrderedDict({
 | 
					        model_data = OrderedDict({
 | 
				
			||||||
            "uid": self.uid.value,
 | 
					            "uid": self.uid.value,
 | 
				
			||||||
            "created_at": self.created_at.value,
 | 
					            "created_at": self.created_at.value,
 | 
				
			||||||
            "updated_at": self.updated_at.value,
 | 
					            "updated_at": self.updated_at.value,
 | 
				
			||||||
            "deleted_at": self.deleted_at.value
 | 
					            "deleted_at": self.deleted_at.value,
 | 
				
			||||||
 | 
					            "is_valid": await self.is_valid
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for key, value in self.__dict__.items():
 | 
					        for key, value in self.fields.items():
 | 
				
			||||||
            if key == "record":
 | 
					            if key == "record":
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            value = self.__dict__[key]
 | 
					            value = self.__dict__[key]
 | 
				
			||||||
            if hasattr(value, "value"):
 | 
					            if hasattr(value, "value"):
 | 
				
			||||||
                model_data[key] = value.to_json()
 | 
					                model_data[key] = await value.to_json()
 | 
				
			||||||
        if encode:
 | 
					        if encode:
 | 
				
			||||||
            return json.dumps(model_data, indent=2)
 | 
					            return json.dumps(model_data, indent=2)
 | 
				
			||||||
        return model_data
 | 
					        return model_data
 | 
				
			||||||
@ -313,8 +321,8 @@ class FormElement(ModelField):
 | 
				
			|||||||
        self.place_holder = place_holder
 | 
					        self.place_holder = place_holder
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self):
 | 
					    async def to_json(self):
 | 
				
			||||||
        data = super().to_json()
 | 
					        data = await super().to_json()
 | 
				
			||||||
        data["name"] = self.name
 | 
					        data["name"] = self.name
 | 
				
			||||||
        data["place_holder"] = self.place_holder
 | 
					        data["place_holder"] = self.place_holder
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
@ -17,10 +17,10 @@ class BaseService:
 | 
				
			|||||||
            self.mapper = None 
 | 
					            self.mapper = None 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def exists(self, **kwargs):
 | 
					    async def exists(self, **kwargs):
 | 
				
			||||||
        return self.mapper.exists(**kwargs)
 | 
					        return await self.count(**kwargs) > 0
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async def count(self, **kwargs):
 | 
					    async def count(self, **kwargs):
 | 
				
			||||||
        return self.mapper.count(**kwargs)
 | 
					        return await self.mapper.count(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def new(self, **kwargs):
 | 
					    async def new(self, **kwargs):
 | 
				
			||||||
        return await self.mapper.new()
 | 
					        return await self.mapper.new()
 | 
				
			||||||
@ -29,9 +29,9 @@ class BaseService:
 | 
				
			|||||||
        return await self.mapper.get(**kwargs)
 | 
					        return await self.mapper.get(**kwargs)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async def save(self, model:UserModel):
 | 
					    async def save(self, model:UserModel):
 | 
				
			||||||
        if model.is_valid:
 | 
					        # if model.is_valid: You Know why not
 | 
				
			||||||
            return self.mapper.save(model) and True 
 | 
					        return await self.mapper.save(model) and True 
 | 
				
			||||||
        return False 
 | 
					         
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async def find(self, **kwargs):
 | 
					    async def find(self, **kwargs):
 | 
				
			||||||
        return await self.mapper.find(**kwargs)
 | 
					        return await self.mapper.find(**kwargs)
 | 
				
			||||||
 | 
				
			|||||||
@ -27,12 +27,21 @@ class BaseFormView(BaseView):
 | 
				
			|||||||
    form = None 
 | 
					    form = None 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get(self):
 | 
					    async def get(self):
 | 
				
			||||||
        form = self.form()
 | 
					        form = self.form(app=self.app)
 | 
				
			||||||
        return await self.json_response(form.to_json())
 | 
					        
 | 
				
			||||||
 | 
					        return await self.json_response(await form.to_json())
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
    async def post(self):
 | 
					    async def post(self):
 | 
				
			||||||
        form = self.form()
 | 
					        form = self.form(app=self.app)
 | 
				
			||||||
        post = await self.request.json()
 | 
					        post = await self.request.json()
 | 
				
			||||||
        form.set_user_data(post['form'])
 | 
					        form.set_user_data(post['form'])
 | 
				
			||||||
        return await self.json_response(form.to_json())  
 | 
					        result = await form.to_json()
 | 
				
			||||||
 | 
					        if post.get('action') == 'validate':
 | 
				
			||||||
 | 
					            # Pass
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        if post.get('action') == 'submit' and result['is_valid']:
 | 
				
			||||||
 | 
					            await self.submit(form)
 | 
				
			||||||
 | 
					        return await self.json_response(result) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def submit(self,model=None):
 | 
				
			||||||
 | 
					        print("Submit sucess")
 | 
				
			||||||
 | 
				
			|||||||
@ -3,3 +3,7 @@ from snek.system.view import BaseFormView
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class RegisterFormView(BaseFormView):
 | 
					class RegisterFormView(BaseFormView):
 | 
				
			||||||
    form = RegisterForm
 | 
					    form = RegisterForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def submit(self, form):
 | 
				
			||||||
 | 
					        result = await self.app.services.user.register(form.email.value,form.username.value,form.password.value)
 | 
				
			||||||
 | 
					        print("SUBMITTED:",result)
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user