Commit 9af2ef16 authored by François Grisez's avatar François Grisez

Reworking of Flexisip reference doc generation for XWiki

* Remove generation for DokuWiki
* Merge the code inside bash script into xw.py
* Change the destination of the docs in order to have
  a documentation for each release of Felexisip in addition
  to the documentation of the development version.
parent 8955f148
Pipeline #7327 failed with stages
in 21 minutes and 30 seconds
import sys
import argparse
from dokuwiki import DokuWiki, DokuWikiError
import ConfigParser, os
default_host= 'https://linphone.org/dokuwiki'
# read from a configuration file for user/pass/host. This allows for out-of-cli specification of these parameters.
config_file = '~/.flexiwiki.doku.cfg'
config_section = 'main'
config_password = None
config_user = None
config_host = None
try:
config = ConfigParser.ConfigParser()
config.read( os.path.expanduser(config_file) )
config_password = config.get(config_section, 'password')
config_user = config.get(config_section, 'username')
config_host = config.get(config_section, 'host')
except Exception, e:
pass
# parse cli arguments
parser = argparse.ArgumentParser(description='Send the Flexisip documentation to the Wiki. All options passed override the config file.', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('modulename', help='the module name')
parser.add_argument('docfile', help='the module documentation file', type=argparse.FileType('r'))
parser.add_argument('--host', default=default_host, help='the host to which we should send the documentation')
parser.add_argument('-p', '--password', default='', help='the password to authenticate to the server', dest='config_password')
parser.add_argument('-u', '--user', default='buildbot', help='the user to authenticate to the server', dest='config_user')
parser.add_argument('-m', '--message', default='', help='summary of the modifications')
args = parser.parse_args()
# summary should be a full string instead of an array of words
args.message = ' '.join(args.message)
args.modulename = 'flexisip:module:' + str.lower(args.modulename)
# require a password for XMLRPC
if args.config_password not in [None, '']:
config_password = args.config_password
if args.config_user not in [None, '']:
config_user = args.config_user
if args.host not in [None, '']:
config_host = args.host
if config_password is None or config_password is '':
print "Please define a password using " + config_file + " or using the --password option"
print "Example of " + config_file +" :"
print "["+config_section+"]"
print "password=toto"
print "username=titi"
print "host=example.com"
sys.exit(1)
print 'Updating ' + args.modulename + '...',
# use config file or provided host
if config_host is None or args.host is not default_host:
config_host = args.host
try:
wiki = DokuWiki(config_host, config_user, config_password)
except DokuWikiError as err:
print ' error.'
print str(err)
sys.exit(1)
meta = {'sum':args.message.join(' '), 'minor':True}
page_content = args.docfile.read()
try:
wiki.pages.set(args.modulename, page_content, **meta )
except Exception as e:
print ' error.'
sys.exit(1)
print ' done.'
\ No newline at end of file
#!/usr/bin/env python
import sys
import argparse
import mwclient
import logging
import ConfigParser, os
log = logging.getLogger('mwclient.client')
log.addHandler(logging.StreamHandler())
log.setLevel(logging.DEBUG)
default_host= 'www.linphone.org/wiki'
# read from a configuration file for user/pass/host. This allows for out-of-cli specification of these parameters.
config_file = '~/.flexiwiki.media.cfg'
config_section = 'main'
config_password = None
config_user = None
config_host = None
try:
config = ConfigParser.ConfigParser()
config.read( os.path.expanduser( config_file ) )
config_password = config.get(config_section, 'password')
config_user = config.get(config_section, 'username')
config_host = config.get(config_section, 'host')
except Exception, e:
log.error("Error opening config file: " + str(e))
pass
# parse cli arguments
parser = argparse.ArgumentParser(description='Send the Flexisip documentation to the Wiki. All options passed override the config file.', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('modulename', help='the module name')
parser.add_argument('docfile', help='the module documentation file', type=argparse.FileType('r'))
parser.add_argument('--host', default=default_host, help='the host to which we should send the documentation')
parser.add_argument('-p', '--password', default='', help='the password to authenticate to the server', dest='config_password')
parser.add_argument('-u', '--user', default='buildbot', help='the user to authenticate to the server', dest='config_user')
parser.add_argument('-m', '--message', default='', help='summary of the modifications')
args = parser.parse_args()
# summary should be a full string instead of an array of words
args.message = ' '.join(args.message)
args.modulename = 'flexisip:module:' + str.lower(args.modulename)
# require a password for XMLRPC
if args.config_password not in [None, '']:
config_password = args.config_password
if args.config_user not in [None, '']:
config_user = args.config_user
if args.host not in [None, '']:
config_host = args.host
if config_password is None or config_password is '':
print "Please define a password using " + config_file + " or using the --password option"
print "Example of " + config_file +" :"
print "["+config_section+"]"
print "password=toto"
print "username=titi"
print "host=example.com"
sys.exit(1)
log.info( 'Updating ' + args.modulename + '...' )
# use config file or provided host
if config_host is None or args.host is not default_host:
config_host = args.host
try:
useragent = 'FlexiBot, based on mwclient'
site = mwclient.Site(('https',config_host), clients_useragent=useragent, path='/')
site.login(config_user, config_password)
except Exception as err:
log.error('Site error.')
log.error(str(err))
sys.exit(1)
meta = {'sum':args.message.join(' '), 'minor':True}
page_content = args.docfile.read()
try:
page = site.Pages[args.modulename]
page.save(page_content, summary = args.message.join(' '))
except Exception as e:
log.error('Page error.')
log.error(str(e))
sys.exit(1)
print ' done.'
\ No newline at end of file
#!/bin/bash
FLEXISIP=$(find $(dirname $0)/../OUTPUT -name flexisip -type f)
# you can give a message by passing it as the first argument (./update_wikidoc "my update message")
if [ "$#" -ge 1 ]; then
message="-m \"$1\""
else
message=""
fi
function flexi_doc_to_file {
_module=$1
_format=$2
_file=$3
$FLEXISIP --dump-format $_format --dump-default $_module > $_file
}
function upload_to_wiki {
_modules=$1
_format=$2
_script=$3
echo "Sending module documentation for $_format"
for module in $_modules
do
modulename=`echo $module | sed 's/module:://g'`
echo "Doc for module $module -> $modulename.$_format.txt"
flexi_doc_to_file $module $_format "$modulename.$_format.txt"
python $_script $modulename $modulename.$_format.txt $message
rm $modulename.$_format.txt
done
}
# special case for the 'global' namespace, which is not technically a module
flexi_doc_to_file "global" "doku" "global.doku.txt"
flexi_doc_to_file "global" "media" "global.wiki.txt"
python dk.py "global" "global.doku.txt" $message
python mw.py "global" "global.wiki.txt" $message
rm "global.doku.txt" "global.wiki.txt"
modules=`$FLEXISIP --list-modules`
# upload for DokuWiki
upload_to_wiki "${modules[@]}" "doku" "dk.py"
#upload for MediaWiki
upload_to_wiki "${modules[@]}" "media" "mw.py"
#!/bin/bash
FLEXISIP=$(find $(dirname $0)/../OUTPUT -name flexisip -type f)
function upload_to_wiki {
_modules=$1
_format=$2
_script=$3
echo "Sending module documentation for $_format"
for module in $_modules
do
modulename=`echo $module | sed 's/module:://g'`
echo "Doc for module $module -> $modulename.$_format.txt"
python $_script $modulename $modulename.$_format.txt
rm $modulename.$_format.txt
done
}
modules=`$FLEXISIP --list-modules`
# upload for DokuWiki
#python "xw.py" "global" "global.xwiki.txt"
upload_to_wiki "global" "xwiki" "xw.py"
upload_to_wiki "${modules[@]}" "xwiki" "xw.py"
#!/usr/bin/env python
#!/bin/python
import sys
import argparse
import base64
import configparser
import os
import subprocess
import ConfigParser
import re
import subprocess
import sys
import urllib.request
class FlexisipProxy:
def __init__(self, binaryPath):
self.path = binaryPath
@property
def module_list(self):
p = subprocess.Popen([self.path, '--list-modules'], stdout=subprocess.PIPE , stderr=subprocess.PIPE)
out, err = p.communicate()
return str(out, encoding='utf-8').rstrip('\n').split('\n')
def dump_section_doc(self, moduleName):
p = subprocess.Popen([self.path, '--dump-format', 'xwiki', '--dump-default', moduleName], stdout=subprocess.PIPE , stderr=subprocess.PIPE)
out, err = p.communicate()
out = str(out, encoding='utf-8')
# replace all the -- in the doc with {{{--}}} to escape xwiki autoformatting -- into striken
return re.sub("--", "{{{--}}}", out)
def get_version(self):
p = subprocess.Popen([self.path, '-v'], stdout=subprocess.PIPE , stderr=subprocess.PIPE)
out, err = p.communicate()
out = str(out, encoding='utf-8')
m = re.search('version: (\S+) \(git: (\S+)\)', out)
if m is None:
raise RuntimeError("unexpected output of 'flexisip -v': [{0}]".format(out))
return m.group(1), m.group(2)
class XWikiProxy:
class Credential:
def __init__(self, user, password):
self.user = user
self.password = password
def to_base64(self):
return base64.b64encode(bytes('{0}:{1}'.format(self.user, self.password), encoding='utf-8'))
def __init__(self, host, wikiname, credentials=None):
self.host = host
self.wikiname = wikiname
self.credentials = credentials
def update_page(self, path, content):
uri = self._forge_page_uri(path)
request = self._forge_http_request(uri, 'PUT', content)
response = urllib.request.urlopen(request)
if response.status not in (201, 202):
raise RuntimeError('page creation or modification has failed' if response.status == 304 \
else 'unexpected status code ({0})'.format(response.status))
def _forge_page_uri(self, path):
uri = self._forge_root_uri()
scopepath = os.path.dirname(path)
scopepath = scopepath.split('/')
if scopepath[0] == '':
del scopepath[0]
for scopename in scopepath:
uri += ('/spaces/' + self._escape(scopename))
pagename = os.path.basename(path)
uri += ('/pages/' + self._escape(pagename))
return uri
def _escape(self, string):
return string.translate({0x20 : '%20'})
def _forge_root_uri(self):
return 'http://' + self.host + XWikiProxy._apipath + '/wikis/' + self.wikiname
_apipath = '/xwiki/rest'
def _forge_http_request(self, uri, method, body):
headers = { 'Content-Type': 'text/plain' }
if self.credentials is not None:
headers['Authorization'] = ('Basic ' + str(self.credentials.to_base64(), encoding='ascii'))
return urllib.request.Request(uri, data=bytes(body, encoding='utf-8'), headers=headers, method=method)
class Settings:
def __init__(self):
self.section_name = 'main'
self.host = ''
self.wikiname = ''
self.user = ''
self.password = ''
def load(self, filename):
config = configparser.ConfigParser()
config.read(config_file)
self.host = config.get(self.section_name, 'host', fallback=self.host)
self.wikiname = config.get(self.section_name, 'wiki', fallback=self.wikiname)
self.user = config.get(self.section_name, 'username')
self.password = config.get(self.section_name, 'password')
def dump_example(self):
return """[{section}]
host=example.com
wiki=public
username=titi
password=toto""".format(self.section_name)
def module_name_to_page_name(module_name):
return module_name[len('module::'):] if module_name.startswith('module::') else module_name
default_host="http://wiki.linphone.org:8080/xwiki/rest/wikis/public/spaces/Flexisip/spaces/Modules%20Reference%20Guide/pages/"
# read from a configuration file for user/pass/host. This allows for out-of-cli specification of these parameters.
config_file = '~/.flexiwiki.x.cfg'
config_section = 'main'
config_password = None
config_user = None
config_host = None
try:
config = ConfigParser.ConfigParser()
config.read( os.path.expanduser( config_file ) )
config_password = config.get(config_section, 'password')
config_user = config.get(config_section, 'username')
config_host = config.get(config_section, 'host')
except Exception, e:
print(str(e))
pass
# parse cli arguments
parser = argparse.ArgumentParser(description='Send the Flexisip documentation to the Wiki. All options passed override the config file.', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('modulename', help='the module name')
parser.add_argument('outputfile', help='the module output doc file')
parser.add_argument('--host', default=default_host, help='the host to which we should send the documentation')
parser.add_argument('-p', '--password', default='', help='the password to authenticate to the server', dest='config_password')
parser.add_argument('-u', '--user', default='', help='the user to authenticate to the server', dest='config_user')
parser = argparse.ArgumentParser(description='Send the Flexisip documentation to the Wiki. All options passed override the config file.')
parser.add_argument('-H', '--host' , help='the host to which we should send the documentation', default='wiki.linphone.org:8080')
parser.add_argument('-w', '--wiki' , help='name of the wiki', default='public', dest='wikiname')
parser.add_argument('-u', '--user' , help='the user to authenticate to the server', dest='config_user')
parser.add_argument('-p', '--password' , help='the password to authenticate to the server', dest='config_password')
parser.add_argument('--flexisip-binary', help='location of the Flexisip executable to run', default='../OUTPUT/bin/flexisip')
args = parser.parse_args()
modulename = args.modulename
if modulename != "global":
module = "module::" + modulename
else:
module = modulename
# summary should be a full string instead of an array of words
args.modulename = 'flexisip:module:' + str.lower(args.modulename)
# read from a configuration file for user/pass/host. This allows for out-of-cli specification of these parameters.
settings = Settings()
config_file = os.path.expanduser('~/.flexiwiki.x.cfg')
if os.access(config_file, os.R_OK):
settings.load(config_file)
# require a password for REST
if args.config_password not in [None, '']:
config_password = args.config_password
if args.config_user not in [None, '']:
config_user = args.config_user
if args.host not in [None, '']:
config_host = args.host
if config_password is None or config_password is '':
print "Please define a password using " + config_file + " or using the --password option"
print "Example of " + config_file +" :"
print "["+config_section+"]"
print "password=toto"
print "username=titi"
print "host=example.com"
if args.config_password is not None:
settings.password = args.config_password
if args.config_user is not None:
settings.user = args.config_user
if args.host is not None:
settings.host = args.host
if args.wikiname is not None:
settings.wikiname = args.wikiname
if settings.password == '':
print("Please define a password using " + config_file + " or using the --password option")
print("Example of " + config_file + ":")
print(settings.dump_example())
sys.exit(1)
fProxy = FlexisipProxy(args.flexisip_binary)
sections = ['global'] + fProxy.module_list
p = subprocess.Popen(['../OUTPUT/bin/flexisip', '--dump-format','xwiki', '--dump-default', module], stdout=subprocess.PIPE , stderr=subprocess.PIPE)
out, err = p.communicate()
if out is not "":
message = "// Documentation based on repostory git version commit "
d = subprocess.Popen(['git', 'describe'], stdout=subprocess.PIPE , stderr=subprocess.PIPE)
gitout, giterr = d.communicate()
# replace all the -- in the doc with {{{--}}} to escape xwiki autoformatting -- into striken
out = re.sub(r"--","{{{--}}}",out)
#add commit version on top of the file
out = message +gitout + "// \n" + out
f = open(args.outputfile, 'w')
f.write(out)
f.close()
version, gitversion = fProxy.get_version()
credentials = XWikiProxy.Credential(settings.user, settings.password)
wiki = XWikiProxy(settings.host, settings.wikiname, credentials=credentials)
host = config_host+modulename
connect = config_user + ":" +config_password
#necessary @ before filename it seems , refer to xwiki REST doc
filename = "@" + modulename + ".xwiki.txt"
p = subprocess.Popen(['curl', '-u', connect , '-X', 'PUT', '--data-binary' , \
filename, '-H', "Content-Type:text/plain", host ], stdout=subprocess.PIPE , stderr=subprocess.PIPE)
for section in sections:
out = fProxy.dump_section_doc(section)
out, err = p.communicate()
print out, err
#add commit version on top of the file
message = "// Documentation based on repostory git version commit {0} //\n\n".format(gitversion)
out = message + out
path = '/Flexisip/Modules Reference Guide/{version}/{pagename}'.format(
version=(version if version == gitversion else 'master'),
pagename=module_name_to_page_name(section))
print("Updating page '{0}'".format(path))
wiki.update_page(path, out)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment