Пример #1
0
    def approve(self):

        params = self.request.params
        id = params['id']
        listing = Listings.get_by_id(id)
        if listing:
            listing.approved = True
            listing.declined = False
            DBSession.flush()

            body = """<html><head></head><body>
                    <p>Dear %s,<p><br>

                    <p>Your Listing <a href="%s">%s</a> at Nairabricks has just been approved.</p>

                    <p>Yours sincerely,</p>
                    <p>The Happy Nairabricks Info Robot</p>
                    </body>
                    </html>
                    """ % (listing.user.fullname,
                           self.request.route_url(
                               'property_view',
                               name=listing.name), listing.serial)
            html_email_sender(self.request,
                              subject="Listing %s Approved" % listing.serial,
                              recipients=listing.user.email,
                              body=body)
            return dict(isOk=1, message="Listing approved")
        return dict(isOk=0, message="No such listing")
Пример #2
0
def restpass(request):
    title = "Reset password"
    submitted_hmac = request.matchdict.get('hmac')
    user_id = request.matchdict.get('user_id')
    form = Form(request, schema=ResetPasswordForm)
    if 'form_submitted' in request.POST and form.validate():
        user = Users.get_by_id(user_id)
        current_time = time.time()
        time_key = int(base64.b64decode(submitted_hmac[10:]))
        if current_time < time_key:
            hmac_key = hmac.new(
                '%s:%s:%d' % (str(user.id), 'r5$55g35%4#$:l3#24&', time_key),
                user.email).hexdigest()[0:10]
            if hmac_key == submitted_hmac[0:10]:
                #Fix me reset email, no such attribute email
                user.password = form.data['password']
                DBSession.merge(user)
                DBSession.flush()
                request.session.flash(
                    'success; Password Changed. Please log in')
                return HTTPFound(location=request.route_url('login'))
            else:
                request.session.flash(
                    'warning; Invalid request, please try again')
                return HTTPFound(location=request.route_url('forgot_password'))
    action_url = request.route_url("reset_password",
                                   user_id=user_id,
                                   hmac=submitted_hmac)
    return {
        'title': title,
        'form': FormRenderer(form),
        'action_url': action_url
    }
Пример #3
0
def company_uploadx(request):
    user = request.user
    filename = request.storage.save(request.POST['company_pix'],
                                    folder="logos")
    user.company_logo = filename
    DBSession.flush()
    return HTTPFound(location=request.route_url("user_edit"))
Пример #4
0
 def ratings(self):
     form = Form(self.request, schema=UserRatingSchema)
     prefix = self.request.matchdict['prefix']
     user = Users.get_by_path(prefix)
     title = 'Rate ' + user.fullname
     if 'form_submitted' in self.request.POST and form.validate():
         if user.id == self.request.user.id:
             self.request.session.flash("danger; You can't rate yourself")
             return HTTPFound(
                 location=self.request.route_url('profile', prefix=prefix))
         if user.rating:
             for rating in user.rating:
                 if rating.rater_id == self.request.user.id:
                     self.request.session.flash(
                         "warning; You have rated %s before" %
                         user.fullname)
                     return HTTPFound(location=self.request.route_url(
                         'profile', prefix=prefix))
         rating = UserRating(rater_id=self.request.user.id,
                             rated_id=user.id,
                             rating=form.data['rating'],
                             review=form.data['review'])
         DBSession.add(rating)
         DBSession.flush()
         self.request.session.flash("success; Success")
         return HTTPFound(
             location=self.request.route_url('profile', prefix=prefix))
     self.request.session.flash("danger; An Error occured")
     return HTTPFound(
         location=self.request.route_url('profile', prefix=prefix))
Пример #5
0
 def update_personal(self):
     user = self.request.user
     form = Form(self.request, schema=PersonalSchema, obj=user)
     if 'personal_submitted' in self.request.POST and form.validate():
         form.bind(user)
         DBSession.add(user)
         if form.data['prefix'] and form.data['prefix'] != user.prefix:
             user.prefix = create_path(form.data['prefix'], is_unique)
         DBSession.flush()
         if self.request.is_xhr:
             html = """<div class="alert alert-success alert-dismissable col-xs-12">
                         <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                         Update Successful
                         </div>"""
             return Response(html)
         self.request.session.flash("success; Update successful")
         return HTTPFound(location=self.request.route_url("user_edit"))
     if self.request.is_xhr:
         html = """<div class="alert alert-danger alert-dismissable col-xs-12">
                     <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                     Update Not Successful
                     </div>"""
         return Response(html)
     self.request.session.flash("success; Update successful")
     return HTTPFound(location=self.request.route_url("user_edit"))
