예제 #1
0
 def __getitem__(self, name):
     log.debug( sys._getframe().f_code.co_name )
     log.debug(type(name))
     log.debug(name)
     name = unicode(name)
     try:
         principal = DBSession.query(
             self.stub_factory).filter(
                 self.stub_factory.name == name).one()
         log.debug('principal found :: id={} name={} email={}'.format(
             principal.id, principal.name, principal.email))
         return principal
     except NoResultFound:
         try:
             account = DBSession.query(
                 self.factory).filter(
                     self.factory.email == self.__name2email(name)).one()
             log.debug('account found  id={} email={}'.format(
                 account.id, account.email))
             principal = DBSession.query(
                 self.stub_factory).filter(
                     self.stub_factory.id == account.id).one()
             log.debug('principal found :: id={} name={} email={}'.format(
                 principal.id, principal.name, principal.email))
             return principal
         except NoResultFound:
             log.error('KeyError')
             raise KeyError(name)
예제 #2
0
 def fruit_categories_bunch(cls, order_by, how_many=10):
     # fruit_categories contain fruits
     ret = []
     fruits = DBSession.query(Fruit).all()
     for r in DBSession.query(FruitCategory).all():
         ret.append(cls.make_record(r, fruits))
     return ret
예제 #3
0
    def create_fruit(self, request):
        data = ast.literal_eval(request.body)
        fruit_category = \
                DBSession.query(FruitCategory).filter_by(
                        id=data['fruit_category']).first()
        name = str(uuid.uuid4())

        fruit = Fruit(parent=fruit_category)
        fruit.__acl__ = SITE_ACL
        session = DBSession()
        session.add(fruit)

        workflow = get_workflow(fruit)
        if workflow:
            session.flush()
            workflow.transition_to_state(fruit, None, u'public')
        else:
            print '################ NO WORKFLOW for ', fruit.title

        session.flush()
        transaction.commit()

        fruit = DBSession.query(Fruit).filter_by(name=name).first()

        return {u'id': fruit.id,
                u'title': fruit.title,
                u'fruit_category': fruit.__parent__.id}
예제 #4
0
파일: util.py 프로젝트: igudym/Kotti
def default_search_content(search_term, request=None):

    searchstring = u'%%%s%%' % search_term

    # generic_filter can be applied to all Node (and subclassed) objects
    generic_filter = or_(Content.name.like(searchstring),
                         Content.title.like(searchstring),
                         Content.description.like(searchstring))

    results = DBSession.query(Content).filter(generic_filter).all()

    # specific result contain objects matching additional criteria
    # but must not match the generic criteria (because these objects
    # are already in the generic_results)
    document_results = DBSession.query(Document).filter(
        and_(Document.body.like(searchstring),
             not_(generic_filter)))

    for results_set in [content_with_tags([searchstring]),
                        document_results.all()]:
        [results.append(c) for c in results_set if not c in results]

    result_dicts = []

    for result in results:
        if has_permission('view', result, request):
            result_dicts.append(dict(
                name=result.name,
                title=result.title,
                description=result.description,
                path=request.resource_path(result)))

    return result_dicts
예제 #5
0
    def delete_nodes(self):
        """
        Delete nodes view. Renders either a view to delete multiple nodes or
        delete the selected nodes and get back to the referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if 'delete_nodes' in self.request.POST:
            ids = self.request.POST.getall('children-to-delete')
            if not ids:
                self.flash(_(u"Nothing was deleted."), 'info')
            for id in ids:
                item = DBSession.query(Node).get(id)
                self.flash(_(u'${title} was deleted.',
                             mapping=dict(title=item.title)), 'success')
                del self.context[item.name]
            return self.back('@@contents')

        if 'cancel' in self.request.POST:
            self.flash(_(u'No changes were made.'), 'info')
            return self.back('@@contents')

        ids = self._selected_children(add_context=False)
        items = []
        if ids is not None:
            items = DBSession.query(Node).filter(Node.id.in_(ids)).\
                order_by(Node.position).all()
        return {'items': items,
                'states': _states(self.context, self.request)}
예제 #6
0
 def fruit_category(self, cls, id_wanted):
     r = DBSession.query(FruitCategory).filter_by(id=id_wanted).first()
     if r is not None:
         fruits = DBSession.query(Fruit).all()
         return self.make_record(r, fruits)
     else:
         return None
예제 #7
0
파일: actions.py 프로젝트: rkintzi/Kotti
    def delete_nodes(self):
        """
        Delete nodes view. Renders either a view to delete multiple nodes or
        delete the selected nodes and get back to the referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if "delete_nodes" in self.request.POST:
            ids = self.request.POST.getall("children-to-delete")
            if not ids:
                self.request.session.flash(_(u"Nothing deleted."), "info")
            for id in ids:
                item = DBSession.query(Node).get(id)
                self.request.session.flash(_(u"${title} deleted.", mapping=dict(title=item.title)), "success")
                del self.context[item.name]
            return self.back("@@contents")

        if "cancel" in self.request.POST:
            self.request.session.flash(_(u"No changes made."), "info")
            return self.back("@@contents")

        ids = self._selected_children(add_context=False)
        items = []
        if ids is not None:
            items = DBSession.query(Node).filter(Node.id.in_(ids)).order_by(Node.position).all()
        return {"items": items, "states": _states(self.context, self.request)}
