Exemplo n.º 1
0
    def __init__(self, url, session, signer=None, db=None, auth=None):
        self.get_url = url + '/get'
        self.add_url = url + '/add'
        self.edit_url = url + '/edit'
        self.delete_url = url + '/delete'
        self.signer = signer or URLSigner(session)
        self.db = db
        self.auth = auth

        # creates actions (entry points of the calls)
        # same as decorators but registered on object creation
        # very similar to Luca's old component creation
        self.__prerequisites__ = [session]
        args = list(filter(None, [session, db, auth, self.signer.verify()]))

        # function definition
        f = action.uses(*args)(self.get_comments)
        action(self.get_url + "/<id>", method=["GET"])(f)

        f = action.uses(*args)(self.add_comment)
        action(self.add_url, method=["POST"])(f)

        f = action.uses(*args)(self.edit_comment)
        action(self.edit_url, method=["POST"])(f)

        f = action.uses(*args)(self.delete_comment)
        action(self.delete_url, method=["POST"])(f)
Exemplo n.º 2
0
 def __init__(self, path, session, fields_or_table,
              redirect_url=None, readonly=False, signer=None,
              db=None, auth=None, url_params=None,
              validate=None):
     """fields_or_table is a list of Fields from DAL, or a table.
     If a table is passed, the fields that are marked writable
     (or readable, if readonly=True) are included.
     session is used to sign the URLs.
     The other parameters are optional, and are used only
     if they will be needed to process the get and post metods.
     @param path: path used for form GET/POST
     @param session: session, used to validate access and sign.
     @param fields_or_table: list of Field for a database table, or table itself.
     @param redirect_url: redirect URL after success.
     @param readonly: If true, the form is readonly.
     @param signer: signer for URLs, or else, a new signer is created.
     @param db: database.  Used by implementation.
     @param auth: auth.  Used by implementation.
     @param url_params: parameters for AJAX URLs.
     @param validate: A function that takes as arguments the dictionary of
         fields, and performs any desired extra validation.  If an error is
         set, then the form is not acted upon, and the error is shown to the user.
     """
     self.path_form = path + '/form'
     self.path_check = path + '/check'
     self.redirect_url = redirect_url
     self.db = db
     self.__prerequisites__ = [session]
     self.signer = signer or URLSigner(session)
     self.validate = validate
     # Creates entry points for giving the blank form, and processing form submissions.
     # There are three entry points:
     # - Form setup GET: This gets how the form is set up, including the types of the fields.
     # - Form GET: This gets the values of the fields.
     # - Form PUT: This gives the values of the fields, and performs whatever
     #   action needs to be peformed.
     # This division is done so that the GET and PUT action, but not the setup_GET,
     # need to be over-ridden when the class is subclassed.
     url_params = url_params or []
     # NOTE: we need a list below, as the iterator otherwise can be used only once.
     # Iterators by default are a very lame idea indeed.
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.get)
     action('/'.join([self.path_form] + url_params), method=["GET"])(f)
     f = action.uses(*args)(self.post)
     action('/'.join([self.path_form] + url_params), method=["POST"])(f)
     f = action.uses(*args)(self.validate_field)
     action('/'.join([self.path_check] + url_params), method=["POST"])(f)
     # Stores the parameters that are necessary for creating the form.
     # Generates the list of field descriptions.
     self.readonly = readonly
     self.fields = collections.OrderedDict()
     for field in fields_or_table:
         self.fields[field.name] = dict(
             field=field, # Field in the form specification.
             error=None,  # Any error found.
             value=None,
             validated_value=None,
         )
Exemplo n.º 3
0
    def __init__(self, url, session, signer=None, db=None, auth=None):
        self.url = url + '/get'
        self.callback_url = url + '/set'
        self.signer = signer or URLSigner(session)

        self.__prerequisites__ = [session]
        args = list(filter(None, [session, db, auth, self.signer.verify()]))
        func = action.uses(*args)(self.get_rating)
        action(self.url + '/<id>', method=['GET'])(func)
        func = action.uses(*args)(self.set_rating)
        action(self.callback_url + '/<id>', method=["GET"])(func)
