]> git.ipfire.org Git - people/ms/python-rrdtool.git/blob - RRDtool.py
Changed License to LGPLv3.
[people/ms/python-rrdtool.git] / RRDtool.py
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3 #
4 # rrdtool-py3k, rrdtool bindings for Python 3.
5 # Based on the rrdtool Python bindings for Python 2 from
6 # Hye-Shik Chang <perky@fallin.lv>.
7 #
8 # Copyright 2012 Christian Jurk <commx@commx.ws>
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU Lesser General Public License as
12 # published by the Free Software Foundation; either version 3 of the
13 # License, or (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU Lesser General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 # MA 02110-1301, USA.
24 #
25 #
26
27 from datetime import datetime
28 from io import BytesIO
29 import os
30 import rrdtool
31 from time import mktime
32
33 def create(filename, *args):
34 "Create a Round Robin Database and return a RRD object on success."
35 rrdtool.create(filename, *args)
36
37 if not os.access(filename, os.F_OK):
38 raise rrdtool.OperationalError('RRD file was not created')
39
40 return RRD(filename)
41
42 class RRD:
43 """An object-based interface to the rrdtool module."""
44
45 def __init__(self, filename, check_type=True):
46 "Initialize the class instance with a filename."
47
48 if not os.access(filename, os.F_OK | os.R_OK):
49 raise rrdtool.OperationalError('RRD {!s} cannot be opened.' \
50 .format(filename))
51
52 # Use rrdinfo to test whether the file is a valid RRD file
53 if check_type is True:
54 rrdtool.info(filename)
55
56 self.readonly = not os.access(filename, os.W_OK)
57 self.filename = filename
58
59 def graph(self, output_file, *args):
60 "Create a graph based on one or more RRDs."
61 buffered = True
62 outfile = '-'
63
64 # write straigt into file using wrapper functions
65 if isinstance(output_file, str):
66 buffered = False
67 outfile = output_file
68
69 gdata = rrdtool.graph(outfile, *args)
70
71 if isinstance(gdata, tuple) and len(gdata) >= 4:
72 if output_file is None:
73 return gdata[3]
74 elif isinstance(output_file, BytesIO):
75 output_file.write(gdata[3])
76 return output_file
77
78 return None
79
80 def info(self):
81 return rrdtool.info(self.filename)
82
83 def update(self, values, *args):
84 vl = []
85
86 if self.readonly:
87 raise rrdtool.OperationalError('RRD file is read-only: {!s}' \
88 .format(self.filename))
89 elif not isinstance(values, (list, tuple)):
90 raise rrdtool.ProgrammingError('The values parameter must be a ' \
91 'list or tuple')
92 else:
93 for row in values:
94 if isinstance(row, str):
95 vl.append(row)
96 elif isinstance(row, (list, tuple)):
97 if len(row) < 2:
98 raise rrdtool.ProgrammingError('Value {!r} has too ' \
99 'few elements in sequence object'.format(row))
100 else:
101 ts = row[0]
102 if ts is None:
103 ts = 'N'
104 elif isinstance(ts, datetime):
105 ts = int(mktime(ts.timetuple()))
106 elif isinstance(ts, str):
107 ts = int(ts)
108 elif not isinstance(ts, int):
109 raise ValueError('Unsupported type')
110
111 v = '{}:{}'.format(ts, ':'.join([str(x) for x in row[1:]]))
112 vl.append(v)
113
114 arglist = tuple(vl + list(args))
115 return rrdtool.update(self.filename, *arglist)
116
117 def __repr__(self):
118 return '<RRD {!r}>'.format(self.filename)