diff farol/producttree.py @ 0:4a9f23230eba

Initial Release
author Benoît Allard <benoit.allard@greenbone.net>
date Wed, 24 Sep 2014 10:07:49 +0200
parents
children dbfe89e3c6fe
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/farol/producttree.py	Wed Sep 24 10:07:49 2014 +0200
@@ -0,0 +1,263 @@
+# -*- encoding: utf-8 -*-
+# Description:
+# Web stuff about the ProductTree
+#
+# Authors:
+# BenoƮt Allard <benoit.allard@greenbone.net>
+#
+# Copyright:
+# Copyright (C) 2014 Greenbone Networks GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""\
+Web-stuff about the producttree
+"""
+
+from functools import wraps
+
+from flask import Blueprint, render_template, redirect, url_for, abort, request, flash
+
+from farolluz.cvrf import (CVRFProductBranch, CVRFFullProductName,
+    CVRFRelationship, CVRFGroup)
+from .session import document_required, get_current
+
+producttree = Blueprint('producttree', __name__)
+
+def producttree_required(f):
+    @wraps(f)
+    def decorated_function(*args, **kwargs):
+        if get_current()._producttree is None:
+            flash('Operation invalid without producttree', 'warning')
+            return redirect(url_for('document'))
+        return f(*args, **kwargs)
+    return decorated_function
+
+@producttree.route('/create', methods=['POST'])
+@document_required
+def create():
+    get_current().createProductTree()
+    return redirect(url_for('document'))
+
+
+@producttree.route('/branch/<path:path>/edit', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def edit_branch(path):
+    path = [int(p) for p in path.split('/')]
+    cvrf = get_current()
+    ptree = cvrf._producttree
+    try:
+        branch = cvrf._producttree.getBranch(path)
+    except ValueError:
+        abort(404)
+    if request.method != 'POST':
+        branches = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getNotTerminalBranches(branch)]
+        return render_template('producttree/edit_branch.j2', branch=branch, branches=branches, types=branch.TYPES)
+
+    pbranch = ptree
+    if request.form['parent']:
+        pbranch = ptree.getBranch([int(p) for p in request.form['parent'].split('/')])
+
+    if pbranch is not branch.getParent():
+        # We have to 're-link' the element ...
+        # 1. unlink
+        branch.unlink()
+        # 2. set the new parent
+        branch._parentbranch = pbranch
+        # 3. add to the Tree (again)
+        ptree.addBranch(branch)
+
+    branch._type = request.form['type']
+    branch._name = request.form['name']
+    return redirect(url_for('document'))
+
+@producttree.route('/branch/add', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def add_branch():
+    cvrf = get_current()
+    ptree = cvrf._producttree
+    if request.method != 'POST':
+        branches = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getNotTerminalBranches()]
+        return render_template('producttree/edit_branch.j2', branch=CVRFProductBranch('', '', ptree), action='Add', branches=branches, types=CVRFProductBranch.TYPES)
+
+    pbranch = ptree
+    if request.form['parent']:
+        pbranch = ptree.getBranch([int(p) for p in request.form['parent'].split('/')])
+    branch = CVRFProductBranch(request.form['type'], request.form['name'], pbranch)
+    ptree.addBranch(branch)
+    return redirect(url_for('document'))
+
+@producttree.route('/product/<productid>')
+@document_required
+@producttree_required
+def view_product(productid):
+    cvrf = get_current()
+    try:
+        product = cvrf.getProductForID(productid)
+    except IndexError:
+        abort(404)
+    return render_template('producttree/view_product.j2', product=product, cvrf=cvrf)
+
+@producttree.route('/product/<productid>/edit', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def edit_product(productid):
+    cvrf = get_current()
+    ptree = cvrf._producttree
+    try:
+        product = cvrf.getProductForID(productid)
+    except KeyError:
+        abort(404)
+
+    if request.method != 'POST':
+        current_rel = ''
+        if product.isRelationship():
+            current_rel = str(ptree._relationships.index(product.getCurrentRelationship()))
+        leaves = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getOrphanedBranches(product)]
+        rels = [('', '')] + [(ptree.getNameOfRelationship(r), str(i)) for i, r in ptree.getOrphanedRelationships(product)]
+        return render_template('producttree/edit_product.j2', product=product, action='Update', orphaned_leaves=leaves, orphaned_relationships=rels, current_rel=current_rel)
+
+    if request.form['parent_branch'] and request.form['parent_relationship']:
+        flash('Cannot set a parent branch and parent relationship', 'danger')
+        return redirect(url_for('.edit_product', productid=productid))
+
+    oldp = product._parent
+    if request.form['parent_branch']:
+        pbranch = ptree.getBranch([int(p) for p in request.form['parent_branch'].split('/')])
+        if pbranch is not oldp:
+            # Gonna be funny, needs re-link
+            product.unlink()
+            product._parent = pbranch
+            ptree.addProduct(product)
+    elif request.form['parent_relationship']:
+        prel = ptree._relationships[int(request.form['parent_relationship'])]
+        if prel is not oldp:
+            product.unlink()
+            product._parent = prel
+            ptree.addProduct(product)
+    else:
+        if ptree is not oldp:
+            product.unlink()
+            product._parent = ptree
+            ptree.addProduct(product)
+
+    product._productid = request.form['productid']
+    product._name = request.form['name']
+    product._cpe = request.form['cpe'] or None
+    return redirect(url_for('document'))
+
+@producttree.route('/product/add', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def add_product():
+    cvrf = get_current()
+    ptree = cvrf._producttree
+
+    if request.method != 'POST':
+        product=CVRFFullProductName('', '', ptree)
+        leaves = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getOrphanedBranches()]
+        rels = [('', '')] + [(ptree.getNameOfRelationship(r), str(i)) for i, r in ptree.getOrphanedRelationships()]
+        return render_template('producttree/edit_product.j2', product=product, action='Add', orphaned_leaves=leaves, orphaned_relationships=rels, current_rel='')
+
+    if request.form['parent_branch'] and request.form['parent_relationship']:
+        flash('Cannot set a parent branch and parent relationship', 'danger')
+        return redirect(url_for('.edit_product', productid=productid))
+
+    parent = ptree
+    if request.form['parent_branch']:
+        parent = ptree.getBranch([int(p) for p in request.form['parent_branch'].split('/')])
+    elif request.form['parent_relationship']:
+        parent = ptree._relationships[int(request.form['parent_relationship'])]
+
+    product = CVRFFullProductName(request.form['productid'], request.form['name'], parent, request.form['cpe'] or None)
+    ptree.addProduct(product)
+    return redirect(url_for('document'))
+
+@producttree.route('/relationship/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def edit_relationship(index):
+    cvrf = get_current()
+    ptree = cvrf._producttree
+    try:
+        rel = ptree._relationships[index]
+    except IndexError:
+        abort(404)
+
+    if request.method != 'POST':
+        return render_template('producttree/edit_relationship.j2', productreference=rel._productreference, relationtype=rel._relationtype, relatestoproductreference=rel._relatestoproductreference, types=rel.TYPES)
+
+    rel._productreference = request.form['productreference']
+    rel._relationtype = request.form['relationtype']
+    rel._relatestoproductreference = request.form['relatestoproductreference']
+    return redirect(url_for('document'))
+
+@producttree.route('/relationship/add', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def add_relationship():
+    cvrf = get_current()
+    ptree = cvrf._producttree
+    if len(ptree._products) < 2:
+        flash('You need to have at least two products to create a relationship', 'warning')
+        return redirect(url_for('.add_product'))
+
+    if request.method != 'POST':
+        return render_template('producttree/edit_relationship.j2', action='Add', types=CVRFRelationship.TYPES)
+
+    prodid1 = request.form['productreference']
+    prodid2 = request.form['relatestoproductreference']
+
+    if prodid1 == prodid2:
+        flash('You cannot create a relationship with the same product twice', 'danger')
+        return redirect(url_for('.add_relationship'))
+
+    rel = CVRFRelationship(prodid1, request.form['relationtype'], prodid2)
+    ptree.addRelationship(rel)
+    return redirect(url_for('document'))
+
+@producttree.route('/group/<groupid>/edit', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def edit_group(groupid):
+    try:
+        group = get_current().getGroupForID(groupid)
+    except KeyError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('producttree/edit_group.j2', groupid=group._groupid, description=group._description, productids=group._productids)
+
+    group._groupid = request.form['groupid']
+    group.setDescription(request.form['description'] or None)
+    group._productids = []
+    for productid in request.form.getlist('products'):
+        group.addProductID(productid)
+    return redirect(url_for('document'))
+
+@producttree.route('/group/add', methods=['GET', 'POST'])
+@document_required
+@producttree_required
+def add_group():
+    if request.method != 'POST':
+        return render_template('producttree/edit_group.j2', action='Add')
+
+    group = CVRFGroup(request.form['groupid'])
+    group.setDescription(request.form['description'] or None)
+    for productid in request.form.getlist('products'):
+        group.addProductID(productid)
+    get_current()._producttree.addGroup(group)
+    return redirect(url_for('document'))

http://farol.wald.intevation.org