예제 #8
0
파일: resume.py 프로젝트: toway/mba
def edit_project(request, user, resume_id):
    t = request.POST["project"]
    if resume_id != int(request.POST['resume_id']):
        return Response(json.dumps({'__result':1}))
    #TODO use try/except
    if t == "new":
        resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first()
        obj = resources.ProjectInfo()
        cstruct2project(request.POST, obj)
        resume.projects.append(obj)
        #flush to get the new id
        DBSession.flush()
        widget = ProjectWidget(resume_id, resume.projects)
        json_string = json.dumps({'__result':0})
        return Response(json_string+"$"+widget.render())
    elif t == "modify":
        cstruct = {}
        cstruct2project(request.POST, cstruct)
        DBSession.query(resources.ProjectInfo).filter_by(resume_id=resume_id, id=int(request.POST['id'])).\
            update(cstruct, synchronize_session=False)
        resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first()
        widget = ProjectWidget(resume_id, resume.projects)
        json_string = json.dumps({'__result':0})
        return Response(json_string+"$"+widget.render())
    elif t == "delete":
        project = DBSession.query(resources.ProjectInfo).filter_by(resume_id=resume_id, id=int(request.POST['id'])).first()
        oid = project.id
        DBSession.delete(project)
        return Response(json.dumps({'__result':0,'id':oid}))
    return Response(json.dumps({'__result':1}))
예제 #9
0
파일: resume.py 프로젝트: toway/mba
def edit_job(request, user, resume_id):
    t = request.POST["experience"]
    if resume_id != int(request.POST['resume_id']):
        #TODO raise error
        pass
    if t == "new":
        resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first()
        job_schema = JobSchema()
        cstruct = job_schema.deserialize(request.POST)
        job_obj = resources.Job()
        cstruct2job(cstruct, job_obj)
        resume.jobs.append(job_obj)
        #flush to get the new id
        DBSession.flush()
        widget = JobsWidget(resume_id, resume.jobs)
        json_string = json.dumps({'__result':0})
        return Response(json_string+"$"+widget.render())
    elif t == "modify":
        job_schema = JobSchema()
        cstruct = job_schema.deserialize(request.POST)
        DBSession.query(resources.Job).filter_by(resume_id=resume_id, id=int(request.POST['id'])).\
            update(cstruct, synchronize_session=False)
        resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first()
        widget = JobsWidget(resume_id, resume.jobs)
        json_string = json.dumps({'__result':0})
        return Response(json_string+"$"+widget.render())
    elif t == "delete":
        job = DBSession.query(resources.Job).filter_by(resume_id=resume_id, id=int(request.POST['id'])).first()
        oid = job.id
        DBSession.delete(job)
        return Response(json.dumps({'__result':0,'id':oid}))
    return Response(json.dumps({'__result':1}))
예제 #10
0
파일: position.py 프로젝트: toway/mba
def job_detail_view(context, request):
    jquery.need()
    pos_id = request.matchdict['id']
    pos_id = int(pos_id)
    
    user = get_user(request)
    interest = ""
    if user.interest:
        interest = user.interest
    industry = ""
    if user.industry:
        industry = user.industry
    if interest == "" and industry == "":
        pos_like = DBSession.query(Position).all()[0:5]
    else:
        pos_like = DBSession.query(Position).join(CompanyInfo).filter(
                or_(Position.title.like(interest)
                    , CompanyInfo.industry.like(industry)) )[0:5]

    pos = DBSession.query(Position).get(pos_id)

    return {
            'pos': pos,
            'pos_like': pos_like,
            }
예제 #11
0
파일: infobox.py 프로젝트: toway/mba
def get_messages(type, context, request):
    jquery.need()

    cur_user = get_user(request)

    if not cur_user:
        return HTTPFound(location="/login?came_from=%s" % request.url)

    messages = []

    if type == 'all_messages':
        messages = DBSession.query(Message).filter_by(reciever_id=cur_user.id).all()
    elif type == 'system_messages':
        messages = DBSession.query(Message).filter(
            and_(
                Message.reciever_id==cur_user.id,
                or_(Message.type==0 ,
                    Message.type==1 ,
                    Message.type==10)
            )).all()
    elif type == 'friend_messages':
        messages = DBSession.query(Message).filter_by(reciever_id=cur_user.id, type=2).all()

    elif type == 'view_invitation_person':
        messages = DBSession.query(Message).filter_by(reciever_id=cur_user.id, type=11).all()

    elif type == 'view_invitation_meetup':
        messages = DBSession.query(Message).filter_by(reciever_id=cur_user.id, type=12).all()

    elif type == 'view_invitation_code':
        messages = view_or_generate_inviation_code(user)

    return {'type': type, 'messages': messages}
예제 #12
0
파일: resume.py 프로젝트: toway/mba
def edit_education(request, user, resume_id):
    t = request.POST["education"]
    if resume_id != int(request.POST['resume_id']):
        #TODO raise error
        pass

    if t == 'new':
        resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first()
        edu_schema = Education()
        cstruct = edu_schema.deserialize(request.POST)
        edu_obj = resources.Education()
        cstruct2edu(cstruct, edu_obj)
        resume.educations.append(edu_obj)
        #flush to get the new id
        DBSession.flush()
        widget = EducationsWidget(resume_id, resume.educations)
        json_string = json.dumps({'__result':0})
        return Response(json_string+"$"+widget.render())
    elif t == 'modify':
        edu_schema = Education()
        cstruct = edu_schema.deserialize(request.POST)
        DBSession.query(resources.Education).filter_by(resume_id=resume_id, id=int(request.POST['id'])).\
            update(cstruct, synchronize_session=False)
        resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first()
        widget = EducationsWidget(resume_id, resume.educations)
        json_string = json.dumps({'__result':0})
        return Response(json_string+"$"+widget.render())
    elif t == 'delete':
        edu = DBSession.query(resources.Education).filter_by(resume_id=resume_id, id=int(request.POST['id'])).first()
        oid = edu.id
        DBSession.delete(edu)
        return Response(json.dumps({'__result':0,'id':oid}))
    # raise error, not exists this operation
    return Response(json.dumps({'__result':1}))
