Hi Dan,
I thought instead of describing what I am doing, I would just show you the patch so you can point at the problem quicker.
As I mentioned before, I decided to just randomly grab a page like CSV_import_export and try to convert it to flask. I started by mimicing reserve_workflow thinking it had a similar display and POST frontend.
However, I found out, I can get the page to render the title but that is about it.
Even on the reserve_workflow page, I don't get the pretty Distro and other forms (without my changes applied too).
So I can't tell if my patch below is technically wrong (I am sure it is missing lots of pieces) or my devel env is not quite configured correctly (because reserve_workflow doesn't quite work either).
Thoughts? Help?
Cheers, Don
diff --git a/Server/assets/csv-export.js b/Server/assets/csv-export.js new file mode 100644 index 0000000..aed9db9 --- /dev/null +++ b/Server/assets/csv-export.js @@ -0,0 +1,35 @@ + +// 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. + +;(function () { + +var CSVExportSelection = Backbone.Model.extend({ +}); + +window.CSVExport = Backbone.View.extend({ + template: JST['csv-export'], + events: { + 'submit form': 'submit', + }, + initialize: function (options) { + this.csv_types = options.options['csv_types'] + this.render(); + }, + render: function () { + this.$el.html(this.template(this)); + }, + submit: function (evt) { + evt.preventDefault(); + var xhr = $.ajax({ + url: 'action_export', + type: 'POST', + data: this.selection.attributes, + traditional: true, + }); + }, +}); + +})(); diff --git a/Server/assets/jst/csv-export.html b/Server/assets/jst/csv-export.html new file mode 100644 index 0000000..eec875e --- /dev/null +++ b/Server/assets/jst/csv-export.html @@ -0,0 +1,19 @@ +<form class="form-horizontal"> + <fieldset> + <div class="control-group"> + <label class="control-label">CSV TYPE</label> + <div class="controls"> + <% _.each(csv_types, function (csv) { %> + <label class="radio"> + <input type="radio" name="csv_type" value="<%- csv.toLowerCase() %>" + <% if (csv == 'System' ) { %>checked<% } %> + /> + <%- csv %> + </label> + </div> + </div> + <div class="form-actions"> + <button class="btn btn-primary" type="submit">Export CSV</button> + </div> + </fieldset> +</form> diff --git a/Server/bkr/server/CSV_import_export.py b/Server/bkr/server/CSV_import_export.py index 41fcb26..94bb00f 100644 --- a/Server/bkr/server/CSV_import_export.py +++ b/Server/bkr/server/CSV_import_export.py @@ -10,7 +10,11 @@ from bkr.server import identity from bkr.server.xmlrpccontroller import RPCRoot from tempfile import NamedTemporaryFile -from cherrypy.lib.cptools import serve_file +#from cherrypy.lib.cptools import serve_file +from flask import send_file, request +from bkr.server.flask_util import render_tg_template + +from bkr.server.app import app from bkr.server.model import (System, SystemType, Activity, SystemActivity, User, Group, LabController, LabInfo, OSMajor, OSVersion, @@ -70,6 +74,64 @@ def line_num(self): def fieldnames(self): return self.reader.fieldnames
+# For XMLRPC methods in this class. +exposed = False + +export_help_text = XML(u'<span>Refer to the <a href="http://beaker-project.org/docs/' + 'admin-guide/interface.html#export" target="_blank">' + 'documentation</a> to learn more about the exported data.</span>').expand() +import_help_text = XML(u'<span>Refer to the <a href="http://beaker-project.org/docs/' + 'admin-guide/interface.html#import" target="_blank">' + 'documentation</a> for details about the supported CSV format.</span>').expand() + +upload = widgets.FileField(name='csv_file', label='Import CSV', \ + help_text = import_help_text) +download = RadioButtonList(name='csv_type', label='CSV Type', + options=[('system', 'Systems'), + ('system_id', 'Systems (for modification)'), + ('labinfo', 'System LabInfo'), + ('power', 'System Power'), + ('exclude', 'System Excluded Families'), + ('install', 'System Install Options'), + ('keyvalue', 'System Key/Values'), + ('system_pool', 'System Pools'), + ('user_group', 'User Groups')], + default='system', + help_text = export_help_text) +exportform = HorizontalForm( + 'export', + action = 'export data', + submit_text = _(u'Export CSV'), +) + +@app.route('/csv', methods=['GET']) +@identity.require(identity.not_anonymous()) +def index(): + options = {} + options['csv_types'] = ('system', 'system_id', 'labinfo', 'power', + 'exclude', 'install', 'keyvalue', 'system_pool', + 'user_group') + #return render_template('assets.jst.csv_export.html', options=options) + return render_tg_template('bkr.server.templates.csv_export', { + 'title' : u'CSV Export Don', + 'options' : options + }) + +@app.route('/csv/action_export', methods=['POST']) +@identity.require(identity.not_anonymous()) +def action_export(): + csv_type = request.form.get('csv_type') + logger.debug("DON: request: %s" % csv_type()) + + file = NamedTemporaryFile() + log = self.to_csv(file, csv_type) + file.seek(0) + + logger.debug('DON CSV export with send_file type: %s', csv_type) + return send_file(file.name, mimetype="text/csv", + as_attachment=True, + attachment_filename="%s.csv" % csv_type) + class CSV(RPCRoot): # For XMLRPC methods in this class. exposed = False @@ -139,6 +201,7 @@ def action_export(self, csv_type, *args, **kw): log = self.to_csv(file, csv_type) file.seek(0)
+ logger.debug('DON CSV export with send_file type: %s', csv_type) return serve_file(file.name, contentType="text/csv", disposition="attachment", name="%s.csv" % csv_type) diff --git a/Server/bkr/server/assets.py b/Server/bkr/server/assets.py index 0c5a117..71747f4 100644 --- a/Server/bkr/server/assets.py +++ b/Server/bkr/server/assets.py @@ -90,6 +90,7 @@ def _create_env(source_dir, output_dir, **kwargs): 'pools.js', 'query-builder.js', 'reserve-workflow.js', + 'csv-export.js', 'installation-model.js', 'task-library-model.js', 'scheduler-model.js', diff --git a/Server/bkr/server/controllers.py b/Server/bkr/server/controllers.py index cece8db..936cdc2 100644 --- a/Server/bkr/server/controllers.py +++ b/Server/bkr/server/controllers.py @@ -146,7 +146,7 @@ class Root(RPCRoot): users = Users() arches = Arches() auth = Auth() - csv = CSV() + #csv = CSV() jobs = Jobs() recipesets = RecipeSets() recipes = Recipes() diff --git a/Server/bkr/server/templates/csv_export.kid b/Server/bkr/server/templates/csv_export.kid new file mode 100644 index 0000000..848cfff --- /dev/null +++ b/Server/bkr/server/templates/csv_export.kid @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'master.kid'"> +<head> +<title>$title</title> +</head> +<body> +<div class="page-header"> + <h1>$title</h1> +</div> +<div class="csv_export"></div> +<script type="text/javascript"> +var csvexport = new CSVExport( +$(function () { + new CSVExport({ + el: '.csv_export', + options: ${tg.to_json(options)}, + }); +}); +</script> +</body> +</html>