Merge "Add docs to about page"
This commit is contained in:
commit
92bf63aa9d
@ -204,6 +204,17 @@ performed to upgrade the database to the latest revision:
|
||||
|
||||
Now it should be some revision number other than `None`.
|
||||
|
||||
(Optional) Generate About Page Content
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The RefStack About page is populated with HTML templates generated from
|
||||
our RST documentation files. If you want this information displayed, then
|
||||
run the following command from the root of the project.
|
||||
|
||||
``./tools/convert-docs.py -o ./refstack-ui/app/components/about/templates ./doc/source/*.rst``
|
||||
|
||||
Ignore any unknown directive errors.
|
||||
|
||||
Start RefStack
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -41,7 +41,9 @@
|
||||
}).
|
||||
state('about', {
|
||||
url: '/about',
|
||||
templateUrl: '/components/about/about.html'
|
||||
templateUrl: '/components/about/about.html',
|
||||
controller: 'AboutController as ctrl'
|
||||
|
||||
}).
|
||||
state('guidelines', {
|
||||
url: '/guidelines',
|
||||
|
@ -226,3 +226,26 @@ a.glyphicon {
|
||||
.modal-body .row {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.about-sidebar {
|
||||
width: 20%;
|
||||
float: left;
|
||||
padding-right: 2px;
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
.about-content {
|
||||
width: 80%;
|
||||
float: left;
|
||||
padding-left: 5%;
|
||||
|
||||
}
|
||||
|
||||
.about-option {
|
||||
padding: 5px 5px 5px 10px;
|
||||
}
|
||||
|
||||
.about-active {
|
||||
background: #f2f2f2;
|
||||
border-left: 2px solid orange;
|
||||
}
|
@ -1,31 +1,13 @@
|
||||
<h1>RefStack Documentation</h1>
|
||||
|
||||
<p>RefStack is a source of tools for interoperability testing of OpenStack clouds.</p>
|
||||
<p>To learn more about RefStack, visit the links below.</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<a href="http://github.com/openstack/refstack/blob/master/README.rst#refstack"
|
||||
target="_blank"
|
||||
</a>
|
||||
<strong>About RefStack</strong>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://github.com/openstack/refstack/blob/master/doc/source/uploading_private_results.rst#how-to-upload-test-results-to-refstack"
|
||||
target="_blank"
|
||||
</a>
|
||||
<strong>How to upload test results to RefStack</strong>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://github.com/openstack/refstack/blob/master/doc/source/vendor_product.rst#vendor-and-product-management"
|
||||
target="_blank"
|
||||
</a>
|
||||
<strong>Vendor and product management</strong>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://github.com/openstack/refstack/blob/master/doc/source/test_result_management.rst#test-result-management"
|
||||
target="_blank"
|
||||
</a>
|
||||
<strong>Test result management</strong>
|
||||
</li>
|
||||
</ol>
|
||||
<hr>
|
||||
<div class="about-sidebar">
|
||||
<div ng-repeat="(key, data) in ctrl.options | arrayConverter | orderBy: 'order'">
|
||||
<a><div class="about-option"
|
||||
ng-click="ctrl.selectOption(data.id)"
|
||||
ng-class="{ 'about-active': ctrl.selected === data.id }">
|
||||
{{data.title}}
|
||||
</div></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="about-content">
|
||||
<div ng-include src="ctrl.template"></div>
|
||||
</div>
|
||||
|
85
refstack-ui/app/components/about/aboutController.js
Normal file
85
refstack-ui/app/components/about/aboutController.js
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('refstackApp')
|
||||
.controller('AboutController', AboutController);
|
||||
|
||||
AboutController.$inject = ['$location'];
|
||||
|
||||
/**
|
||||
* RefStack About Controller
|
||||
* This controller handles the about page and the multiple templates
|
||||
* associated to the page.
|
||||
*/
|
||||
function AboutController($location) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.selectOption = selectOption;
|
||||
ctrl.getHash = getHash;
|
||||
|
||||
ctrl.options = {
|
||||
'about' : {
|
||||
'title': 'About RefStack',
|
||||
'template': 'components/about/templates/README.html',
|
||||
'order': 1
|
||||
},
|
||||
'uploading-your-results': {
|
||||
'title': 'Uploading Your Results',
|
||||
'template': 'components/about/templates/' +
|
||||
'uploading_private_results.html',
|
||||
'order': 2
|
||||
},
|
||||
'managing-results': {
|
||||
'title': 'Managing Results',
|
||||
'template': 'components/about/templates/' +
|
||||
'test_result_management.html',
|
||||
'order': 3
|
||||
},
|
||||
'vendors-and-products': {
|
||||
'title': 'Vendors and Products',
|
||||
'template': 'components/about/templates/vendor_product.html',
|
||||
'order': 4
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an option key, mark it as selected and set the corresponding
|
||||
* template and URL hash.
|
||||
*/
|
||||
function selectOption(key) {
|
||||
ctrl.selected = key;
|
||||
ctrl.template = ctrl.options[key].template;
|
||||
$location.hash(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hash in the URL and select it if possible.
|
||||
*/
|
||||
function getHash() {
|
||||
var hash = $location.hash();
|
||||
if (hash && hash in ctrl.options) {
|
||||
ctrl.selectOption(hash);
|
||||
}
|
||||
else {
|
||||
ctrl.selectOption('about');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.getHash();
|
||||
}
|
||||
})();
|
@ -40,6 +40,7 @@
|
||||
<script src="shared/header/headerController.js"></script>
|
||||
<script src="shared/alerts/alertModalFactory.js"></script>
|
||||
<script src="shared/alerts/confirmModalFactory.js"></script>
|
||||
<script src="components/about/aboutController.js"></script>
|
||||
<script src="components/guidelines/guidelinesController.js"></script>
|
||||
<script src="components/results/resultsController.js"></script>
|
||||
<script src="components/results-report/resultsReportController.js"></script>
|
||||
|
@ -58,6 +58,49 @@ describe('Refstack controllers', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('AboutController', function () {
|
||||
var $location, ctrl;
|
||||
|
||||
beforeEach(inject(function ($controller, _$location_) {
|
||||
$location = _$location_;
|
||||
ctrl = $controller('AboutController', {});
|
||||
ctrl.options = {
|
||||
'about' : {
|
||||
'title': 'About RefStack',
|
||||
'template': 'about-template'
|
||||
},
|
||||
'option1' : {
|
||||
'title': 'Option One',
|
||||
'template': 'template-1'
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
||||
it('should have a function to select an option',
|
||||
function () {
|
||||
ctrl.selectOption('option1');
|
||||
expect(ctrl.selected).toBe('option1');
|
||||
expect(ctrl.template).toBe('template-1');
|
||||
expect($location.hash()).toBe('option1');
|
||||
});
|
||||
|
||||
it('should have a function to get the URL hash and select it',
|
||||
function () {
|
||||
// Test existing option.
|
||||
$location.url('/about#option1');
|
||||
ctrl.getHash();
|
||||
expect(ctrl.selected).toBe('option1');
|
||||
expect(ctrl.template).toBe('template-1');
|
||||
|
||||
// Test nonexistent option.
|
||||
$location.url('/about#foobar');
|
||||
ctrl.getHash();
|
||||
expect(ctrl.selected).toBe('about');
|
||||
expect(ctrl.template).toBe('about-template');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('GuidelinesController', function () {
|
||||
var ctrl;
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
SQLAlchemy>=0.8.3
|
||||
alembic==0.5.0
|
||||
beaker==1.6.5.post1
|
||||
beautifulsoup4
|
||||
cryptography>=1.0,!=1.3.0 # BSD/Apache-2.0
|
||||
docutils>=0.11
|
||||
oslo.config>=1.6.0 # Apache-2.0
|
||||
oslo.db>=1.4.1 # Apache-2.0
|
||||
oslo.log>=3.11.0
|
||||
|
75
tools/convert-docs.py
Executable file
75
tools/convert-docs.py
Executable file
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2017 IBM, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Convert RST files to basic HTML. The primary use case is to provide a way
|
||||
to display RefStack documentation on the RefStack website.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import os
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from docutils.core import publish_file
|
||||
|
||||
|
||||
def extract_body(html):
|
||||
"""Extract the content of the body tags of an HTML string."""
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
return ''.join(['%s' % str(a) for a in soup.body.contents])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Convert RST files to basic HTML template files.'
|
||||
)
|
||||
parser.add_argument('files',
|
||||
metavar='file',
|
||||
nargs='+',
|
||||
help='RST file(s) to be converted to HTML templates.')
|
||||
parser.add_argument('-o', '--output_dir',
|
||||
required=False,
|
||||
help='The directory where template files should be '
|
||||
'output to. Defaults to the current directory.')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.output_dir:
|
||||
output_dir = args.output_dir
|
||||
# If the output directory doesn't exist, create it.
|
||||
if not os.path.exists(output_dir):
|
||||
try:
|
||||
os.makedirs(output_dir)
|
||||
except OSError:
|
||||
if not os.path.isdir(output_dir):
|
||||
raise
|
||||
else:
|
||||
output_dir = os.getcwd()
|
||||
|
||||
for path in args.files:
|
||||
for file in glob.glob(path):
|
||||
base_file = os.path.splitext(os.path.basename(file))[0]
|
||||
|
||||
# Calling publish_file will also print to stdout. Destination path
|
||||
# is set to /dev/null to suppress this.
|
||||
html = publish_file(source_path=file,
|
||||
destination_path='/dev/null',
|
||||
writer_name='html',)
|
||||
body = extract_body(html)
|
||||
|
||||
output_file = os.path.join(output_dir, base_file + ".html")
|
||||
with open(output_file, "w") as template_file:
|
||||
template_file.write(body)
|
Loading…
Reference in New Issue
Block a user