예제 #13
0
 def _get_product(self, sku, subsku):
     """return tuple product & variation"""
     product = DBSession.query(
         VendoProduct).filter_by(sku=sku).one()
     variation = DBSession.query(
         VendoProductVariation).filter_by(sub_sku=subsku).one()
     return product, variation
예제 #14
0
    def create_fruit_category(self, request):
        data = ast.literal_eval(request.body)
        # Assume only one fruit_categories folder.
        fruit_categories_folder = \
                DBSession.query(FruitCategoriesFolder).first()
        name = str(uuid.uuid4())
        fruit_category = FruitCategory(name=name,
                                       title=data['title'],
                                       parent=fruit_categories_folder)
        fruit_category.__acl__ = SITE_ACL
        session = DBSession()
        session.add(fruit_category)

        workflow = get_workflow(fruit_category)
        if workflow:
            session.flush()
            workflow.transition_to_state(fruit_category, None, u'public')
        else:
            print '################ NO WORKFLOW for ', fruit_category.title

        session.flush()
        transaction.commit()

        fruit_category = \
                DBSession.query(FruitCategory).filter_by(name=name).first()

        return {u'id': fruit_category.id,
                u'title': fruit_category.title}
예제 #15
0
파일: edit.py 프로젝트: fschulze/Kotti
def order_node(context, request):
    P = request.POST

    if 'order-up' in P or 'order-down' in P:
        up, down = P.get('order-up'), P.get('order-down')
        child = DBSession.query(Node).get(int(down or up))
        if up is not None:
            mod = -1
        else:  # pragma: no cover
            mod = 1
        index = context.children.index(child)
        context.children.pop(index)
        context.children.insert(index + mod, child)
        request.session.flash(_(u'${title} moved.',
                                mapping=dict(title=child.title)), 'success')
        if not request.is_xhr:
            return HTTPFound(location=request.url)

    elif 'toggle-visibility' in P:
        child = DBSession.query(Node).get(int(P['toggle-visibility']))
        child.in_navigation ^= True
        mapping = dict(title=child.title)
        if child.in_navigation:
            msg = _(u'${title} is now visible in the navigation.',
                    mapping=mapping)
        else:
            msg = _(u'${title} is no longer visible in the navigation.',
                    mapping=mapping)
        request.session.flash(msg, 'success')
        if not request.is_xhr:
            return HTTPFound(location=request.url)

    return {}
