#!/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);