Skip to content

Commit

Permalink
Added TigerFile class, not done yet.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjwelborn committed Feb 28, 2019
1 parent cb05cba commit fe968ab
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 2 deletions.
130 changes: 129 additions & 1 deletion lib/util/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
import shutil
from contextlib import suppress

from lxml import etree as ElementTree

from colr import (
auto_disable as colr_auto_disable,
Colr as C,
)

from .config import (
config_increment,
)
Expand All @@ -23,6 +30,7 @@
)
from .format import create_xml

colr_auto_disable()

# Pattern to grab multiple cab quantities from a room/cab number.
cab_count_pat = re.compile(r'R?\d{1,3}?\:?\d{1,3}?\((\d{1,3})\)')
Expand Down Expand Up @@ -371,7 +379,15 @@ def write_tiger_file(
)
print_err(msg)
return error_cb(mozfile, msg) if use_err_cb else 1
status('Created', tigerpath)
partlen = len(mozfile.parts)
plural = 'part' if partlen == 1 else 'parts'
msg = C(' ').join(
C('Created', 'blue'),
C(partlen, 'blue', style='bright'),
C(plural, 'blue'),
C('parts in', 'blue'),
)
status(msg, tigerpath)
if archive_dir in (None, '', '-'):
# No archiving was requested/set.
debug('No archiving {}.'.format(
Expand Down Expand Up @@ -935,3 +951,115 @@ def to_csv(self):
class MozaikPart(MozaikMasterPart):
""" A part with a width that depends on the MozaikFile's width. """
header = MozaikFile.header


class TigerFile(object):
""" A tiger file (XML, .tiger) constructed from a file or XML string with
a header and a parts list.
Typical Header:
Index, Quantity, Completed, Length, Part, No, Note
...where Quantity and Completed are TigerStop values, and the
others are from the user's printStrings/labelField/labelStrings.
"""
def __init__(self, filename=None, parts=None):
self.filename = filename or None
self.parts = parts or []
# Header values always added by tigerstop.
self.header_ts = ['Quantity', 'Completed', 'Length']
# Header values added by the user through labelStrings.
self.header_user = None
# Final header for display, set in self.from_bytes().
self.header = None
self.root = None

def __str__(self):
partlen = len(self.parts)
singleitem = partlen == 1
return '{}(filename={!r}, parts={})'.format(
type(self).__name__,
self.filename,
'[{} {}{}]'.format(
partlen,
'part' if singleitem else 'parts',
'' if singleitem else '..',
),
)

def _build_headers(self, rootelem):
""" Set self.header with values from `header_ts` and `header_user`,
calling `_parse_user_headers()` to get them.
"""
# Get user headers.
self.header_user = self._parse_user_headers(rootelem)
if not self.header_user:
raise ValueError(
'No user headers!: {!r}'.format(self.header_user)
)
if self.header_user.lower() in ('index', 'count'):
self.header = [self.header_user[0]]
skip = 1
else:
self.header = []
skip = 0
self.header.extend(self.header_ts)
self.header.extend(self.header_user[skip:])

@classmethod
def from_file(cls, filename):
with open(filename, 'rb') as f:
tf = cls.from_bytes(f.read())
tf.filename = filename
return tf

@classmethod
def from_bytes(cls, b, filename=None):
""" Create a TigerFile from XML bytes (a .tiger file's content). """
tf = cls(filename=filename)
root = ElementTree.fromstring(b)

tf._build_headers(root)
tf.parts = tf._parse_pieces(root)
return tf

def _parse_pieces(self, rootelem):
# Parse parts in <pieces><Piece>..</Piece>..</pieces>
if not self.header_user:
raise ValueError('Headers not set (needs _build_headers())!')

parts = []
for piece in rootelem.iter('Piece'):
partinfo = {
'length': piece.find('length').text,
'quantity': int(piece.find('quantity').text),
'completed': int(piece.find('completed').text),

}
lblstrs = piece.find('labelStrings')
# Expecting Index, Part, No, and optional Note <string>s.
userstrs = [
(i, string.text)
for i, string in enumerate(lblstrs.findall('string'))
]
for index, value in userstrs:
lbl = self.header_user[index]
if lbl.lower() in ('index', 'count'):
value = int(value)
partinfo[lbl] = value

parts.append(partinfo)
return parts

@classmethod
def _parse_user_headers(cls, rootelem):
""" Grab all <header>s from <printStrings>, and return the text
in a list, using <column> for the list index.
Returns a list of user headers from a .tiger file root element.
"""

user_headers = []
for lblfield in rootelem.find('printStrings'):
index = int(lblfield.find('column').text)
user_headers.insert(index, lblfield.find('header').text)
return user_headers
2 changes: 1 addition & 1 deletion tigertamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def main(argd):
)
)
for pfile in sorted(parentfiles):
debug(pfile, align=True)
debug('Parent file: {}'.format(pfile))
return errs


Expand Down

0 comments on commit fe968ab

Please sign in to comment.