예제 #16
0
파일: actions.py 프로젝트: rkintzi/Kotti
    def rename_nodes(self):
        """
        Rename nodes view. Renders either a view to change the titles and
        names for multiple nodes or handle the changes and get back to the
        referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if "rename_nodes" in self.request.POST:
            ids = self.request.POST.getall("children-to-rename")
            for id in ids:
                item = DBSession.query(Node).get(id)
                name = self.request.POST[id + "-name"]
                title = self.request.POST[id + "-title"]
                if not name or not title:
                    self.request.session.flash(_(u"Name and title are required."), "error")
                    location = resource_url(self.context, self.request) + "@@rename_nodes"
                    return HTTPFound(location=location)
                else:
                    item.name = title_to_name(name, blacklist=self.context.keys())
                    item.title = title
            self.request.session.flash(_(u"Your changes have been saved."), "success")
            return self.back("@@contents")

        if "cancel" in self.request.POST:
            self.request.session.flash(_(u"No changes made."), "info")
            return self.back("@@contents")

        ids = self._selected_children(add_context=False)
        items = []
        if ids is not None:
            items = DBSession.query(Node).filter(Node.id.in_(ids)).all()
        return {"items": items}
예제 #17
0
파일: banners.py 프로젝트: toway/mba
def admin_home_banners(context, request):
    jquery.need()

    user = get_user(request)
    if not user:
        return HTTPFound(location="/login?came_from=%s" % request.url)




    if 'method' in request.POST:
        # mt stands for meetup-type
        try:
            method = request.POST['method'] # del-banner

            if method  == 'del-banner':



                mt_id = int(request.POST['banner-id'])

                to_op_mt = DBSession.query(Banner).filter_by(id=mt_id).first()



                banner_id = request.POST.get('banner-id', None)

                if not banner_id :
                    return RetDict(errcode=RetDict.ERR_CODE_WRONG_PARAM)

                try:
                    banner_id = int(banner_id)
                except ValueError,e:
                    return RetDict(errcode=RetDict.ERR_CODE_WRONG_PARAM)


                banner = DBSession.query(Banner).filter_by(id=banner_id).first()

                if not banner:
                    return RetDict(errcode=RetDict.ERR_CODE_WRONG_PARAM)


                DBSession.delete(banner)

                msg = u"成功删除BANNER %d" % banner_id

                request.session.flash(msg, 'success')

                return RetDict(retval=msg)




        except Exception,ex:
            err_msg = "错误:%s" % ex
            request.session.flash(err_msg, 'danger')

            return RetDict(errmsg=err_msg)
예제 #18
0
파일: filedepot.py 프로젝트: Kotti/Kotti
    def delete(self, file_or_id: str) -> None:
        """Deletes a file. If the file didn't exist it will just do nothing.

        :param file_or_id: can be either ``DBStoredFile`` or a ``file_id``
        """

        file_id = self._get_file_id(file_or_id)

        DBSession.query(DBStoredFile).filter_by(file_id=file_id).delete()
예제 #19
0
    def test_clear(self, db_session):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node

        child = get_root()['child'] = Node()
        assert DBSession.query(Node).filter(Node.name == u'child').all() == [
            child]
        get_root().clear()
        assert DBSession.query(Node).filter(Node.name == u'child').all() == []
예제 #20
0
def delete_orphaned_tags(event):
    """Delete Tag instances / records when they are not associated with any
    content.

    :param event: event that trigerred this handler.
    :type event: :class:`ObjectAfterDelete`
    """

    DBSession.query(Tag).filter(~Tag.content_tags.any()).delete(
        synchronize_session=False)
예제 #21
0
파일: test_node.py 프로젝트: fschulze/Kotti
    def test_container_methods(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node

        session = DBSession()

        # Test some of Node's container methods:
        root = get_root()
        self.assertEquals(root.keys(), [])

        child1 = Node(name=u'child1', parent=root)
        session.add(child1)
        self.assertEquals(root.keys(), [u'child1'])
        self.assertEquals(root[u'child1'], child1)

        del root[u'child1']
        self.assertEquals(root.keys(), [])

        # When we delete a parent node, all its child nodes will be
        # released as well:
        root[u'child2'] = Node()
        root[u'child2'][u'subchild'] = Node()
        self.assertEquals(
            session.query(Node).filter(Node.name == u'subchild').count(), 1)
        del root[u'child2']
        self.assertEquals(
            session.query(Node).filter(Node.name == u'subchild').count(), 0)

        # We can pass a tuple as the key to more efficiently reach
        # down to child objects:
        root[u'child3'] = Node()
        subchild33 = Node(name=u'subchild33', parent=root[u'child3'])
        session.add(subchild33)
        del root.__dict__['_children']  # force a different code path
        self.assertTrue(
            root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33'])
        self.assertTrue(
            root[(u'child3', u'subchild33')] is subchild33)
        self.assertTrue(
            root[(u'child3', u'subchild33')] is subchild33)
        self.assertRaises(KeyError, root.__getitem__, (u'child3', u'bad-name'))
        root.children  # force a different code path
        self.assertRaises(KeyError, root.__getitem__, (u'child3', u'bad-name'))
        del root[u'child3']

        # Overwriting an existing Node is an error; first delete manually!
        child4 = Node(name=u'child4', parent=root)
        session.add(child4)
        self.assertEquals(root.keys(), [u'child4'])

        child44 = Node(name=u'child4')
        session.add(child44)
        root[u'child4'] = child44
        self.assertRaises(SQLAlchemyError, session.flush)
예제 #22
0
파일: populate.py 프로젝트: toway/mba
def test_act():
    # Step 1 Act test
    print 'Test Act'
    print DBSession.query(Act).count()
    act = Act(**_TEST_ATTRS)
    DBSession.add(act)
    print DBSession.query(Act).count()
    print 'Act.parts', act.parts

    # Step 2 Student test
    print 'Test Student'
    print DBSession.query(Student).count()
    stu = Student(name=u'test')
    DBSession.add(stu)
    print DBSession.query(Student).count()

    # Step 3 Participate test
    part = Participate()
    part.act_id = act.id
    part.user_id = stu.id
    DBSession.add(part)
    print 'Act.parts', act.parts
    DBSession.flush()
    #part = DBSession.query(Participate).first()
    #print 'Part user', part.user, part.act_id
    act = DBSession.query(Act).first()
    print 'query Act', act.id
    print 'Act.parts', act._parts
예제 #23
0
    def test_add(self, db_session, events):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Tag, TagsToContents

        root = get_root()
        root.tags = [u'tag 1', u'tag 2']
        result = DBSession.query(Tag).filter(TagsToContents.item == root).all()
        assert result[0].items == [root]
        assert root.tags == [u'tag 1', u'tag 2']
        assert len(DBSession.query(Tag).all()) == 2
예제 #24
0
파일: position_admin.py 프로젝트: toway/mba
def view_position_list(request, page_index=1, num_per_page=10):
    jquery.need()
    start = (page_index-1) * num_per_page
    count = DBSession.query(Position).count()
    positions = DBSession.query(Position).slice(start, num_per_page).all()

    return wrap_user2(request, {
        'positions': positions,
        'total_count': count,
        'total_page': count/ num_per_page + 1,
        'page_index': page_index
    })
예제 #25
0
    def change_state(self):
        """
        Change state view. Renders either a view to handle workflow changes
        for multiple nodes or handle the selected workflow changes and get
        back to the referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if 'change_state' in self.request.POST:
            ids = self.request.POST.getall('children-to-change-state')
            to_state = self.request.POST.get('to-state', u'no-change')
            include_children = self.request.POST.get('include-children', None)
            if to_state != u'no-change':
                items = DBSession.query(Node).filter(Node.id.in_(ids)).all()
                for item in items:
                    wf = get_workflow(item)
                    if wf is not None:
                        wf.transition_to_state(item, self.request, to_state)
                    if include_children:
                        childs = self._all_children(item,
                                                    permission='state_change')
                        for child in childs:
                            wf = get_workflow(child)
                            if wf is not None:
                                wf.transition_to_state(child,
                                                       self.request,
                                                       to_state, )
                self.request.session.flash(
                    _(u'Your changes have been saved.'), 'success')
            else:
                self.request.session.flash(_(u'No changes made.'), 'info')
            return self.back('@@contents')

        if 'cancel' in self.request.POST:
            self.request.session.flash(_(u'No changes made.'), 'info')
            return self.back('@@contents')

        ids = self._selected_children(add_context=False)
        items = transitions = []
        if ids is not None:
            wf = get_workflow(self.context)
            if wf is not None:
                items = DBSession.query(Node).filter(Node.id.in_(ids)).all()
                for item in items:
                        trans_info = wf.get_transitions(item, self.request)
                        for tran_info in trans_info:
                            if tran_info not in transitions:
                                transitions.append(tran_info)
        return {'items': items,
                'states': _states(self.context, self.request),
                'transitions': transitions, }