Exemplo n.º 4
0
 def __init__(self, url, session, signer=None, db=None, auth=None):
     self.url = url + '/get'
     self.callback_url = url + '/set'
     self.signer = signer or URLSigner(session)
     # Creates an action (an entry point for URL calls),
     # mapped to the api method, that can be used to request pages
     # for the table.
     self.__prerequisites__ = [session]
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.get_rating)
     action(self.url + "/<id>", method=["GET"])(f)
     f = action.uses(*args)(self.set_rating)
     action(self.callback_url + "/<id>", method=["GET"])(f)
Exemplo n.º 5
0
 def enable(self, route='auth/', uses=(), env=None):
     """enables Auth, aka generates login/logout/register/etc pages"""
     self.route = route
     """This assumes the bottle framework and exposes all actions as /{app_name}/auth/{path}"""
     def responder(path, env=env):
         return self.action(path, request.method, request.query, request.json, env=env)
     action(route + '<path:path>', method=['GET','POST'])(action.uses(self, *uses)(responder))
Exemplo n.º 6
0
 def api(path):
     # this is not final, requires pydal 19.5
     args = path.split('/')
     app_name = args[0]
     from py4web.core import Reloader, DAL
     from pydal.restapi import RestAPI, ALLOW_ALL_POLICY, DENY_ALL_POLICY
     if MODE == 'full':
         policy = ALLOW_ALL_POLICY
     else:
         policy = DENY_ALL_POLICY
     module = Reloader.MODULES[app_name]
     def url(*args): return request.url + '/' + '/'.join(args)
     databases = [name for name in dir(module) if isinstance(getattr(module, name), DAL)]
     if len(args) == 1:
         def tables(name):
             db = getattr(module, name)
             return [{'name': t._tablename,
                      'fields': t.fields,
                      'link': url(name, t._tablename)+'?model=true'}
                     for t in getattr(module, name)]
         return {'databases': [{'name':name, 'tables': tables(name)} for name in databases]}
     elif len(args) > 2 and args[1] in databases:
         db = getattr(module, args[1])
         id = args[3] if len(args) == 4 else None
         data = action.uses(db)(lambda: RestAPI(db, policy)(
                 request.method, args[2], id, request.query, request.json))()
     else:
         data = {}
     if 'code' in data:
         response.status = data['code']
     return data
Exemplo n.º 7
0
 def __init__(self,
              path,
              session,
              search_placeholder=None,
              signer=None,
              db=None,
              auth=None):
     """
     Displays a grid.
     :param path: Path where the grid is loaded via AJAX.
     :param session: used by the signer.
     :param signer: singer for URLs.
     :param db: specify a db if you need it added as widget.
     :param auth: specify auth if you need it added as widget.
     """
     self.path = path
     self.search_placeholder = search_placeholder
     self.signer = signer or URLSigner(session)
     # Creates an action (an entry point for URL calls),
     # mapped to the api method, that can be used to request pages
     # for the table.
     self.__prerequisites__ = [session]
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.api)
     action(self.path, method=["GET"])(f)
Exemplo n.º 8
0
 def __init__(self, url, session, signer=None, db=None, auth=None, dumpDir="dump"):
     self.dumpDir = dumpDir
     self.url = url
     self.signer = signer or URLSigner(session)
     self.__prerequisites__ = [session]
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.api)
     action(self.url + "/<id>", method=["POST"])(f)
Exemplo n.º 9
0
    def enable(self, route='auth/'):
        self.route = route
        """This assumes the bottle framework and exposes all actions as /{app_name}/auth/{path}"""
        def responder(path):
            return self.action(path, request.method, request.query,
                               request.json)

        action(route + '<path:path>',
               method=['GET', 'POST'])(action.uses(self)(responder))