Пример #6
0
    def delete(self):
        name = self.request.matchdict['name']
        blog = Blogs.get_by_name(name)
        user = blog.user
        if not blog:
            self.session.flash("warning; no such blog")
            return HTTPFound(location=self.request.route_url('blog_list'))
        body = '''<html><head></head><body>
                    <p>Dear %s,<p><br>

                    <p>Your blog post <a href="%s">%s</a> have just been deleted. This might be because of self promotion,
                    abuse or outright violation of our good neighbor policy</p>
                    <p>Please, you are only allowed to write articles that will help our community</p>

                    <p>Yours sincerely,<br>
                    The Happy Nairabricks Info Robot</p>
                    </body>
                    </html>
                    ''' % (user.fullname,
                           self.request.route_url('blog_view',
                                                  name=blog.name), blog.title)
        #html_email_sender(self.request,
        #        subject = "Blog Post deleted",
        #        recipients=user.email,
        #        body = body
        #        )
        DBSession.delete(blog)
        DBSession.flush()

        self.session.flash("success;  blog_deleted")
        return HTTPFound(location=self.request.route_url('blog_list'))
Пример #7
0
def listplans(request):
    plans = DBSession.query(Plans).order_by(Plans.id).all()
    form = Form(request, schema=PlanSchema())
    if 'form_submitted' in request.POST and form.validate():
        plan = form.bind(Plans())
        DBSession.add(plan)
        DBSession.flush()
        return HTTPFound(location=request.route_url('list_plans'))
    return dict(form=FormRenderer(form), plans=plans, title="List of plans")
Пример #8
0
 def view(self):
     id = self.request.matchdict['id']
     message = Messages.get_by_id(id)
     if not message:
         self.session.flash('info; No such message')
         return HTTPFound(location=self.request.route_url('home'))
     message.is_read = True
     DBSession.flush()
     return dict(message=message, mess='mess')
Пример #9
0
    def reg(self):
        title = 'Registration'
        usertypes = userTypes()
        states = get_states()
        msg = ''
        form = Form(self.request, schema=Registration)
        if 'form_submitted' in self.request.POST and form.validate():
            try:
                resp = self.request.POST['g-recaptcha-response']
            except:
                self.request.session.flash(
                    'danger; Failed captcha due to slow network')
                return HTTPFound(location=self.request.route_url('reg'))
            recaptcha_r = requests.post(
                recaptcha_endpoint,
                dict(secret=buddy_settings('recaptcha_secret'), response=resp))
            rdata = recaptcha_r.json()
            if rdata:
                if not rdata['success']:
                    msg = 'Failed recaptcha, please solve again'
                    return dict(form=FormRenderer(form),
                                msg=msg,
                                title=title,
                                usertypes=usertypes,
                                states=states)

            user = form.bind(Users())
            if 'ref_email' in self.request.session:
                referrer = Users.get_by_email(
                    self.request.session['ref_email'])
                if referrer:
                    user.parent_id = referrer.id
            with transaction.manager:
                DBSession.add(user)
                user.prefix = create_path(user.user_fullname, is_unique)
                DBSession.flush()
                timestamp = time.time() + 3600
                hmac_key = hmac.new(
                    '%s:%s:%d' %
                    (str(user.id), 'r5$55g35%4#$:l3#24&', timestamp),
                    user.email).hexdigest()[0:10]
                time_key = base64.urlsafe_b64encode('%d' % timestamp)
                email_hash = '%s%s' % (hmac_key, time_key)
                user_regmail(self.request, user.id, user.email, email_hash)
                headers = buddy_remember(self.request, user, event='R')
                self.session.flash(
                    "success;You should be receiving an email with a link to activate your "
                    "account within 10 minutes. Doing so will let you post properties/blog on this website."
                )
                return HTTPFound(location=self.request.route_url('account'),
                                 headers=headers)

        return dict(form=FormRenderer(form),
                    title=title,
                    usertypes=usertypes,
                    msg=msg,
                    states=states)
