#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author Andreas Götz <cpuidle@gmx.de>
# @author Sven Anders <volkszaehler2011@sven.anders.im> 2011
# @copyright Copyright (c) 2011-2020, The volkszaehler.org project
# @license https://www.gnu.org/licenses/gpl-3.0.txt GNU General Public License version 3
#
# This file is part of volkzaehler.org
#
# volkzaehler.org 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 3 of the License, or
# any later version.
#
# volkzaehler.org 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 volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
#
import argparse
import configparser
import urllib.request as urllib
import os
import json
Config = configparser.ConfigParser()
version="1.1";
parser = argparse.ArgumentParser(description='A python client for volkszaehler.org',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Example request
---------------
To get the titles of all public channels use:
vzclient --url demo.volkszaehler.org/middleware.php -f json -e channels,...title get channel
Note that the ... operator will build an array containing the following child property, in this case `title`.
Syntax of /etc/vzclient.conf or ~/.vzclient.conf
------------------------------------------------
[default]
url:http://www.example.org/subdir/volkszaehler/middleware.php
format:json""")
parser.add_argument("operation",choices=["add","get","edit","delete"],help="what to do");
parser.add_argument('context',choices=["data","channel","group","capabilities"],help="the context of the operation");
parser.add_argument('--url',action='store',help="url to the volkszaehler.org middleware.php (tip: put this in config file, see below)");
parser.add_argument('-u', '--uuid',action='append',help="the uuid to edit, get or delete");
parser.add_argument('-f', '--format',choices=["json","xml","csv","png","gif","jpg"],action='store',help="the format (Note: when requesting json format the response is pretty-printed)");
parser.add_argument('-e', '--eval',action='store',help="get comma-separated attribute from json response (Example: entity,uuid will extract the uuid from a json string: {\"entity\":{\"uuid\":\"4...\"}})");
parser.add_argument('-j', '--json',action='store',help="send json request");
parser.add_argument('param',nargs='*',help="query parameter to add to the request in key=value syntax");
args = parser.parse_args();
Config.read(["/etc/vzclient.conf",os.path.expanduser('~/.vzclient.conf'),".vzclient.conf"]);
url=args.url;
if (url is None):
try:
url=Config.get("default", "url");
except:
print("ERROR: Please specify an url!");
exit(1);
elif (url[:4].lower() != "http"):
url="http://"+url
format=args.format;
if (format is None):
try:
format=Config.get("default","format");
except:
format="json";
context=args.context;
url=url+"/"+context;
uuid=args.uuid;
if (uuid is not None) and len(uuid) == 1:
url=url+"/"+uuid[0];
url=url+"."+format+"?operation="+args.operation
if (uuid is not None) and len(uuid) > 1:
url=url+"&uuid[]="+"&uuid[]=".join(uuid);
for p in args.param:
(key,value)=p.split("=");
url=url+"&"+urllib.quote(key)+"="+urllib.quote(value);
# print(url);
req = urllib.Request(url)
req.add_header('User-Agent', 'vzclient/'+version)
try:
if (args.json):
req.add_header('Content-Type', 'application/json');
f=urllib.urlopen(req, args.json);
else:
f=urllib.urlopen(req);
jsonstr=f.read();
# unparsed - json or other format
if (args.eval is None):
if (args.format == "json"):
print(json.dumps(json.loads(jsonstr), indent=2))
else:
print(jsonstr);
exit(0)
# parsed - only json
obj=json.loads(jsonstr);
for ev in args.eval.split(",") :
if (isinstance(obj,(list,tuple))):
if (ev[:3]=="..."):
ev=ev[3:] # child access key
children = []
for child in obj:
children.append(child[ev])
obj = children
ev = None
else:
try:
ev=int(ev) # array access
except: pass
if (ev != None):
try:
obj=obj[ev]
except KeyError:
print("Key:",ev,"not found in str:",jsonstr);
print(json.dumps(obj, indent=None if args.format != "json" else 2));
except urllib.HTTPError as error:
print(error.read());
exit(1);