Exemplo n.º 10
0
 def __init__(self, db, policy=None, auth=None, path="service/{uuid}/<tablename>"):
     self.db = db
     self.policy = policy
     self.restapi = RestAPI(self.db, policy)
     self.path = path.format(uuid=str(uuid.uuid4()))
     args = [db, auth] if auth else [db]
     f = action.uses(*args)(self.api)
     f = action(self.path, method=["GET", "POST"])(f)
     f = action(self.path + "/<id:int>", method=["PUT", "DELETE"])(f)
Exemplo n.º 11
0
    def api(path):
        # this is not final, requires pydal 19.5
        args = path.split("/")
        app_name = args[0]
        from py4web.core import Reloader, DAL
        from pydal.restapi import RestAPI, Policy

        if MODE != "full":
            raise HTTP(403)
        module = Reloader.MODULES[app_name]

        def url(*args):
            return request.url + "/" + "/".join(args)

        databases = [
            name for name in dir(module) if isinstance(getattr(module, name), DAL)
        ]
        if len(args) == 1:

            def tables(name):
                db = getattr(module, name)
                return [
                    {
                        "name": t._tablename,
                        "fields": t.fields,
                        "link": url(name, t._tablename) + "?model=true",
                    }
                    for t in getattr(module, name)
                ]

            return {
                "databases": [
                    {"name": name, "tables": tables(name)} for name in databases
                ]
            }
        elif len(args) > 2 and args[1] in databases:
            db = getattr(module, args[1])
            id = args[3] if len(args) == 4 else None
            policy = Policy()
            for table in db:
                policy.set(table._tablename, 'GET', authorize=True,
                           allowed_patterns=["**"], allow_lookup=True,
                           fields=table.fields)
                policy.set(table._tablename,'PUT', authorize=True, fields=table.fields)
                policy.set(table._tablename,'POST', authorize=True, fields=table.fields)
                policy.set(table._tablename,'DELETE', authorize=True)
            data = action.uses(db, T)(
                lambda: RestAPI(db, policy)(
                    request.method, args[2], id, request.query, request.json
                )
            )()
        else:
            data = {}
        if "code" in data:
            response.status = data["code"]
        return data
Exemplo n.º 12
0
 def __init__(self, path, session, signer=None, db=None, auth=None):
     self.path = path
     self.signer = signer or URLSigner(session)
     # Creates an action (an entry point for URL calls),
     # mapped to the api method, that can be used to request pages
     # for the table.
     self.__prerequisites__ = [session]
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.api)
     action(self.path + "/<id>", method=["POST"])(f)
Exemplo n.º 13
0
 def __init__(self, path, session, signer=None, db=None, auth=None):
     """
     :param path: path at which the star rating does the AJAX calls
     :param session: session, used to validate access and sign.
     :param signer: A URL signer, or else one is created.
     :param db: Used in case db should be one of the widgets.
     :param auth: Used in case auth should be one of the widgets.
     """
     self.path = path
     self.signer = signer or URLSigner(session)
     # Creates an action (an entry point for URL calls),
     # mapped to the api method, that can be used to request pages
     # for the table.
     self.__prerequisites__ = [session]
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.get_stars)
     action(self.path + "/<id>", method=["GET"])(f)
     f = action.uses(*args)(self.set_stars)
     action(self.path + "/<id>", method=["POST"])(f)
Exemplo n.º 14
0
 def make_action(func, path=path, method=method, template=template):
     if not path:
         path = func.__name__
         for name in func.__code__.co_varnames[: func.__code__.co_argcount]:
             path += "/<%s>" % name
     fixtures = [f for f in self.fixtures]
     if template is None:
         template = func.__name__ + ".html"
     if template:
         fixtures.append(template)
     new_func = action.uses(*fixtures)(func)
     action(path, method=method)(new_func)
     return func
