PK^uL@pgttrsparam/__init__.py"""Utilities for working with Revit shared parameter files.""" import codecs import csv from collections import namedtuple, defaultdict # pylama:ignore=D105 # rsparam version __version__ = '0.1.7' SharedParamEntries = namedtuple('SharedParamEntries', ['groups', 'params']) class SharedParamFileItem(object): def __init__(self, lineno): self.lineno = lineno def __contains__(self, key): for value in self: if key in value: return True return False def __eq__(self, other): return hash(self) == hash(other) class SharedParamGroup(SharedParamFileItem): def __init__(self, args, lineno=None): super(SharedParamGroup, self).__init__(lineno) self.guid = args[0] self.desc = args[1] self.name = self.desc def __str__(self): return self.desc def __iter__(self): return iter([self.guid, self.desc]) def __repr__(self): return '<{} desc:"{}" guid:{}>'.format(self.__class__.__name__, self.desc, self.guid) def __hash__(self): return hash(self.guid + self.desc) class SharedParam(SharedParamFileItem): def __init__(self, args, lineno=None): super(SharedParam, self).__init__(lineno) self.guid = args[0] self.name = args[1] self.datatype = args[2] self.datacategory = args[3] self.group = args[4] self.visible = args[5] self.desc = args[6] self.usermod = args[7] def __str__(self): return self.desc def __iter__(self): return iter([self.guid, self.name, self.datatype, self.datacategory, self.group, self.visible, self.desc, self.usermod]) def __repr__(self): return '<{} name:"{}" guid:{}>'.format(self.__class__.__name__, self.name, self.guid) def __hash__(self): return hash(self.guid + self.name + self.datatype + self.datacategory + self.visible + self.desc + self.usermod) def read_entries(src_file, encoding=None): # open file and collect shared param and groups spgroups = [] sparams = [] with codecs.open(src_file, 'r', encoding) as spf: count = 0 for line in csv.reader(spf, delimiter="\t"): if len(line) >= 1: if line[0] == 'PARAM': sparam = SharedParam(line[1:], lineno=count) sparams.append(sparam) elif line[0] == 'GROUP': spgroup = SharedParamGroup(line[1:], lineno=count) spgroups.append(spgroup) count += 1 # now update sparams with group obj for sp in sparams: for spg in spgroups: if sp.group == spg.guid: sp.group = spg return SharedParamEntries(spgroups, sparams) def get_paramgroups(src_file, encoding=None): spgroups, sparams = read_entries(src_file, encoding=encoding) return spgroups def get_params(src_file, encoding=None, groupid=None): spgroups, sparams = read_entries(src_file, encoding=encoding) if groupid: return [x for x in sparams if x.group.guid == groupid] return sparams def find_duplicates(src_file, encoding=None, byname=False): param_guid_lut = defaultdict(list) group_guid_lut = defaultdict(list) spgroups, sparams = read_entries(src_file, encoding=encoding) duplparam = 'name' if byname else 'guid' for sparam in sparams: param_guid_lut[getattr(sparam, duplparam)].append(sparam) for spgroup in spgroups: group_guid_lut[getattr(spgroup, duplparam)].append(spgroup) duplgroups = [v for k, v in group_guid_lut.items() if len(v) > 1] duplparams = [v for k, v in param_guid_lut.items() if len(v) > 1] return SharedParamEntries(duplgroups, duplparams) def find(src_file, searchstr, encoding=None): spgroups, sparams = read_entries(src_file, encoding=encoding) matchedgroups = [x for x in spgroups if searchstr in x] matchedparams = [x for x in sparams if searchstr in x] return SharedParamEntries(matchedgroups, matchedparams) def compare(first_file, second_file, encoding=None): spgroups1, sparams1 = read_entries(first_file, encoding=encoding) spgroups2, sparams2 = read_entries(second_file, encoding=encoding) uniqgroups1 = [x for x in spgroups1 if x not in spgroups2] uniqparams1 = [x for x in sparams1 if x not in sparams2] uniqgroups2 = [x for x in spgroups2 if x not in spgroups1] uniqparams2 = [x for x in sparams2 if x not in sparams1] return SharedParamEntries(uniqgroups1, uniqparams1), \ SharedParamEntries(uniqgroups2, uniqparams2) PKbbL ##rsparam/cli.py#!/usr/bin/env python """Utilities for working with Revit shared parameter files Usage: rsparam.py (-h | --help) rsparam.py (-V | --version) rsparam.py [-q -e ] list [-a] rsparam.py [-q -e ] list [-p -g] rsparam.py [-q -e ] list -p [-f ] rsparam.py [-q -e ] find dupl [-n -a -p -g] rsparam.py [-q -e ] find [-p -g] rsparam.py [-q -e ] comp [-p -g -1 -2] rsparam.py [-q -e ] merge ... rsparam.py [-q -e ] sort [-n] Options: -h, --help Show this help. -V, --version Show version. -q, --quiet Quiet mode. -e , --encode File encoding. -a, --all All items. -p, --params Parameters only. -g, --groups Parameter groups only. -f , --filter Filter by group id. -n, --byname Compare by name. -1, --first First file only. -2, --second Second file only. """ from docopt import docopt import colorful from tabulate import tabulate import rsparam _quiet = False # global quiet mode flag _encoding = None # global encoding for reading files def report(message): if not _quiet: print(message) def report_globals(): enc_report = 'encoding={}'.format(_encoding) if _encoding \ else 'encoding not set' report(colorful.yellow(enc_report)) def report_filenames(sparam_files, title='shared parameter file: ', colorfunc=colorful.blue): if not isinstance(sparam_files, list): sparam_files = [sparam_files] for sparam_file in sparam_files: report(colorfunc(f'{title}{sparam_file}')) def list_params(src_file, sparams=None, groupid=None): if not sparams: sparams = rsparam.get_params(src_file, encoding=_encoding, groupid=groupid) sparamdata = [] for sp in sparams: sparamdata.append((sp.guid, sp.name, sp.datatype, sp.group, sp.lineno)) print(tabulate(sparamdata, headers=('Guid', 'Name', 'Datatype', 'Group', 'Line #'))) def list_groups(src_file, spgroups=None): if not spgroups: spgroups = rsparam.get_paramgroups(src_file, encoding=_encoding) spgroupdata = [] for spg in spgroups: spgroupdata.append((spg.guid, spg.name, spg.lineno)) print(tabulate(spgroupdata, headers=('Id', 'Description', 'Line #'))) def list_all(src_file): list_groups(src_file) list_params(src_file) def find_param_dupls(src_file, byname=False): spentries = rsparam.find_duplicates(src_file, byname=byname) duplparam = 'name' if byname else 'guid' dupldata = [] report(colorful.yellow('\nduplicate params by {}:'.format(duplparam))) for dlist in spentries.params: for d in dlist: dupldata.append((d.name if byname else d.guid, d.guid if byname else d.name, d.datatype, d.group, d.lineno)) print(colorful.yellow('\ndupicates by {}: {}'.format(duplparam, dupldata[0][0]))) print(tabulate(dupldata, headers=('Name' if byname else 'Guid', 'Guid' if byname else 'Name', 'Datatype', 'Group', 'Line #'))) def find_group_dupls(src_file, byname=False): spentries = rsparam.find_duplicates(src_file, byname=byname) duplparam = 'name' if byname else 'guid' dupldata = [] report(colorful.yellow('\nduplicate groups by {}:'.format(duplparam))) for dlist in spentries.groups: for d in dlist: dupldata.append((d.name if byname else d.guid, d.guid if byname else d.name, d.lineno)) print(colorful.yellow('\ndupicates by {}: {}'.format(duplparam, dupldata[0][0]))) print(tabulate(dupldata, headers=('Name' if byname else 'Guid', 'Guid' if byname else 'Name', 'Line #'))) def find_all_dupls(src_file, groupsonly=False, paramsonly=False): if not paramsonly: find_group_dupls(src_file) find_group_dupls(src_file, byname=True) if not groupsonly: find_param_dupls(src_file) find_param_dupls(src_file, byname=True) def find_matching(src_file, search_str, groupsonly=False, paramsonly=False): spentries = rsparam.find(src_file, search_str, encoding=_encoding) if spentries.groups and not paramsonly: report(colorful.yellow('\ngroups matching: {}'.format(search_str))) list_groups(None, spgroups=spentries.groups) if spentries.params and not groupsonly: report(colorful.yellow('\nparams matching: {}'.format(search_str))) list_params(None, sparams=spentries.params) def comp(first_file, second_file, listfirstonly=False, listsecondonly=False, groupsonly=False, paramsonly=False): uniq1, uniq2 = rsparam.compare(first_file, second_file, encoding=_encoding) if uniq1.groups and not paramsonly and not listsecondonly: report(colorful.yellow('\nunique groups in first')) list_groups(None, spgroups=uniq1.groups) if uniq2.groups and not paramsonly and not listfirstonly: report(colorful.yellow('\nunique groups in second')) list_groups(None, spgroups=uniq2.groups) if uniq1.params and not groupsonly and not listsecondonly: report(colorful.yellow('\nunique parameters in first')) list_params(None, sparams=uniq1.params) if uniq2.params and not groupsonly and not listfirstonly: report(colorful.yellow('\nunique parameters in second')) list_params(None, sparams=uniq2.params) def merge(dest_file, source_files): raise NotImplementedError() def sort(source_file, dest_file, byname=False): raise NotImplementedError() def main(): args = docopt(__doc__, version='rsparam {}'.format(rsparam.__version__)) # set global flags _quiet = args['--quiet'] _encoding = args['--encode'] report_globals() # process command line args # print(args) # exit() if args['list']: src_file = args[''] report_filenames(src_file, title='source file: ') if args['--groups'] and not args['--params']: # list groups only list_groups(src_file) elif args['--params'] and not args['--groups']: # list params only list_params(src_file, groupid=args['--filter']) else: # list everything list_all(src_file) elif args['find']: src_file = args[''] report_filenames(src_file, title='source file: ') if args['dupl']: if args['--params']: if args['--all']: find_all_dupls(src_file, paramsonly=True) else: find_param_dupls(src_file, byname=args['--byname']) elif args['--groups']: if args['--all']: find_all_dupls(src_file, groupsonly=True) else: find_group_dupls(src_file, byname=args['--byname']) else: find_all_dupls(src_file) else: find_matching(src_file, args[''], paramsonly=args['--params'], groupsonly=args['--groups']) elif args['comp']: first_file = args[''] report_filenames(first_file, title='first file: ') second_file = args[''] report_filenames(second_file, title='second file: ') comp(first_file, second_file, listfirstonly=args['--first'], listsecondonly=args['--second'], paramsonly=args['--params'], groupsonly=args['--groups']) elif args['merge']: dest_file = args[''] report_filenames(dest_file, title='destination file: ') src_files = args[''] report_filenames(src_files, title='source file: ') merge(dest_file, src_files) elif args['sort']: source_file = args[''] report_filenames(source_file, title='source file: ') dest_file = args[''] report_filenames(dest_file, title='destination file: ') sort(source_file, dest_file, byname=args['--byname']) report('') PKYbLrsparam/tests/__init__.pyPKYbLrsparam/tests/clitests.shPKYbLrsparam/tests/file1.txtPKYbLrsparam/tests/file2.txtPK!HxgR_(,(rsparam-0.1.7.dist-info/entry_points.txtN+I/N.,()**.H,J̵z9Vy\\PKQaL*1`FFrsparam-0.1.7.dist-info/LICENSEMIT License Copyright (c) 2018 Ehsan Iran-Nejad Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!HxyUbrsparam-0.1.7.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,Q034 /, (-JLR()*M ILR(4KM̫#DPK!H3l rsparam-0.1.7.dist-info/METADATA]AN@ Es _ e4+*@jMM0 gZ~^bI0XX䷦BO$(_u/;GWvL p C'tdأPRhQ*xFҍ^u(DM |5 1j^} O}dL}TLM*;ڕ<n0+ 8z(%cA|*όhWBtQU0 QF&SvG͚%_$9DE{cCʍm¤ Ŕٵad(7x+'ۏ:EʑeU޷j<ռd%&cTxȺXiМ(鬿4FPsGk7 t*hc]tan◁|s Ʉ<O4=S#1e$F,[9m=8Z\]ၔrW͍hqo?PK^uL@pgttrsparam/__init__.pyPKbbL ##rsparam/cli.pyPKYbL7rsparam/tests/__init__.pyPKYbL7rsparam/tests/clitests.shPKYbL8rsparam/tests/file1.txtPKYbLM8rsparam/tests/file2.txtPK!HxgR_(,(8rsparam-0.1.7.dist-info/entry_points.txtPKQaL*1`FF8rsparam-0.1.7.dist-info/LICENSEPK!HxyUbs=rsparam-0.1.7.dist-info/WHEELPK!H3l >rsparam-0.1.7.dist-info/METADATAPK!H:љO1?rsparam-0.1.7.dist-info/RECORDPK  A