Пример #10
0
def editplans(request):
    pid = request.matchdict.get('id')
    plan = DBSession.query(Plans).get(pid)
    form = Form(request, schema=PlanSchema(), obj=plan)
    if 'form_submitted' in request.POST and form.validate():
        form.bind(plan)
        DBSession.add(plan)
        DBSession.flush()
        return HTTPFound(location=request.route_url('list_plans'))
    return dict(form=FormRenderer(form), plan=plan, title=plan.name + " Edit")
Пример #11
0
 def delete(self):
     prefix = self.request.matchdict['prefix']
     user = Users.get_by_path(prefix)
     if user:
         DBSession.delete(user)
         DBSession.flush()
         return HTTPFound(location=self.request.route_url('home'))
     else:
         self.request.session.flash("warning; User not found")
         return HTTPFound(location='/')
Пример #12
0
 def delete(self):
     id = self.request.matchdict['id']
     listing = Listings.get_by_id(id)
     if listing:
         DBSession.delete(listing)
         DBSession.flush()
         return HTTPFound(location=self.request.route_url('home'))
     else:
         self.request.session.flash("warning; Listing not found")
         return HTTPFound(location='/')
Пример #13
0
    def edit_blog(self):
        from buddy.models.properties_model import State

        def get_states():
            query = [(s.id, s.name) for s in DBSession.query(State).all()]
            return query

        name = self.request.matchdict['name']
        categories = get_categories()
        blog = Blogs.get_by_name(name)
        if not blog:
            self.session.flash("danger; No such blog post")
            return HTTPFound(location=self.request.route_url('blog_list'))
        title = "Editing " + blog.title
        form = Form(self.request, schema=BlogPost, obj=blog)
        if "form_submitted" in self.request.POST and form.validate():
            form.bind(blog, exclude=['category_id'])
            for i, cat in enumerate(blog.categories):
                if cat.id not in form.data['category_id']:
                    del blog.categories[i]
            catids = [cat.id for cat in blog.categories]
            for cate in form.data['category_id']:
                if cate not in catids:
                    t = DBSession.query(BlogCategory).get(cate)
                    blog.categories.append(t)
            blog.status = True
            DBSession.add(blog)
            DBSession.flush()
            return HTTPFound(
                location=self.request.route_url('blog_view', name=blog.name))
        elif "draft" in self.request.POST and form.validate():
            form.bind(blog, exclude=['category_id'])
            for i, cat in enumerate(blog.categories):
                if cat.id not in form.data['category_id']:
                    del blog.categories[i]
            catids = [cat.id for cat in blog.categories]
            for cate in form.data['category_id']:
                if cate not in catids:
                    t = DBSession.query(BlogCategory).get(cate)
                    blog.categories.append(t)
            blog.status = 0
            DBSession.add(blog)
            DBSession.flush()
            return HTTPFound(
                location=self.request.route_url('blog_view', name=blog.name))

        return {
            'form': FormRenderer(form),
            'blog_nav_cat': get_navcategories(),
            'title': title,
            'categories': categories,
            'blog': blog,
            'wb': 'wb',
            'states': get_states()
        }
Пример #14
0
def add_g(request):
    title = 'Add group'
    groups = DBSession.query(Groups).all()
    form = Form(request, schema=AddGroup)
    if 'form_submitted' in request.POST and form.validate():
        group = form.bind(Groups())
        DBSession.add(group)
        DBSession.flush()
        redir_url = request.route_url('dashboard')
        return HTTPFound(location=redir_url)
    return dict(form=FormRenderer(form), groups=groups, title=title)
Пример #15
0
    def delete_m(self):
        id = self.request.matchdict['id']
        user_id = self.request.matchdict['user_id']

        message = Messages.get_by_id(id)
        if not message:
            self.session.flash('info; No such message')
            return HTTPFound(location=self.request.route_url('home'))
        DBSession.delete(message)
        DBSession.flush()
        return HTTPFound(location=self.request.route_url('inbox', id=user_id))