Exemplo n.º 15
0
 def __init__(self,
              db,
              policy=None,
              auth=None,
              path='service/{uuid}/<tablename>'):
     self.db = db
     self.policy = policy
     self.restapi = RestAPI(self.db, policy)
     self.path = path.format(uuid=str(uuid.uuid4()))
     args = [db, auth] if auth else [db]
     f = action.uses(*args)(self.api)
     f = action(self.path, method=['GET', 'POST'])(f)
     f = action(self.path + '/<id:int>', method=['PUT', 'DELETE'])(f)
Exemplo n.º 16
0
    def api(path):
        # this is not final, requires pydal 19.5
        args = path.split("/")
        app_name = args[0]
        from py4web.core import Reloader, DAL
        from pydal.restapi import RestAPI, ALLOW_ALL_POLICY, DENY_ALL_POLICY

        if MODE == "full":
            policy = ALLOW_ALL_POLICY
        else:
            policy = DENY_ALL_POLICY
        module = Reloader.MODULES[app_name]

        def url(*args):
            return request.url + "/" + "/".join(args)

        databases = [
            name for name in dir(module) if isinstance(getattr(module, name), DAL)
        ]
        if len(args) == 1:

            def tables(name):
                db = getattr(module, name)
                return [
                    {
                        "name": t._tablename,
                        "fields": t.fields,
                        "link": url(name, t._tablename) + "?model=true",
                    }
                    for t in getattr(module, name)
                ]

            return {
                "databases": [
                    {"name": name, "tables": tables(name)} for name in databases
                ]
            }
        elif len(args) > 2 and args[1] in databases:
            db = getattr(module, args[1])
            id = args[3] if len(args) == 4 else None
            data = action.uses(db, T)(
                lambda: RestAPI(db, policy)(
                    request.method, args[2], id, request.query, request.json
                )
            )()
        else:
            data = {}
        if "code" in data:
            response.status = data["code"]
        return data
    def __init__(self, url, session, signer=None, db=None, auth=None):

        # Creating generic get/set URLS
        self.url = url + '/get'

        self.callback_url = url + '/set'

        # Setting URL Signer
        self.signer = signer or URLSigner(session)

        #
        self.__prerequisites__ = [session]

        # Set each element to None in args
        args = list(filter(None, [session, db, auth, self.signer.verify()]))

        # *var in a function call unpacks a list or tuple into positional arguments
        # Gets the rating from database based on id

        # Equivalent of:
        # @action('url/<id>', method=["GET"])
        # @action.uses(session, db, auth, signer.verify())
        # def get_thumb():

        f = action.uses(*args)(self.get_rating)
        action(self.url + "/<id>", method=["GET"])(f)

        # Sets/Updates the rating in database based on id

        # Equivalent of:
        # @action('callback_url</id>', method=["GET"])
        # @action.uses(session, db, auth, signer.verify())
        # def set_thumb():

        f = action.uses(*args)(self.set_rating)
        action(self.callback_url + "/<id>", method=["GET"])(f)
Exemplo n.º 18
0
 def __init__(
     self,
     path,
     session,
     use_id=False,
     search_placeholder=None,
     signer=None,
     db=None,
     sort_fields=None,
     default_sort=None,
     auth=None,
     page_size=20,
 ):
     """
     Displays a grid.
     :param path: Path where the grid is loaded via AJAX.
     :param session: used by the signer.
     :param signer: singer for URLs.
     :param use_id: does the AJAX call come with an id?
     :param db: specify a db if you need it added as widget.
     :param sort_fields: list of fields that are sortable.  If a
         field is not sortable, use None.  E.g.:
         [db.user.name, None, db.user.email]
     :param default_sort: array that indicates the default sorting order.
     :param auth: specify auth if you need it added as widget.
     """
     assert session is not None, "You must provide a session."
     self.path = path
     self.search_placeholder = search_placeholder
     self.signer = signer or URLSigner(session)
     # Creates an action (an entry point for URL calls),
     # mapped to the api method, that can be used to request pages
     # for the table.
     self.use_id = use_id
     self.__prerequisites__ = [self.signer]
     args = list(filter(None, [session, db, auth, self.signer.verify()]))
     f = action.uses(*args)(self.api)
     p = "/".join([self.path, "<id>"]) if use_id else self.path
     action(p, method=["GET"])(f)
     # Some defaults.  Over-ride them in subclasses.
     self.sort_fields = sort_fields
     self.default_sort = default_sort
     self.page_size = page_size