예제 #26
0
    def test_container_methods(self, db_session):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node

        # Test some of Node's container methods:
        root = get_root()
        assert root.keys() == []

        child1 = Node(name=u'child1', parent=root)
        DBSession.add(child1)
        assert root.keys() == [u'child1']
        assert root[u'child1'] == child1

        del root[u'child1']
        assert root.keys() == []

        # When we delete a parent node, all its child nodes will be
        # released as well:
        root[u'child2'] = Node()
        root[u'child2'][u'subchild'] = Node()
        assert (
            DBSession.query(Node).filter(Node.name == u'subchild').count() == 1)
        del root[u'child2']
        assert (
            DBSession.query(Node).filter(Node.name == u'subchild').count() == 0)

        # We can pass a tuple as the key to more efficiently reach
        # down to child objects:
        root[u'child3'] = Node()
        subchild33 = Node(name=u'subchild33', parent=root[u'child3'])
        DBSession.add(subchild33)
        del root.__dict__['_children']  # force a different code path
        assert root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33']
        assert root[(u'child3', u'subchild33')] is subchild33
        assert root[(u'child3', u'subchild33')] is subchild33
        with raises(KeyError):
            root[u'child3', u'bad-name']
        root.children  # force a different code path
        with raises(KeyError):
            root[u'child3', u'bad-name']
        del root[u'child3']

        # Overwriting an existing Node is an error; first delete manually!
        child4 = Node(name=u'child4', parent=root)
        DBSession.add(child4)
        assert root.keys() == [u'child4']

        child44 = Node(name=u'child4')
        DBSession.add(child44)
        root[u'child4'] = child44
        with raises(SQLAlchemyError):
            DBSession.flush()
예제 #27
0
파일: company_admin.py 프로젝트: toway/mba
def view_company_list(request, page_index=1, num_per_page=10):
    jquery.need()
    start = (page_index-1) * num_per_page
    count = DBSession.query(CompanyInfo).count()
    companies = DBSession.query(CompanyInfo).slice(start, num_per_page).all()

    return wrap_user2(request, {
        'companies': companies,
        'total_count': count,
        'total_page': count/ num_per_page + 1,
        'page_index': page_index
    })
예제 #28
0
def set_groups(name, context, groups_to_set=()):
    """Set the list of groups for principal with given ``name`` and in
    given ``context``.
    """
    name = unicode(name)
    from kotti.resources import LocalGroup
    DBSession.query(LocalGroup).filter(
        LocalGroup.node_id == context.id).filter(
        LocalGroup.principal_name == name).delete()

    for group_name in groups_to_set:
        DBSession.add(LocalGroup(context, name, unicode(group_name)))
예제 #29
0
    def test_delete_content_deletes_orphaned_tags(self, db_session, events):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Tag, Content

        root = get_root()
        root[u'content_1'] = Content()
        root[u'content_2'] = Content()
        root[u'content_1'].tags = [u'tag 1', u'tag 2']
        root[u'content_2'].tags = [u'tag 2']
        assert DBSession.query(Tag).count() == 2
        del root[u'content_1']
        assert DBSession.query(Tag).one().title == u'tag 2'
예제 #30
0
def cleanup_user_groups(event):
    """Remove a deleted group from the groups of a user/group and remove
       all local group entries of it."""
    name = event.object.name

    if name.startswith("group:"):
        principals = get_principals()
        users_groups = [p for p in principals if name in principals[p].groups]
        for user_or_group in users_groups:
            principals[user_or_group].groups.remove(name)

    DBSession.query(LocalGroup).filter(
        LocalGroup.principal_name == name).delete()
예제 #31
0
파일: base.py 프로젝트: Kotti/kotti_boxes
    def addable(self, context, request):
        resolver = DottedNameResolver()
        if hasattr(self, 'dotted_class'):
            resource_class = resolver.maybe_resolve(self.dotted_class)

            if resource_class:
                already_exists_box = DBSession.query(resource_class).\
                    filter(resource_class.parent_id == context.id).first()
                if already_exists_box is not None:
                    return False
            else:
                return False
        else:
            return False

        return super(BoxManagerTypeInfo, self).addable(context, request)
예제 #32
0
    def test_rename_to_empty_name(self):
        from kotti import DBSession
        from kotti.resources import Node
        from kotti.resources import Document
        from kotti.views.edit.actions import NodeActions

        root = DBSession.query(Node).get(1)
        child = root['child'] = Document(title=u"Child")
        request = DummyRequest()
        request.params['rename'] = u'on'
        request.params['name'] = u''
        request.params['title'] = u'foo'
        NodeActions(child, request).rename_node()
        assert (request.session.pop_flash('error') == [
            u'Name and title are required.'
        ])
예제 #33
0
    def cut_nodes(self):
        """
        Cut nodes view. Cut the current node or the selected nodes in the
        contents view and save the result in the session of the request.

        :result: Redirect response to the referrer of the request.
        :rtype: pyramid.httpexceptions.HTTPFound
        """
        ids = self._selected_children()
        self.request.session['kotti.paste'] = (ids, 'cut')
        for id in ids:
            item = DBSession.query(Node).get(id)
            self.flash(_(u'${title} was cut.', mapping=dict(title=item.title)),
                       'success')
        if not self.request.is_xhr:
            return self.back()
def upgrade():
    from alembic.context import get_bind

    conn = get_bind()
    if conn.engine.dialect.name == 'mysql':
        op.add_column('nodes', sa.Column('path', sa.Unicode(1000)))
    else:
        op.add_column('nodes', sa.Column('path', sa.Unicode(1000), index=True))

    from kotti import DBSession
    from kotti.resources import Node

    for node in DBSession.query(Node).with_polymorphic([Node]):
        reversed_lineage = reversed(tuple(lineage(node)))
        node.path = u'/'.join(
            node.__name__ for node in reversed_lineage) or u'/'
