]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
tvh-json: more updates, added README.md
authorJaroslav Kysela <perex@perex.cz>
Thu, 31 Aug 2017 13:00:19 +0000 (15:00 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 31 Aug 2017 13:20:27 +0000 (15:20 +0200)
lib/api/python/README.md [new file with mode: 0644]
lib/api/python/tvh-json.py

diff --git a/lib/api/python/README.md b/lib/api/python/README.md
new file mode 100644 (file)
index 0000000..e521ed1
--- /dev/null
@@ -0,0 +1,86 @@
+tvh-json.py
+=================================
+(c) 2017 Tvheadend Foundation CIC
+
+The json import / export tool written in the python language.
+
+
+Background
+----------
+
+TVHeadend uses internal database called idnode. This database uses
+unique identifier (UUID) for each entry. The entries may be linked
+(thus some nodes may refer to another). The each entry belongs
+to a class which defines the meta data (type, description).
+
+
+Environment variables
+---------------------
+
+Name          | Description
+-----------------------------------------------------------
+TVH_URL_API   | URL like http://localhost:9981/api
+TVH_USER      | username for HTTP API
+TVH_PASS      | password for HTTP API
+
+
+Command 'get'
+-------------
+
+This is basic command which allows the elementary operation through
+the HTTP API. Basically, almost all other commands uses this internally.
+
+Arguments:
+* path
+* json string (arguments)
+
+
+Command 'pathlist'
+------------------
+
+Returns all path names.
+
+
+Command 'classes'
+-----------------
+
+Returns all class names.
+
+
+Command 'import'
+----------------
+
+Imports the json data and updates the internal structure in TVHeadend's
+database. The structure must be identical to data printed with the 'export'
+command.
+
+Arguments:
+* uuid
+* filename (optional - otherwise standard input is used)
+
+
+Command 'export'
+----------------
+
+Exports the json data from TVHeadend's database.
+
+Arguments:
+* uuid
+
+
+Command 'exportcls'
+-------------------
+
+Exports the json data from TVHeadend's database for all idnodes which
+belongs to the specified class.
+
+Arguments:
+* class
+
+
+Examples:
+---------
+
+`TVH_USER=admin TVH_PASS=admin ./tvh-json.py exportcls dvb_mux_dvbs`
+`TVH_USER=admin TVH_PASS=admin ./tvh-json.py export 6dbdb849bd8eae9c1fecf684f773baca > a.json`
+`TVH_USER=admin TVH_PASS=admin ./tvh-json.py import 6dbdb849bd8eae9c1fecf684f773baca < a.json`
index d04baa1a01c4f75c4f3b53108fa25aaedd84062e..fd5f67025591e413493c5931364fff15d913ce0f 100755 (executable)
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 
 #
-# TVH bintray tool, compatible with both python2 and python3
+# TVH json import/export tool, compatible with both python2 and python3
 #
 
 import os
@@ -12,23 +12,21 @@ import traceback
 try:
     # Python 3
     import urllib.request as urllib
-    from urllib.parse import urlencode
+    from urllib.parse import urlencode, quote
 except ImportError:
     # Python 2
     import urllib2 as urllib
-    from urllib import urlencode
+    from urllib import urlencode, quote
 
-def env(key):
+def env(key, deflt):
     if key in os.environ: return os.environ[key]
-    return None
+    return deflt
 
 DEBUG=False
 
-TVH_API=env('TVH_API_URL') or 'http://localhost:9981/api'
-TVH_USER=env('TVH_USER')
-TVH_PASS=env('TVH_PASS')
-
-PACKAGE_DESC='Tvheadend is a TV streaming server and recorder for Linux, FreeBSD and Android'
+TVH_API=env('TVH_API_URL', 'http://localhost:9981/api')
+TVH_USER=env('TVH_USER', None)
+TVH_PASS=env('TVH_PASS', None)
 
 class Response(object):
     def __init__(self, response):
@@ -71,7 +69,7 @@ class TVHeadend(object):
         if binary:
           content_type = 'application/binary'
         else:
-          data = data and urlencode(data) or None
+          data = data and urlencode(data).encode('utf-8') or None
         opener = self.opener()
         path = self._path
         if path[0] != '/': path = '/' + path
@@ -92,10 +90,14 @@ class TVHeadend(object):
     def post(self, data):
         return self._push(data, method='POST')
 
-def do_get(*args):
+def do_get0(*args):
     if len(args) < 1: error(1, 'get [path] [json_query]')
     path = args[0]
-    query = len(args) > 1 and json.loads(args[1]) or None
+    query = None
+    if len(args) > 1:
+        query = args[1]
+        if type(query) != type({}):
+            query = json.loads(query.decode('utf-8'))
     if query:
         for q in query:
             r = query[q]
@@ -104,16 +106,69 @@ def do_get(*args):
     resp = TVHeadend(path).post(query)
     if resp.code != 200 and resp.code != 201:
         error(10, 'HTTP ERROR "%s" %s %s', resp.url, resp.code, resp.reason)
-    if type(resp.body) == type({}) or type(resp.body) == type([]):
-        print(json.dumps(resp.body, indent=4, separators=(',', ': ')))
+    return resp.body
+
+def do_get(*args):
+    body = do_get0(*args)
+    if type(body) == type({}) or type(body) == type([]):
+        print(json.dumps(body, indent=4, separators=(',', ': ')))
+    else:
+        print(body)
+
+def do_export(*args):
+    if len(args) < 1: error(1, 'get [uuid]')
+    body = do_get0('raw/export', {'uuid':args[0]})
+    if type(body) != type({}):
+        error(11, 'Unknown data')
+    if 'entries' in body:
+        body = body['entries']
+    if len(body) == 1:
+        body = body[0]
+    if not 'uuid' in body:
+        body['uuid'] = args[0].strip()
+    print(json.dumps(body, indent=4, separators=(',', ': ')))
+
+def do_exportcls(*args):
+    if len(args) < 1: error(1, 'get [class]')
+    body = do_get0('raw/export', {'class':args[0]})
+    if type(body) != type({}) and type(body) != type([]):
+        error(11, 'Unknown data')
+    if 'entries' in body:
+        body = body['entries']
+    if len(body) == 1:
+        body = body[0]
+    print(json.dumps(body, indent=4, separators=(',', ': ')))
+
+def do_import(*args):
+    if len(args) < 1:
+        jdata = sys.stdin.read()
     else:
-        print(resp.body)
+        fp = open(args[0])
+        jdata = fp.read()
+        fp.close()
+    jdata = json.loads(jdata.decode('utf-8'))
+    body = do_get0('raw/import', {'node':jdata})
+    if body and type(body) != type({}):
+        error(11, 'Unknown data / response')
+
+def do_paths(*args):
+    do_get('pathlist')
+
+def do_classes(*args):
+    do_get('classes')
+
+def do_unknown(*args):
+    r = 'Please, specify a valid command:\n'
+    for n in globals():
+        if n.startswith('do_') and n != 'do_unknown':
+            r += '  ' + n[3:] + '\n'
+    error(1, r[:-1])
 
 def main(argv):
     global DEBUG
     if not TVH_USER or not TVH_PASS:
         error(2, 'No credentals')
-    if argv[1] == '--debug':
+    if len(argv) > 1 and argv[1] == '--debug':
         DEBUG=1
         argv.pop(0)
     cmd = 'do_' + (len(argv) > 1 and argv[1] or 'unknown')