Exemplo n.º 19
0
from py4web import action, redirect, URL, Field, HTTP
from py4web.utils.form import Form
from .common import flash, session, db, auth
from .make_up_data import make

#
# Convenience functions
#

authenticated_api = action.uses(session, db, auth.user)


def check_liked(items):
    """add a liked attributed to each item"""
    query = db.item_like.created_by == auth.user_id
    query &= db.item_like.item_id.belongs(items.as_dict().keys())
    liked_ids = [row.item_id for row in db(query).select(db.item_like.item_id)]
    for item in items:
        item["liked"] = "true" if item.id in liked_ids else "false"


def friend_ids(user_id):
    """return a list of ids of friends (included user_id self)"""
    query = db.friend_request.status == "accepted"
    query &= (db.friend_request.to_user
              == user_id) | (db.friend_request.from_user == user_id)
    rows = db(query).select()
    return (set([user_id])
            | set(row.from_user for row in rows)
            | set(row.to_user for row in rows))
Exemplo n.º 20
0
    return os.path.exists(os.path.join(FOLDER, project, ".git/config"))


class Logged(Fixture):
    def __init__(self, session):
        self.__prerequisites__ = [session]
        self.session = session

    def on_request(self):
        user = self.session.get("user")
        if not user or not user.get("id"):
            abort(403)


authenticated = ActionFactory(Logged(session))
session_secured = action.uses(Logged(session))


@action('version')
def version():
    return __version__


if MODE in ("demo", "readonly", "full"):

    @action("index")
    @action.uses("index.html", session, T)
    def index():
        return dict(
            languages=dumps(T.local.language),
            mode=MODE,
Exemplo n.º 21
0
 def define_routes(self, args, method, url, class_func):
     func = action.uses(*args)(class_func)
     action(url, method=method)(func)
Exemplo n.º 22
0
    def api(path):
        # this is not final, requires pydal 19.5
        args = path.split("/")
        app_name = args[0]
        if MODE != "full":
            raise HTTP(403)
        module = Reloader.MODULES.get(app_name)

        if not module:
            raise HTTP(404)

        def url(*args):
            return request.url + "/" + "/".join(args)

        databases = [
            name for name in dir(module) if isinstance(getattr(module, name), DAL)
        ]
        if len(args) == 1:

            def tables(name):
                db = getattr(module, name)                
                make_safe(db)
                return [
                    {
                        "name": t._tablename,
                        "fields": t.fields,
                        "link": url(name, t._tablename) + "?model=true",
                    }
                    for t in getattr(module, name)
                ]

            return {
                "databases": [
                    {"name": name, "tables": tables(name)} for name in databases
                ]
            }
        elif len(args) > 2 and args[1] in databases:
            db = getattr(module, args[1])
            make_safe(db)          
            id = args[3] if len(args) == 4 else None
            policy = Policy()
            for table in db:
                policy.set(
                    table._tablename,
                    "GET",
                    authorize=True,
                    allowed_patterns=["**"],
                    allow_lookup=True,
                    fields=table.fields,
                )
                policy.set(table._tablename, "PUT", authorize=True, fields=table.fields)
                policy.set(
                    table._tablename, "POST", authorize=True, fields=table.fields
                )
                policy.set(table._tablename, "DELETE", authorize=True)

            # must wrap into action uses to make sure it closes transactions
            data = action.uses(db)(lambda: RestAPI(db, policy)(
                request.method, args[2], id, request.query, request.json
            ))()
        else:
            data = {}
        if "code" in data:
            response.status = data["code"]
        return data
Exemplo n.º 23
0
 def create_route(self, url, method, protocol):
     func = action.uses(*self.args)(method)
     action(url, method=[protocol])(func)