예제 #35
0
파일: security.py 프로젝트: cruxlog/Kotti
    def search(self, **kwargs):
        if not kwargs:
            return []

        filters = []
        for key, value in kwargs.items():
            col = getattr(self.factory, key)
            if '*' in value:
                value = value.replace('*', '%').lower()
                filters.append(func.lower(col).like(value))
            else:
                filters.append(col == value)

        query = DBSession.query(self.factory)
        query = query.filter(or_(*filters))
        return query
예제 #36
0
파일: security.py 프로젝트: cruxlog/Kotti
def principals_with_local_roles(context, inherit=True):
    """Return a list of principal names that have local roles in the
    context.
    """
    from resources import LocalGroup
    principals = set()
    items = [context]
    if inherit:
        items = lineage(context)
    for item in items:
        principals.update(
            r[0] for r in DBSession.query(LocalGroup.principal_name).filter(
                LocalGroup.node_id == item.id).group_by(
                    LocalGroup.principal_name).all()
            if not r[0].startswith('role:'))
    return list(principals)
예제 #37
0
파일: util.py 프로젝트: timgates42/Kotti
def nodes_tree(request, context=None, permission="view"):
    item_mapping = {}
    item_to_children = defaultdict(lambda: [])
    for node in DBSession.query(Content).with_polymorphic(Content):
        item_mapping[node.id] = node
        if request.has_permission(permission, node):
            item_to_children[node.parent_id].append(node)

    for children in item_to_children.values():
        children.sort(key=lambda ch: ch.position)

    if context is None:
        node = item_to_children[None][0]
    else:
        node = context

    return NodesTree(node, request, item_mapping, item_to_children, permission)
예제 #38
0
def nodes_tree(request):
    item_mapping = {}
    item_to_children = defaultdict(lambda: [])
    for node in DBSession.query(Content).with_polymorphic(Content):
        item_mapping[node.id] = node
        if has_permission('view', node, request):
            item_to_children[node.parent_id].append(node)

    for children in item_to_children.values():
        children.sort(key=lambda ch:ch.position)

    return NavigationNodeWrapper(
        item_to_children[None][0],
        request,
        item_mapping,
        item_to_children,
        )
예제 #39
0
def get_paste_items(context, request):
    from kotti.resources import Node

    items = []
    info = request.session.get("kotti.paste")
    if info:
        ids, action = info
        for id in ids:
            item = DBSession.query(Node).get(id)
            if item is None or not item.type_info.addable(context, request):
                continue
            if action == "cut" and inside(context, item):
                continue
            if context == item:
                continue
            items.append(item)
    return items
예제 #40
0
    def read(self, n=-1):
        """Reads ``n`` bytes from the file.

        If ``n`` is not specified or is ``-1`` the whole
        file content is read in memory and returned
        """
        if self._data is _marker:
            file_id = DBSession.merge(self).file_id
            self._data = DBSession.query(DBStoredFile.data).\
                filter_by(file_id=file_id).scalar()

        if n == -1:
            result = self._data[self._cursor:]
        else:
            result = self._data[self._cursor:self._cursor + n]

        self._cursor += len(result)

        return result
예제 #41
0
    def test_paste_without_edit_permission(self):
        from kotti import DBSession
        from kotti.resources import Node
        from kotti.views.edit import paste_node

        root = DBSession.query(Node).get(1)
        request = DummyRequest()
        request.params['paste'] = u'on'
        self.config.testing_securitypolicy(permissive=False)

        # We need to have the 'edit' permission on the original object
        # to be able to cut and paste:
        request.session['kotti.paste'] = (1, 'cut')
        self.assertRaises(Forbidden, paste_node, root, request)

        # We don't need 'edit' permission if we're just copying:
        request.session['kotti.paste'] = (1, 'copy')
        response = paste_node(root, request)
        self.assertEqual(response.status, '302 Found')
예제 #42
0
    def move(self, move):
        """
        Do the real work to move the selected nodes up or down. Called
        by the up and the down view.

        :result: Redirect response to the referrer of the request.
        :rtype: pyramid.httpexceptions.HTTPFound
        """
        ids = self._selected_children()
        if move == 1:
            ids.reverse()
        for id in ids:
            child = DBSession.query(Node).get(id)
            index = self.context.children.index(child)
            self.context.children.pop(index)
            self.context.children.insert(index + move, child)
            self.flash(_('${title} was moved.',
                         mapping=dict(title=child.title)), 'success')
        if not self.request.is_xhr:
            return self.back()
예제 #43
0
    def addable(self, context, request):
        resolver = DottedNameResolver()
        if hasattr(self, 'dotted_class'):
            resource_class = resolver.maybe_resolve(self.dotted_class)

            if resource_class:
                already_exists_action = DBSession.query(resource_class).\
                    filter(resource_class.parent_id == context.id).first()
                if already_exists_action is not None:
                    return False
            else:
                return False
        else:
            return False

        if INavigationRoot.providedBy(context) and \
           view_permitted(context, request, self.add_view):
            return True
        else:
            return False
예제 #44
0
    def test_paste_without_edit_permission(self, config, db_session):
        from kotti import DBSession
        from kotti.resources import Node
        from kotti.views.edit.actions import NodeActions

        root = DBSession.query(Node).get(1)
        request = DummyRequest()
        request.params['paste'] = u'on'
        config.testing_securitypolicy(permissive=False)

        # We need to have the 'edit' permission on the original object
        # to be able to cut and paste:
        request.session['kotti.paste'] = ([1], 'cut')
        view = NodeActions(root, request)
        with raises(Forbidden):
            view.paste_nodes()

        # We don't need 'edit' permission if we're just copying:
        request.session['kotti.paste'] = ([1], 'copy')
        response = NodeActions(root, request).paste_nodes()
        assert response.status == '302 Found'