Пример #16
0
def user_pix(request):
    user = request.user
    fileO = request.POST['profile_pix']
    data = StringIO(fileO.file.read())
    resized_data = make_thumbnail(data)
    filename = request.storage.save_file_io(resized_data,
                                            fileO.filename,
                                            randomize=True,
                                            folder="profilepics")
    user.photo = filename
    DBSession.flush()
    return HTTPFound(location=request.route_url("user_edit"))
Пример #17
0
def company_upload(request):
    user = request.user
    fileO = request.POST['cover_pix']
    data = StringIO(fileO.file.read())
    optimized_data = optimize(data)
    filename = request.storage.save_file_io(optimized_data,
                                            fileO.filename,
                                            randomize=True,
                                            folder="coverphotos")
    user.cover_photo = filename
    DBSession.flush()
    return HTTPFound(location=request.route_url("user_edit"))
Пример #18
0
def buddy_remember(request, user, event='L'):
    if asbool(buddy_settings('log_logins')):
        if buddy_settings('log_login_header'):
            ip_addr = request.environ.get(
                buddy_settings('log_login_header'),
                u'invalid value - buddy.log_login_header')
        else:
            ip_addr = unicode(request.environ['REMOTE_ADDR'])
        record = AuthUserLog(user_id=user.id, ip_addr=ip_addr, event=event)
        DBSession.add(record)
        DBSession.flush()
        return remember(request, user.id)
    return remember(request, user.id)
Пример #19
0
def verify(request):
    prefix = request.matchdict['prefix']
    user = Users.get_by_path(prefix)
    if not user:
        request.session.flash('danger; user not found')
    user.is_verified = True
    user_parent = user.parent
    silver_plan = DBSession.query(Plans).filter(Plans.name == 'Silver').first()
    if user_parent:
        if not user_parent.earned_benefit:
            if user.active_subscription:
                active_sub = user.active_subscription[0]
                subscription = Subscription(user=user,
                                            plan=silver_plan,
                                            amount=0,
                                            no_of_months=1,
                                            discount=u"100%",
                                            status=u"Active")
                subscription.start_date = active_sub.end_date
                subscription.end_date = active_sub.end_date + timedelta(
                    days=30)
            else:
                subscription = Subscription(user=request.user,
                                            plan=silver_plan,
                                            amount=0,
                                            no_of_months=1,
                                            discount=u"100%",
                                            start_date=datetime.today(),
                                            end_date=datetime.today() +
                                            timedelta(days=30),
                                            status=u"Active")
            DBSession.add(subscription)
            DBSession.flush()
    body = """<html><head><title>Verified on nairabricks.com</title></head><body>
            <p>Dear %s,<p><br>
            <p>You are now verified as a professional in Nairabricks</p>
            <p>However, please note that we still have the right to decline your listings if they violate our property listing policy</p>
            <p>Moreso, ensure that your listings are not duplicated.
            Instead of having duplicate listings, update your listing frequently to keep it at the top</p>
            <p>Yours sincerely,</p>
            <p>The Happy Nairabricks Info Robot</p>
            </body>
            </html>
            """ % user.fullname

    html_email_sender(request,
                      subject="Congratulations",
                      recipients=user.email,
                      body=body)
    request.session.flash('success; user verified')
    return HTTPFound(location=request.route_url('user_list'))
Пример #20
0
def promo_sub(request):
    id = request.matchdict['id']
    user = Users.get_by_id(id)
    if not user:
        return HTTPNotFound()
    form = Form(request, schema=PromoSubSchema)
    if 'submit' in request.POST and form.validate():
        plan_id = form.data['plan']
        plan = DBSession.query(Plans).get(plan_id)
        if plan:
            subscription = Subscription(user=user,
                                        plan=plan,
                                        amount=0,
                                        no_of_months=1,
                                        discount="100%",
                                        status="Active",
                                        start_date=datetime.today(),
                                        end_date=datetime.today() +
                                        timedelta(days=30))
            DBSession.add(subscription)
            DBSession.flush()
            if request.is_xhr:
                html = """<div class="alert alert-success alert-dismissable col-xs-12">
                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                            User subscription
                            </div>"""
                return Response(html)
            request.session.flash('success; User subscribed')
            return HTTPFound(
                location=request.route_url('profile', prefix=user.prefix))
        if request.is_xhr:
            html = """<div class="alert alert-danger alert-dismissable col-xs-12">
                        <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                        An error occured, user Not subscribed
                        </div>"""
            return Response(html)
        request.session.flash('danger; An error occured, user subscribed %s' %
                              form.all_errors())
        return HTTPFound(
            location=request.route_url('profile', prefix=user.prefix))
    if request.is_xhr:
        html = """<div class="alert alert-danger alert-dismissable col-xs-12">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                    An error occured, user Not subscribed
                    </div>"""
        return Response(html)
    request.session.flash('danger; An error occured, user subscribed %s' %
                          form.all_errors())
    return HTTPFound(location=request.route_url('profile', prefix=user.prefix))
