Source code for pydarkstar.itemlist

from .darkobject import DarkObject
from . import item
import collections
import re
import os


[docs]class ItemList(DarkObject): """ Container for Item objects. """ def __init__(self): super(ItemList, self).__init__() self.items = collections.OrderedDict()
[docs] @classmethod def from_csv(cls, *data): """ Create ItemList from CSV file(s). """ # make sure there is data if not data: raise RuntimeError('missing item data CSV!') # load data obj = ItemList() obj.info('loading item data...') for f in data: obj.loadcsv(f) return obj
[docs] def add(self, itemid, *args, **kwargs): """ Add Item to ItemList. Item must not already exist. .. seealso:: py:class:`pydarkstar.item.Item` """ i = item.Item(itemid, *args, **kwargs) if i.itemid in self.items: raise KeyError('duplicate item found: %d' % i.itemid) self.items[i.itemid] = i return i
[docs] def set(self, *itemids, **kwargs): """ Set Item(s) properties. """ for itemid in itemids: i = self[itemid] for k in kwargs: if hasattr(i, k): setattr(i, k, kwargs[k]) else: raise KeyError('%s' % str(k))
[docs] def get(self, itemid): """ Get Item by itemid. """ return self.items[itemid]
def __getitem__(self, itemid): return self.items[itemid] def __len__(self): return len(self.items)
[docs] def loadcsv(self, fname): """ Load Item(s) from CSV file. Columns are Item attributes. The 'itemid' column is required. :param fname: name of file """ regex_c = re.compile(r'#.*$') regex_t = '[{0}{1}]?True[{0}{1}]?'.format('"', "'") regex_t = re.compile(regex_t, re.IGNORECASE) regex_f = '[{0}{1}]?False[{0}{1}]?'.format('"', "'") regex_f = re.compile(regex_f, re.IGNORECASE) self.info('load %s', fname) line_number = 0 with open(fname, 'r') as handle: # first line is item titles line = handle.readline() line_number += 1 # ignore comments line = regex_c.sub('', line).strip() # split into tokens keys = line.split(',') keys = list(map(lambda x: x.strip().lower(), keys)) # make sure keys are valid for k in keys: if k not in item.Item.keys: raise RuntimeError('unknown column: %s' % k) # check for primary key if 'itemid' not in keys: raise RuntimeError('missing itemid column:\n\t%s' % keys) # other lines are items line = handle.readline() line_number += 1 while line: # remove comments line = regex_c.sub('', line).strip() # fix True and False line = regex_t.sub('1', line) line = regex_f.sub('0', line) # ignore empty lines if line: # split into tokens tokens = list(map(lambda x: x.strip(), line.split(','))) # check for new title line if set(tokens).issubset(item.Item.keys): keys = tokens # check for primary key if 'itemid' not in keys: raise RuntimeError('missing itemid column:\n\t%s' % keys) # validate line elif set(tokens).intersection(item.Item.keys): raise RuntimeError('something wrong with line %d' % line_number) # process normal line else: # try to evaluate tokens for i, token in enumerate(tokens): try: token = eval(token) except SyntaxError: pass except NameError: pass # process missing tokens if isinstance(token, str) and not token: token = None tokens[i] = token # map values kwargs = {k: None for k in keys} for i in range(len(tokens)): kwargs[keys[i]] = tokens[i] # add new item self.add(**kwargs) # read next line line = handle.readline() line_number += 1
[docs] def savecsv(self, fname, itertitle=100): """ Save Item data to CSV file. :param fname: name of file :param itertitle: how often to write title line """ if os.path.exists(fname): self.info('overwriting file...') self.info('save %s', fname) else: self.info('save %s', fname) with open(fname, 'w') as handle: for j, i in enumerate(self.items): if j % itertitle == 0: handle.write(item.title_str()) handle.write(item.value_str(self.items[i]))
if __name__ == '__main__': pass