예제 #45
0
def populate():
    """
    Create the root node (:class:`~kotti.resources.Document`) and the 'about'
    subnode in the nodes tree if there are no nodes yet.
    """
    lrm = LocalizerRequestMixin()
    lrm.registry = get_current_registry()
    lrm.locale_name = get_settings()['pyramid.default_locale_name']
    localizer = lrm.localizer

    if DBSession.query(Node.id).count() == 0:
        localized_root_attrs = dict([(k, localizer.translate(v))
                                     for k, v in _ROOT_ATTRS.iteritems()])
        root = Document(**localized_root_attrs)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        localized_about_attrs = dict([(k, localizer.translate(v))
                                      for k, v in _ABOUT_ATTRS.iteritems()])
        root['about'] = Document(**localized_about_attrs)
        DBSession.flush()

    populate_users()
예제 #46
0
    def set_visibility(self, show):
        """ Do the real work to set the visibility of nodes in the menu. Called
        by the show and the hide view.

        :result: Redirect response to the referrer of the request.
        :rtype: pyramid.httpexceptions.HTTPFound
        """
        ids = self._selected_children()
        for id in ids:
            child = DBSession.query(Node).get(id)
            if child.in_navigation != show:
                child.in_navigation = show
                mapping = dict(title=child.title)
                if show:
                    mg = _('${title} is now visible in the navigation.',
                           mapping=mapping)
                else:
                    mg = _('${title} is no longer visible in the navigation.',
                           mapping=mapping)
                self.flash(mg, 'success')
        if not self.request.is_xhr:
            return self.back()
예제 #47
0
def order_node(context, request):
    P = request.POST
    session = DBSession()

    if 'order-up' in P or 'order-down' in P:
        up, down = P.get('order-up'), P.get('order-down')
        id = int(down or up)
        if up is not None:
            mod = -1
        else:  # pragma: no cover
            mod = 1

        child = session.query(Node).get(id)
        index = context.children.index(child)
        context.children.pop(index)
        context.children.insert(index + mod, child)
        request.session.flash(
            _(u'${title} moved.', mapping=dict(title=child.title)), 'success')
        if not request.is_xhr:
            return HTTPFound(location=request.url)

    return {}
예제 #48
0
    def search(self, match='any', **kwargs):
        """ Search the principal database.

        :param match: ``any`` to return all principals matching any search
                      param, ``all`` to return only principals matching
                      all params
        :type match: str

        :param kwargs: Search conditions, e.g. ``name='bob', active=True``.
        :type kwargs: varying.

        :result: SQLAlchemy query object
        :rtype: :class:`sqlalchemy.orm.query.Query``
        """

        if not kwargs:
            return []

        filters = []

        for key, value in kwargs.items():
            col = getattr(self.factory, key)
            if isinstance(value, string_types) and '*' in value:
                value = value.replace('*', '%').lower()
                filters.append(func.lower(col).like(value))
            else:
                filters.append(col == value)

        query = DBSession.query(self.factory)

        if match == 'any':
            query = query.filter(or_(*filters))
        elif match == 'all':
            query = query.filter(and_(*filters))
        else:
            raise ValueError('match must be either "any" or "all".')

        return query
예제 #49
0
 def view_blog(self):
     macros = get_renderer('templates/macros.pt').implementation()
     query = DBSession.query(BlogEntry)
     query = query.filter(BlogEntry.parent_id == self.context.id)
     query = query.order_by(BlogEntry.date.desc())
     items = query.all()
     items = [
         item for item in items
         if has_permission('view', item, self.request)
     ]
     page = self.request.params.get('page', 1)
     use_pagination = get_setting('use_pagination')
     if use_pagination:
         items = Batch.fromPagenumber(items,
                                      pagesize=get_setting('pagesize'),
                                      pagenumber=int(page))
     return {
         'api': template_api(self.context, self.request),
         'macros': macros,
         'items': items,
         'use_pagination': use_pagination,
         'link_headline': get_setting('link_headline'),
     }
예제 #50
0
    def paste_nodes(self):
        """
        Paste nodes view. Paste formerly copied or cutted nodes into the
        current context. Note that a cutted node can not be pasted into itself.

        :result: Redirect response to the referrer of the request.
        :rtype: pyramid.httpexceptions.HTTPFound
        """
        ids, action = self.request.session['kotti.paste']
        for count, id in enumerate(ids):
            item = DBSession.query(Node).get(id)
            if item is not None:
                if action == 'cut':
                    if not self.request.has_permission('edit', item):
                        raise Forbidden()
                    item.__parent__.children.remove(item)
                    item.name = title_to_name(item.name,
                                              blacklist=list(self.context.keys()))
                    self.context[item.name] = item
                    if count is len(ids) - 1:
                        del self.request.session['kotti.paste']
                elif action == 'copy':
                    copy = item.copy()
                    name = copy.name
                    if not name:  # for root
                        name = copy.title
                    name = title_to_name(name, blacklist=list(self.context.keys()))
                    copy.name = name
                    self.context[name] = copy
                self.flash(_('${title} was pasted.',
                             mapping=dict(title=item.title)), 'success')
            else:
                self.flash(_('Could not paste node. It no longer exists.'),
                           'error')
        DBSession.flush()
        if not self.request.is_xhr:
            return self.back()
