Commit 7df213b8 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Merge branch 'lhcbfrance2'

parents 181ccf9e 30fd6a65
*~
*.pdf
.project
.pydevproject
*.pyc
.settings/
cache/
cron/
databases
databases*/
*build*
*jsduck*
*epydoc*
*sphinx*
errors/
private/
*plugin_ace*
*plugin_dbui*
*plugin_extjs*
*plugin_mathjax*
sessions/
static/*-min.js
uploads/
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
NAME
buildVersion -- helper script to build and tag a track_lhcbfrance version
SYNOPSIS
buildVersion [options] version
DESCRIPTION
Helper script to build a version of the track_lhcbfrance.
The version identifier should contains alphanumeric characters
including ".", "-" and "_".
Push version identifier in the javascript library.
Push version number in the CHANGELOG.
Build debug and minified version of the javascript library.
Commit the new version in git and tag it
Build the web2py plugin file
EXAMPLES
> buildVersion -h
> buildVersion -g
> buildVersion -g 0.8.2
> buildVersion -a 0.8.3
AUTHOR
R. Le Gac, renaud.legac@free.fr
Copyright (c) 2012-2014 R. Le Gac
"""
import datetime
import optparse
import os
import re
import subprocess
import sys
import tempfile
import urllib
# constants
APP = os.path.basename(os.getcwd())
CHANGELOG = 'static/CHANGELOG'
DBUIJSSRC = 'static/plugin_dbui/src'
EXTJSSRC = 'static/plugin_extjs/src'
JSDOC = 'static/docs/jsduck'
JSLIBMIN = 'static/%s-min.js' % APP
JSLIBSRC = 'static/src'
LATEXDOC = 'static/docs/latex'
PYDOC = 'static/docs/epydoc'
PDFDOC = 'static/docs/pdf'
SPHINXDOC = 'static/docs/sphinx'
SPHINXSRC = 'documentations/userguide/'
NOW = datetime.datetime.now()
# basic commands
JSDUCK = os.path.expandvars("$HOME/bin/jsduck")
GIT = '/usr/bin/git'
PDFLATEX = '/usr/bin/pdflatex'
SENCHA = os.path.expandvars("$HOME/bin/sencha")
SPHINX = '/usr/bin/sphinx-build'
# message
MSG_VERSION = 'Enter the new version: '
def compile():
"""compile the javascript code and generate the minified version
of the application library.
The compiler verify that the code complied with the class model
and order the file in the proper way.
The minified library can be build in several ways, including
the Ext JS class required by the applications. In the
current version, the library contains only the application classes and
the Ext JS ones have to be loaded separately.
Several compressor can be used yui, closure compiler, ....
In the current version, the default yui compressor is used?
This operation relies on the Sencha Cmd:
http://www.sencha.com/products/sencha-cmd/download
The details documantation can be found:
http://docs.sencha.com/extjs/4.2.2/#!/guide/command
"""
if not os.path.exists(SENCHA):
print '\n\tThe application sencha is missing !'
print '\tSee: http://www.sencha.com/products/sencha-cmd/download'
print '\tSkip this step.\n'
return
# clean previous build
if os.path.exists(JSLIBMIN):
os.remove(JSLIBMIN)
# Minified version of the javascript library
print '\nMinified version of the javascript library', JSLIBMIN
cwd = os.getcwd()
cmd = ["sencha", "-sdk", os.path.join(cwd, EXTJSSRC),
"compile", "-classpath", os.path.join(cwd, DBUIJSSRC),
"-classpath", os.path.join(cwd, JSLIBSRC),
"exclude", "--namespace", "Ext", "--namespace", "App",
"and", "concat", "--yui", os.path.join(cwd, JSLIBMIN)]
subprocess.call(cmd)
def epydoc():
"""Generate the epydoc documentation
The HTML files are located in static/plugin_dbui/docs/epydoc
"""
if not os.path.exists(GIT):
print '\n\tThe application epydoc is missing !'
print '\tSkip this step.\n'
return
# create the directory
if not os.path.exists(PYDOC):
os.makedirs(PYDOC)
# clean the directory
cmd = ["rm", "-rf", PYDOC]
subprocess.call(cmd)
# run epydoc
cmd = ["epydoc", "--docformat", "epytext",
"--html",
"--name", APP,
"-o", PYDOC,
"--parse-only",
"-v",
"modules/*.py"]
subprocess.call(cmd)
print "HTML documentation in", PYDOC
def get_version():
"""Return the identifier of the current version.
"""
fi = tempfile.TemporaryFile()
subprocess.call(["git", "describe", "--tags"], stdout=fi)
fi.seek(0)
return fi.read()
def git(version):
"""Commit and tag the current release.
"""
if not os.path.exists(GIT):
print '\n\tThe application git is missing !'
print '\tSkip this step.\n'
return
# check tag in git
fi = tempfile.TemporaryFile()
subprocess.call(["git", "tag"], stdout=fi)
fi.seek(0)
if version in fi.read():
print "\n\ttag %s already exit in git" % version
sys.exit(1)
# release message
m = "Release version %s" % version
# Commit the new release in git an tag it
print 'git add', CHANGELOG
cmd = ["git", "add", CHANGELOG]
subprocess.call(cmd)
print 'git commit'
cmd = ["git", "commit", "-m", m]
subprocess.call(cmd)
# annotated tag
print 'git tag', version
cmd = ["git", "tag", "-a", version, "-m", m]
subprocess.call(cmd)
def jsduck():
"""Generate the JavaScript documentation.
The HTML files are located in static/docs/jsduck
"""
if not os.path.exists(JSDUCK):
print '\n\tThe application jsduck is missing !'
print '\tSkip this step.\n'
return
# create the directory
if not os.path.exists(JSDOC):
os.makedirs(JSDOC)
# clean the directory
cmd = ["rm", "-rf", JSDOC]
subprocess.call(cmd)
# run JsDuck
cmd = ["jsduck", EXTJSSRC, DBUIJSSRC, JSLIBSRC, \
"--output", JSDOC, \
"--title", "%s %s" % (APP, get_version()), \
"--warnings=-all:"+EXTJSSRC]
subprocess.call(cmd)
print "JavaScript documentation in", JSDOC
def set_version(version):
"""Set version identifier in CHANGELOG
"""
# look for a pattern HEAD in the CHANGELOG
# split the the string in 2 parts (pre HEAD, post HEAD)
print 'Set version in', CHANGELOG
s = open(CHANGELOG, 'rb').read()
m = re.match("(.+HEAD\n)(.*)", s, re.DOTALL)
if m == None:
print '\n\tNo HEAD tag in the CHANGELOG!\n'
rep = raw_input('\tDo you want to continue [n]?')
if rep not in ('y', 'yes'):
sys.exit(1)
# update the version and edit the CHANGELOG
s = '%s\n%s (%s)\n%s' % (m.group(1), version, NOW.strftime('%b %Y'), m.group(2))
fi = open(CHANGELOG, 'wb')
fi.write(s)
fi.close()
subprocess.call(["vim", CHANGELOG])
# cleaning
fn = "%s~" % CHANGELOG
if os.path.exists(fn):
os.remove(fn)
def sphinx():
"""Generate the Sphinx documentation.
"""
if not os.path.exists(SPHINX):
print '\n\tThe application sphinx is missing !'
print '\tSkip this step.\n'
return
if not os.path.exists(SPHINXSRC):
return
# generate the HTML version
cmd = [SPHINX, "-b", "html", SPHINXSRC, SPHINXDOC]
subprocess.call(cmd)
print "\nSphinx HTML documentation in", SPHINXDOC,"\n"
# generate the PDF version
if not os.path.exists(PDFLATEX):
print '\n\tThe application pdflatex is missing !'
print '\tSkip this step.\n'
return
rep = raw_input("Produce the sphinx pdf (y/N) [n]:")
if not rep.lower().startswith("y"):
return
if not os.path.exists(PDFDOC):
os.makedirs(PDFDOC)
# generate the latex
cmd = [SPHINX, "-b", "latex", SPHINXSRC, LATEXDOC]
subprocess.call(cmd)
# find the tex file
cwd = os.getcwd()
os.chdir(LATEXDOC)
li = [el for el in os.listdir('.') if el.endswith('.tex')]
fn = (li[0] if len(li) == 1 else None)
if fn:
pdf = fn.replace('.tex', '.pdf')
cmd = [PDFLATEX, "-output-directory", "../pdf", fn]
# run pdflatex twice to get reference right
subprocess.call(cmd)
subprocess.call(cmd)
# clean the pdf directory
os.chdir(cwd)
for el in os.listdir(PDFDOC):
if el.endswith('.pdf'):
continue
os.remove(os.path.join(PDFDOC, el))
cmd = ["rm", "-rf", LATEXDOC]
subprocess.call(cmd)
print "\nSphinx PDF documentation in", PDFDOC,"\n"
if __name__ == '__main__':
ops = optparse.OptionParser()
ops.add_option("-a", "--all",
action="store_true",
dest= "all",
help= "run all steps.")
ops.add_option("-c", "--compile",
action="store_true",
dest="compile",
help="compile the javascript library using sencha command.")
ops.add_option("-e", "--epydoc",
action="store_true",
dest= "epydoc",
help= "generate the epydoc documentation.")
ops.add_option("-g", "--git",
action="store_true",
dest= "git",
help= "commit and tag the current release.")
ops.add_option("-j", "--jsduck",
action="store_true",
dest= "jsduck",
help= "generate the JavaScript documentation.")
ops.add_option("-r", "--release",
action="store_true",
dest= "get",
help= "get the tag of the current release and exit.")
ops.add_option("-s", "--sphinx",
action="store_true",
dest= "sphinx",
help= "generate the sphinx documentation.")
ops.add_option("-v", "--version",
action="store_true",
dest= "version",
help= "set the version.")
ops.set_defaults(all=False,
compile=False,
epydoc=False,
get=False,
git=False,
jsduck=False,
sphinx=False,
version=False)
(opt, args) = ops.parse_args()
print '\nStart buildVersion'
# standalone action
if opt.get:
version = get_version()
print "\nThe version of the current release is %s\n" % version
if opt.version:
version = (args[0] if args else raw_input(MSG_VERSION))
set_version(version)
if opt.git:
git(version)
if opt.epydoc:
epydoc()
if opt.jsduck:
jsduck()
if opt.sphinx:
sphinx()
if opt.compile:
compile()
# run all steps
if opt.all:
version = get_version()
print "\nThe version of the current release is %s\n" % version
version = (args[0] if args else raw_input(MSG_VERSION))
set_version(version)
git(version)
epydoc()
jsduck()
sphinx()
compile()
print 'Exit buidVersion\n'
sys.exit(0)
\ No newline at end of file
""" Controllers """
import os
def about():
fn = os.path.join("applications",
request.application,
"static",
"ABOUT.html")
return open(fn, 'rb').read()
def documentations():
di = {}
"""Main controller to give access to the documentation.
di["epydoc_dbui"] = URL('static', 'plugin_dbui/docs/epydoc/index.html')
di["epydoc_application"] = URL('static', 'docs/epydoc/index.html')
di["png_db"] = URL('static', 'docs/database.png')
return di
"""
return dict()
@auth.requires_login()
# @auth.requires_login()
def index():
"""Main Controller to run the application launching the plugin dbui.
......@@ -40,7 +26,14 @@ def index():
else:
session.role = ADMIN
return LOAD('plugin_dbui', 'index', vars=request.vars)
if 'debug' in request.vars:
del request.vars['debug']
url = URL('plugin_dbui', 'debug', args=request.args, vars=request.vars)
else:
url = URL('plugin_dbui', 'index', args=request.args, vars=request.vars)
return redirect(url)
def user():
......@@ -57,11 +50,3 @@ def user():
to decorate functions that need access control
"""
return dict(form=auth())
def versions():
""" expose http://.../default/versions and show software versions.
"""
import plugin_dbui
return plugin_dbui.get_versions()
""" List controllers
"""
from reporting_tools import (MySelector,
Base,
Person)
BASE_VIEW = 'report.%s'
def hardware():
""" Active hardware for a given period of time, given team, ...
"""
# instantiate the selector
selector = MySelector(virtdb.hardware_selector)
iframe = selector.download()
if iframe:
return iframe
# add constraint to select only hardware item
selector.append_query(db.events.category == 'hardware')
# define virtual field to compute time data
# to be added in the report via extra columns
db.history.duration = Field.Virtual(Base(selector).duration)
# retrieve the records
orderfields = (db.people.last_name, db.history.start_date)
rows = selector.select_active_items(db.history, orderby=orderfields)
# build the header and publish
header = '%s %s' % (T('List of hardware'), selector.header(db))
response.view = BASE_VIEW % request.extension
return dict(footer='', header=header, rows=rows)
def list():
"""list of objects followed by the history table.
"""
# instantiate the selector
selector = MySelector(virtdb.list_selector,
exclude_fields=('category',
'period_start',
'period_end',
'year'))
iframe = selector.download()
if iframe:
return iframe
# handle the category constraint
if selector.category:
selector.append_query(db.people_categories.category == selector.category)
# define virtual field to compute time data
# to be added in the report via extra columns
db.history.duration = Field.Virtual(Person(selector).duration)
# retrieve the records
orderfields=(db.people.last_name, db.history.start_date)
rows = selector.select_active_items(db.history, orderby=orderfields)
# build the header and publish
header = '%s %s' % (T('List'), selector.header(db))
response.view = BASE_VIEW % request.extension
return dict(footer='', header=header, rows=rows)
def people():
"""Active people for a given period of time, given team, ...
"""
# instantiate the selector
selector = MySelector(virtdb.people_selector,
exclude_fields=('category',
'year',
'period_start',
'period_end'))
iframe = selector.download()
if iframe:
return iframe
# add constraint to avoid event (diploma, distinction,...)
selector.append_query(db.history.id_events == undef_id)
# add constraints to select category of people
if selector.category:
selector.append_query(db.people_categories.category == selector.category)
# define virtual field to compute time data
# to be added in the report via extra columns
tool = Person(selector)
db.history.time_coverage = Field.Virtual(tool.coverage)
db.people.age = Field.Virtual(tool.age)
# retrieve the record
orderfields = (db.people_categories.category, db.people.last_name)
rows = selector.select_active_items(db.history, orderby=orderfields)
# get the header and publish
header = '%s %s' % (T('List of people '), selector.header(db))
response.view = BASE_VIEW % request.extension
return dict(footer='', header=header, rows=rows)
def responsibilities():
"""Active responsibilities for a person, a given period of time, ...
"""
# instantiate the selector
selector = MySelector(virtdb.responsibilities_selector)
iframe = selector.download()
if iframe:
return iframe
# add constraint to select only hardware item
selector.append_query(db.events.category == 'responsabilité')
# order the records
orderfields = (db.organization_levels.level,
db.people.last_name,
db.history.start_date)