Пример #21
0
 def markassold(self):
     params = self.request.params
     token = params['token']
     id = params['id']
     price = params['price']
     price = str(price[2:])
     price = ''.join([i for i in price if i.isdigit()])
     if len(price) < 3:
         return dict(isOk=0, message="Enter price value")
     listing = Listings.get_by_id(id)
     if listing and (token == self.request.session.get_csrf_token()):
         listing.sold_price = price
         listing.status = False
         DBSession.flush()
         return dict(isOk=1, message="Success")
     return dict(isOk=0, message="No such listing")
Пример #22
0
 def inbox(self):
     id = self.request.matchdict['id']
     user = Users.get_by_id(id)
     if not user:
         self.session.flash('info; No such user')
         return HTTPFound(location=self.request.route_url('home'))
     messages = DBSession.query(Messages).filter(
         Messages.user_id == user.id).order_by(
             Messages.created.desc()).all()
     page_url = PageURL_WebOb(self.request)
     paginator = Page(messages,
                      page=int(self.request.params.get("page", 1)),
                      url=page_url)
     for message in messages:
         message.is_seen = True
     DBSession.flush()
     return dict(user=user, paginator=paginator, mess='mess')
Пример #23
0
 def makefavourites(self):
     for r in self.request.params:
         opts = r
     params = json.loads(opts)
     listing = Listings.get_by_id(params['id'])
     positive = params['positive']
     if listing:
         user = self.request.user
         if int(positive) == 1:
             user.favourites.remove(listing)
             DBSession.flush()
             return dict(isOk=1, message='Property removed from favourite')
         else:
             user.favourites.append(listing)
             DBSession.flush()
             return dict(isOk=1, message='Property saved')
     return dict(isOk=0, message="Please try again")
Пример #24
0
def delete_district(request):
    dbsession=DBSession()
    district_id = request.matchdict['district_id']
    lga_id = request.matchdict['lga_id']
    district = District.get_by_id(district_id)
    if district is None:
        request.session.flash('info; No such area')
        return HTTPFound(location = request.route_url("view_district",lga_id=lga_id))
    try:
        dbsession.delete(district)
        DBSession.flush()
        request.session.flash('success; district deleted')
        return HTTPFound(location = request.route_url("view_lga",lga_id=lga_id))
    except IntegrityError:
        transaction.abort()
        request.session.flash('info; operation failed')
        return HTTPFound(location = request.route_url("view_lga",lga_id=lga_id))
Пример #25
0
    def view_p(self):
        name = self.request.matchdict['name']
        listing = Listings.get_by_name(name)
        if not listing:
            self.request.session.flash('warning; Listing not found')
            return HTTPFound(location=self.request.route_url('home'))
        form = Form(self.request)
        files = listing.pictures.all()
        #city = DBSession.query(Locality).filter(Locality.state_id==listing.state_id).\
        #    filter(Locality.city_name==listing.city).first()
        category = listing.property_extra
        '''
        receiver = listing.user.email
        body = """
        <html><head></head><body>
        <p>Dear %s,<p><br>

        <p>A user at Nairabricks viewed your property <a href="%s">%s</a> just now.</p>

        <p>Yours sincerely,</p>
        <p>The Happy Nairabricks Info Robot</p>
        </body>
        </html>
        """%(listing.user.fullname,self.request.route_url('property_view',name=name),listing.serial)
        if not self.request.user==listing.user:
            html_email_sender(self.request,
            subject = "Property Clicks",
            recipients=receiver,
            body = body
        )
        '''
        view_log = Content_Stat(content_id=listing.id, views=1)
        DBSession.add(view_log)
        DBSession.flush()

        return dict(files=files,
                    title=listing.title,
                    form=FormRenderer(form),
                    category=category,
                    listing=listing
                    #, locality=city
                    )