예제 #51
0
    def test_multi_delete(self):
        from kotti import DBSession
        from kotti.resources import Node
        from kotti.resources import Document
        from kotti.views.edit.actions import NodeActions

        root = DBSession.query(Node).get(1)
        root['child1'] = Document(title=u"Child 1")
        root['child2'] = Document(title=u"Child 2")

        request = DummyRequest()
        request.POST = MultiDict()
        id1 = str(root['child1'].id)
        id2 = str(root['child2'].id)
        request.POST.add('delete_nodes', u'delete_nodes')
        NodeActions(root, request).delete_nodes()
        assert request.session.pop_flash('info') ==\
            [u'Nothing deleted.']

        request.POST.add('children-to-delete', id1)
        request.POST.add('children-to-delete', id2)
        NodeActions(root, request).delete_nodes()
        assert request.session.pop_flash('success') ==\
            [u'${title} deleted.', u'${title} deleted.']
예제 #52
0
def paste_node(context, request):
    session = DBSession()
    id, action = request.session['kotti.paste']
    item = session.query(Node).get(id)
    if action == 'cut':
        if not has_permission('edit', item, request):
            raise Forbidden()
        item.__parent__.children.remove(item)
        context.children.append(item)
        del request.session['kotti.paste']
    elif action == 'copy':
        copy = item.copy()
        name = copy.name
        if not name:  # for root
            name = title_to_name(copy.title)
        while name in context.keys():
            name = disambiguate_name(name)
        copy.name = name
        context.children.append(copy)
    request.session.flash(
        _(u'${title} pasted.', mapping=dict(title=item.title)), 'success')
    if not request.is_xhr:
        location = resource_url(context, request)
        return HTTPFound(location=location)
예제 #53
0
def migrate_storage(from_storage, to_storage):
    from depot.fields.sqlalchemy import _SQLAMutationTracker
    from depot.manager import DepotManager
    from kotti.util import _to_fieldstorage
    import logging

    log = logging.getLogger(__name__)

    old_default = DepotManager._default_depot
    DepotManager._default_depot = to_storage

    for klass, props in _SQLAMutationTracker.mapped_entities.items():
        log.info("Migrating %r", klass)

        mapper = klass._sa_class_manager.mapper

        # use type column to avoid polymorphism issues, getting the same
        # Node item multiple times.
        type_ = camel_case_to_name(klass.__name__)
        for instance in DBSession.query(klass).filter_by(type=type_):
            for prop in props:
                uf = getattr(instance, prop)
                if not uf:
                    continue
                pk = mapper.primary_key_from_instance(instance)
                log.info("Migrating %s for %r with pk %r", prop, klass, pk)

                filename = uf['filename']
                content_type = uf['content_type']
                data = _to_fieldstorage(fp=uf.file,
                                        filename=filename,
                                        mimetype=content_type,
                                        size=uf.file.content_length)
                setattr(instance, prop, data)

    DepotManager._default_depot = old_default
예제 #54
0
파일: resources.py 프로젝트: dnouri/Kotti
def default_get_root(request=None):
    return DBSession.query(Node).filter(Node.parent_id == None).one()
예제 #55
0
파일: events.py 프로젝트: eugeneai/Kotti
def delete_orphaned_tags(event):
    DBSession.query(Tag).filter(~Tag.content_tags.any()).delete(
        synchronize_session=False)
예제 #56
0
def upgrade():
    from depot.manager import DepotManager
    from depot.fields.upload import UploadedFile
    from sqlalchemy import bindparam, Unicode, Column

    from kotti import DBSession, metadata

    files = sa.Table('files', metadata)
    files.c.data.type = sa.LargeBinary()    # this restores to old column type
    dn = DepotManager.get_default()

    _saved = []

    def process(thing):
        id, data, filename, mimetype = thing
        uploaded_file = UploadedFile({'depot_name': dn, 'files': []})
        uploaded_file._thaw()
        uploaded_file.process_content(
            data, filename=filename, content_type=mimetype)
        _saved.append({'nodeid': id, 'data': uploaded_file.encode()})
        log.info("Saved data for node id {}".format(id))

    query = DBSession.query(
        files.c.id, files.c.data, files.c.filename, files.c.mimetype
    ).order_by(files.c.id).yield_per(10)

    window_size = 10
    window_idx = 0

    log.info("Starting migration of blob data")

    now = time.time()
    while True:
        start, stop = window_size * window_idx, window_size * (window_idx + 1)
        things = query.slice(start, stop).all()
        if things is None:
            break
        for thing in things:
            process(thing)
        if len(things) < window_size:
            break
        window_idx += 1

    log.info("Files written on disk, saving information to DB")

    op.drop_column('files', 'data')
    op.add_column('files', Column('data', Unicode(4096)))
    files.c.data.type = Unicode(4096)

    update = files.update().where(files.c.id == bindparam('nodeid')).\
        values({files.c.data: bindparam('data')})

    def chunks(l, n):
        for i in range(0, len(l), n):
            yield l[i:i + n]

    for cdata in chunks(_saved, 10):
        DBSession.execute(update, cdata)

    log.info("Blob migration completed in {} seconds".format(
        int(time.time() - now)))
예제 #57
0
파일: util.py 프로젝트: Python3pkg/Kotti
def content_with_tags(tag_terms):

    return DBSession.query(Content).join(TagsToContents).join(Tag).filter(
        or_(*[Tag.title.like(tag_term) for tag_term in tag_terms])).all()
예제 #58
0
 def iterkeys(self):
     for (principal_name, ) in DBSession.query(self.factory.name):
         yield principal_name
예제 #59
0
파일: events.py 프로젝트: eugeneai/Kotti
def reset_content_owner(event):
    """Reset the owner of the content from the deleted owner."""
    contents = DBSession.query(Content).filter(
        Content.owner == event.object.name).all()
    for content in contents:
        content.owner = None
예제 #60
0
    def clear(self) -> None:

        DBSession.query(Node).filter(Node.parent == self).delete()