[976] | 1 | import re
|
---|
| 2 |
|
---|
| 3 | from ....builtins import *
|
---|
| 4 |
|
---|
| 5 | from ...exceptions import *
|
---|
| 6 | from ...expressions import *
|
---|
| 7 | from ...streams import *
|
---|
| 8 |
|
---|
| 9 | import pytz
|
---|
| 10 | import dateutil.parser
|
---|
| 11 | datetimeparser = dateutil.parser.parser()
|
---|
| 12 |
|
---|
| 13 | ##
|
---|
| 14 | ## vmquery has records separated by a line of = characters
|
---|
| 15 | ##
|
---|
| 16 | def stream(stream, format='vmquery -X'):
|
---|
| 17 |
|
---|
| 18 | if format in ['vmquery -X']:
|
---|
| 19 | return LineSeparatorStream(stream, separator='================================================================================', header=1)
|
---|
| 20 | else:
|
---|
| 21 | raise ParseError, 'Unknown format %s' % (format)
|
---|
| 22 |
|
---|
| 23 |
|
---|
| 24 | ##
|
---|
| 25 | ## Parse a vmquery record
|
---|
| 26 | ##
|
---|
| 27 | ## vmquery -a -X
|
---|
| 28 | ##
|
---|
| 29 | def parse(record, format='vmquery -X', version=None, tz=None):
|
---|
| 30 |
|
---|
| 31 | volume = ExtendedDict()
|
---|
| 32 |
|
---|
| 33 | #re_pair = re.compile('^([^:]+):\s*(.*)$')
|
---|
| 34 | re_pair = re.compile('^\s*([^:]+):\s*(.*)\s*$')
|
---|
| 35 | re_dashes = re.compile('^-+$')
|
---|
| 36 | #re_type_id = re.compile('^(.+)\s+\((\d+)\)$')
|
---|
| 37 | re_type_id = re.compile('^([0-9a-zA-Z\-_ /"]+)\s+\((\d+)\)$')
|
---|
| 38 |
|
---|
| 39 | if format == 'vmquery -X':
|
---|
| 40 |
|
---|
| 41 | try:
|
---|
| 42 |
|
---|
| 43 | for line in record:
|
---|
| 44 |
|
---|
| 45 | if line == '':
|
---|
| 46 | continue
|
---|
| 47 |
|
---|
| 48 | match = re_pair.match(line)
|
---|
| 49 |
|
---|
| 50 | key = match.group(1)
|
---|
| 51 | value = match.group(2)
|
---|
| 52 | key = key.lower()
|
---|
| 53 | key = key.replace(' ', '_')
|
---|
| 54 | key = key.replace('/', '_')
|
---|
| 55 |
|
---|
| 56 | #
|
---|
| 57 | # convert text values to python datatypes
|
---|
| 58 | #
|
---|
| 59 | while True:
|
---|
| 60 |
|
---|
| 61 | #
|
---|
| 62 | # convert to integer value
|
---|
| 63 | #
|
---|
| 64 | match = re_integer.match(value)
|
---|
| 65 | if match:
|
---|
| 66 | value = int(value)
|
---|
| 67 | break
|
---|
| 68 |
|
---|
| 69 | #
|
---|
| 70 | # convert - to None
|
---|
| 71 | #
|
---|
| 72 | match = re_dashes.match(value)
|
---|
| 73 | if match:
|
---|
| 74 | value = None
|
---|
| 75 | break
|
---|
| 76 |
|
---|
| 77 | #
|
---|
| 78 | # separate type and id
|
---|
| 79 | #
|
---|
| 80 | match = re_type_id.match(value)
|
---|
| 81 | if match:
|
---|
| 82 | idkey = '%s_id' % (key)
|
---|
| 83 | value = match.group(1)
|
---|
| 84 | volume[idkey] = int(match.group(2))
|
---|
| 85 | break
|
---|
| 86 |
|
---|
| 87 | #
|
---|
| 88 | # convert timestamps to Python datetime objects with timezone
|
---|
| 89 | #
|
---|
| 90 | if key in ['created', 'assigned', 'first_mounted', 'last_mounted', 'expiration']:
|
---|
| 91 |
|
---|
| 92 | if value is None:
|
---|
| 93 | break
|
---|
| 94 |
|
---|
| 95 | try:
|
---|
| 96 | dt = datetimeparser.parse(value)
|
---|
| 97 | dt = dt.replace(tzinfo=tz)
|
---|
| 98 | value = dt
|
---|
| 99 | break
|
---|
| 100 |
|
---|
| 101 | except ValueError:
|
---|
| 102 | value = value
|
---|
| 103 |
|
---|
| 104 | #
|
---|
| 105 | # break out of enclosing while loop
|
---|
| 106 | #
|
---|
| 107 | break
|
---|
| 108 |
|
---|
| 109 | volume[key] = value
|
---|
| 110 |
|
---|
| 111 | return volume
|
---|
| 112 |
|
---|
| 113 | except Exception, e:
|
---|
| 114 |
|
---|
| 115 | #raise ParseError, e
|
---|
| 116 | raise
|
---|
| 117 |
|
---|
| 118 |
|
---|
| 119 | else:
|
---|
| 120 |
|
---|
| 121 | raise ParseError, 'Unknown format %s' % (format)
|
---|
| 122 |
|
---|
| 123 |
|
---|
| 124 |
|
---|