Пример #26
0
    def view_blog(self):
        name = self.request.matchdict['name']
        blog = Blogs.get_by_name(name)
        if not blog:
            self.session.flash("danger; No such blog post")
            return HTTPFound(location=self.request.route_url('blog_list'))
        title = blog.title
        bcategor = DBSession.query(Blogs).filter(
            Blogs.user_id == blog.user.id).all()
        bc = [s.categories for s in bcategor]
        bc = histogram(bc)
        view_log = Content_Stat(content_id=blog.id, views=1)
        DBSession.add(view_log)

        DBSession.flush()
        return dict(blog=blog,
                    user=blog.user,
                    title=title,
                    blog_nav_cat=get_navcategories(),
                    bcategories=bc)
Пример #27
0
def editdistrict(request):
    district_id = request.matchdict['district_id']
    lga_id = request.matchdict['lga_id']
    lga = LGA.get_by_id(lga_id)
    district =District.get_by_id(district_id)
    title = "Editing %s" %(district.name)
    form = Form(request, schema=StateSchema)
    if 'form_submitted' in request.POST and form.validate():
        s_string = form.data['name']
        district.name = s_string
        district.lga_id = lga_id
        DBSession.flush()
        request.session.flash("success; District updated")
        return HTTPFound(location=request.route_url('view_lga',lga_id=lga_id))
    action_url = request.route_url('edit_district',district_id=district_id,lga_id=lga_id)
    return dict(
        form=FormRenderer(form),
        district=district,
        lga=lga,
        title=title,
        action_url=action_url)
Пример #28
0
def editlga(request):
    lga_id = request.matchdict['lga_id']
    state_id = request.matchdict['state_id']
    state=State.get_by_id(state_id)
    lga =LGA.get_by_id(lga_id)
    title = "Editing %s" %(lga.name)
    form = Form(request, schema=StateSchema)
    if 'form_submitted' in request.POST and form.validate():
        s_string = form.data['name']
        lga.name = s_string
        lga.state_id = state_id
        DBSession.flush()
        request.session.flash("success; LGA updated")
        return HTTPFound(location=request.route_url('view_state', state_id=state_id))
    action_url = request.route_url('edit_lga',lga_id=lga_id, state_id=state_id)
    return dict(
        title=title,
        state=state,
        form=FormRenderer(form),
        lga=lga,
        action_url=action_url)
Пример #29
0
def email_passw(request):
    user = request.user
    form = Form(request, schema=ChangeEmailPassword, obj=user)
    if 'pass_submitted' in request.POST and form.validate():
        form.bind(user)
        DBSession.add(user)
        DBSession.flush()
        if request.is_xhr:
            html = """<div class="alert alert-success alert-dismissable col-xs-12">
                        <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                        Update Successful
                        </div>"""
            return Response(html)
        request.session.flash("success; Email and password saved")
        return HTTPFound(location=request.route_url('account'))
    if request.is_xhr:
        html = """<div class="alert alert-danger alert-dismissable col-xs-12">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                    Update not Successful {0}
                    </div>""".format(form.all_errors())
        return Response(html)
    request.session.flash("danger; Update not successful")
    return HTTPFound(location=request.route_url('account'))
Пример #30
0
def blog_category_add(request):
    title = 'Add blog category'
    parent_categories = DBSession.query(BlogCategory).filter(
        BlogCategory.parent == None).all()
    parent_categories = [(x.id, x.name) for x in parent_categories]
    form = Form(request, schema=BlogCategoryForm)
    if "form_submitted" in request.POST and form.validate():
        #add
        category = BlogCategory(name=form.data['name'],
                                description=form.data['description'],
                                parent=form.data['parent'])
        DBSession.add(category)
        DBSession.flush()
        request.session.flash('success; category saved')
        return HTTPFound(location=request.route_url("blog_category_list"))

    action_url = request.route_url('add_blog_category')
    return {
        'form': FormRenderer(form),
        'title': title,
        'action_url': action_url,
        'parent_categories': parent_categories
    }