U
    h                      @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dlm
Z
 d d	lmZ d d
lmZ G dd deZdd ZdddZdd ZdddZG dd deZdS )    N)abort)render_template)request)Database)DoesNotExist)Model)Proxy)SelectQuery)connectc                   @   s8   e Zd ZdddZdd Zdd	 Zd
d ZdddZdS )PaginatedQuerypageNFc                 C   sN   || _ || _|pd | _|| _t|tr8|| _| jj| _n|| _| j | _d S N)	paginate_bypage_varr   check_bounds
isinstancer	   querymodelselect)selfquery_or_modelr   r   r   r    r   9/tmp/pip-unpacked-wheel-5j60pwdk/playhouse/flask_utils.py__init__   s    

zPaginatedQuery.__init__c                 C   s<   | j d k	r| j S tj| j}|r8| r8tdt|S dS )N   )r   r   argsgetr   isdigitmaxint)r   Z	curr_pager   r   r   get_page   s    
zPaginatedQuery.get_pagec                 C   s0   t | ds*ttt| j | j | _| jS )N_page_count)	hasattrr   mathceilfloatr   countr   r!   r   r   r   r   get_page_count'   s
    
zPaginatedQuery.get_page_countc                 C   s2   | j r|  |  krtd | j|  | jS Ni  )r   r    r(   r   r   Zpaginater   r'   r   r   r   get_object_list-   s    zPaginatedQuery.get_object_list   c                 C   sN   t ||d  d}t|| |d }t t||| d}tt||d | S )N   r   )r   minlistrange)r   r   totalshowstartstopr   r   r   get_page_range2   s    zPaginatedQuery.get_page_range)r   NF)r+   )__name__
__module____qualname__r   r    r(   r*   r4   r   r   r   r   r      s     
	r   c                 G   sD   t | ts|  } z| j|  W S  tk
r>   td Y nX d S r)   )r   r	   r   wherer   r   r   )r   r   r   r   r   get_object_or_404<   s    
r9   object_list   r   Tc           	      K   s8   t |||||d}| ||< t| f|| d|S )N)r   r   r   r   )Z
paginationr   )r   r*   r   r    )	Ztemplate_namer   Zcontext_variabler   r   r   r   kwargsZpaginated_queryr   r   r   r:   D   s     c                   C   s   t jst jS dt jt jf S )Nz%s?%s)r   Zquery_stringpathr   r   r   r   get_current_urlT   s    r>   /c                 C   s0   t jdrt jd S t jdr,t jd S | S )Nnext)r   r   r   form)defaultr   r   r   get_next_urlY   s
    

rC   c                   @   sf   e Zd ZdZddedfddZdd Zdd Zd	d
 Zdd Z	dd Z
edd Zdd Zdd ZdS )FlaskDBa  
    Convenience wrapper for configuring a Peewee database for use with a Flask
    application. Provides a base `Model` class and registers handlers to manage
    the database connection during the request/response cycle.

    Usage::

        from flask import Flask
        from peewee import *
        from playhouse.flask_utils import FlaskDB


        # The database can be specified using a database URL, or you can pass a
        # Peewee database instance directly:
        DATABASE = 'postgresql:///my_app'
        DATABASE = PostgresqlDatabase('my_app')

        # If we do not want connection-management on any views, we can specify
        # the view names using FLASKDB_EXCLUDED_ROUTES. The db connection will
        # not be opened/closed automatically when these views are requested:
        FLASKDB_EXCLUDED_ROUTES = ('logout',)

        app = Flask(__name__)
        app.config.from_object(__name__)

        # Now we can configure our FlaskDB:
        flask_db = FlaskDB(app)

        # Or use the "deferred initialization" pattern:
        flask_db = FlaskDB()
        flask_db.init_app(app)

        # The `flask_db` provides a base Model-class for easily binding models
        # to the configured database:
        class User(flask_db.Model):
            email = CharField()

    Nc                 C   s8   d | _ || _|| _|| _|pd| _|d k	r4| | d S )Nr   )databasebase_model_class_app_db_excluded_routesinit_app)r   apprE   Zmodel_classZexcluded_routesr   r   r   r      s    
zFlaskDB.__init__c                 C   s|   || _ | jd krFd|jkr&|jd }qLd|jkr<|jd }qLtdn| j}d|jkrb|jd | _| || | | d S )NZDATABASEZDATABASE_URLzKMissing required configuration data for database: DATABASE or DATABASE_URL.ZFLASKDB_EXCLUDED_ROUTES)rG   rH   config
ValueErrorrI   _load_database_register_handlers)r   rK   Z
initial_dbr   r   r   rJ      s    




zFlaskDB.init_appc                 C   sV   t |tr|}n"t |tr*| t|}nt|}t | jtrL| j| n|| _d S r   )r   r   dict_load_from_config_dictdb_url_connectrE   r   Z
initialize)r   rK   Zconfig_valuerE   r   r   r   rN      s    

zFlaskDB._load_databasec                 C   s   z| d}| d}W n tk
r4   tdY nX d|krP|dd\}}n
d| }}z.t| tj| }t||}t|t	st
W n\ tk
r   td| Y n> tk
r   td| Y n  t
k
r   td	| Y nX ||f|S )
Nnameenginez:DATABASE configuration must specify a `name` and `engine`..r   peeweezUnable to import %szDatabase engine not found %sz5Database engine not a subclass of peewee.Database: %s)popKeyErrorRuntimeErrorrsplit
__import__sysmodulesgetattr
issubclassr   AssertionErrorImportErrorAttributeError)r   Zconfig_dictrS   rT   r=   
class_namemoduleZdatabase_classr   r   r   rQ      s,    



zFlaskDB._load_from_config_dictc                 C   s   | | j || j d S r   )Zbefore_request
connect_dbZteardown_requestclose_db)r   rK   r   r   r   rO      s    zFlaskDB._register_handlersc                    s,    j d krtdG  fddd j}|S )NzDatabase must be initialized.c                       s   e Zd ZG  fdddZdS )z*FlaskDB.get_model_class.<locals>.BaseModelc                       s   e Zd Z jZdS )z/FlaskDB.get_model_class.<locals>.BaseModel.MetaN)r5   r6   r7   rE   r   r'   r   r   Meta   s   rg   N)r5   r6   r7   rg   r   r'   r   r   	BaseModel   s   rh   )rE   rY   rF   )r   rh   r   r'   r   get_model_class   s    
zFlaskDB.get_model_classc                 C   s@   | j d kr&t| dd }|d kr&t | _t| ds:|  | _| jS )NrE   _model_class)rG   r^   r   rE   r"   ri   rj   )r   rE   r   r   r   r      s    


zFlaskDB.Modelc                 C   s$   | j rtj| j krd S | j  d S r   )rI   r   endpointrE   r
   r'   r   r   r   re      s    zFlaskDB.connect_dbc                 C   s.   | j rtj| j krd S | j s*| j  d S r   )rI   r   rk   rE   Z	is_closedclose)r   excr   r   r   rf      s    
zFlaskDB.close_db)r5   r6   r7   __doc__r   r   rJ   rN   rQ   rO   ri   propertyre   rf   r   r   r   r   rD   `   s   &




rD   )r:   r;   r   NT)r?   )r#   r\   Zflaskr   r   r   rV   r   r   r   r   r	   Zplayhouse.db_urlr
   rR   objectr   r9   r:   r>   rC   rD   r   r   r   r   <module>   s*   -        

