def get_rst(self): #~ print 'MainBlogIndexDirective.get_rst()' #~ env = self.state.document.settings.env #~ print self.arguments, self.options, self.content cellsep = '<NEXTCELL>' rowsep = '<NEXTROW>' if len(self.arguments) > 0: cellsep = self.arguments[0] if len(self.arguments) > 1: rowsep = self.arguments[1] content = '\n'.join(self.content) rows = [] colcount = None for row in content.split(rowsep): cells = [cell.strip() for cell in row.split(cellsep)] if colcount is None: colcount = len(cells) else: assert colcount == len(cells) rows.append(cells) if 'header' in self.options: return rstgen.table(rows[0], rows[1:]) return rstgen.table([""] * colcount, rows, show_headers=False)
def summary(*cmdline_args): """Print a summary to stdout.""" headers = ( # ~ '#','Location', 'Project', # 'Old version', 'Version') def cells(self): # print 20140116, self.module url = self.SETUP_INFO['url'] desc = "`%s <%s>`__ -- %s" % ( self.name, url, self.SETUP_INFO['description']) #~ import pkg_resources #~ for d in pkg_resources.find_distributions(self.name): #~ d = pkg_resources.get_distribution(self.name) #~ d = pkg_resources.Distribution.from_location("http://pypi.python.org/simple/",self.name) #~ print 20130911, self.name, d.version return ( '\n'.join(textwrap.wrap(desc, 60)), # self.dist.version, self.SETUP_INFO['version']) print rstgen.table(headers, [cells(p) for p in atelier.load_projects()])
def show_fields(model, fieldnames=None): """Print an overview description of the specified fields of the specified model. """ cells = [] cols = ["Internal name", "Verbose name", "Help text"] if isinstance(model, BoundAction): get_field = model.action.parameters.get if fieldnames is None: fieldnames = model.action.params_layout elif isinstance(model, Action): get_field = model.parameters.get if fieldnames is None: fieldnames = model.params_layout.main elif issubclass(model, Model): get_field = model._meta.get_field elif issubclass(model, AbstractTable): get_field = model.parameters.get if fieldnames is None: fieldnames = model.params_layout.main if isinstance(fieldnames, six.string_types): fieldnames = fieldnames.split() for n in fieldnames: fld = get_field(n) if fld is not None: cells.append([n, fld.verbose_name, unindent(fld.help_text)]) print(table(cols, cells).strip())
def show_fields(model, fieldnames=None): """Print an overview description of the specified fields of the specified model. """ cells = [] cols = ["Internal name", "Verbose name", "Help text"] if isinstance(model, BoundAction): get_field = model.action.parameters.get if fieldnames is None: fieldnames = model.action.params_layout elif isinstance(model, Action): get_field = model.parameters.get if fieldnames is None: fieldnames = model.params_layout.main elif issubclass(model, Model): get_field = model._meta.get_field if fieldnames is None: fieldnames = [f.name for f in model._meta.get_fields()] elif issubclass(model, AbstractTable): get_field = model.parameters.get if fieldnames is None: fieldnames = model.params_layout.main if isinstance(fieldnames, six.string_types): fieldnames = fieldnames.split() for n in fieldnames: fld = get_field(n) if fld is not None and hasattr(fld, 'verbose_name'): cells.append([n, fld.verbose_name, unindent(fld.help_text or '')]) print(table(cols, cells).strip())
def get_rst(self): env = self.state.document.settings.env entries = [] all_docnames = env.found_docs.copy() found = set([env.docname]) # don't include myself for entry in self.content: if not entry: continue patname = docname_join(env.docname, entry) docnames = sorted(patfilter(all_docnames, patname)) for docname in docnames: if not docname in found: found.add(docname) entries.append(self.entry_class.create(env, docname)) expr = self.options.get('filter') if expr: def func(e): return eval(expr, dict(e=e)) entries = list(filter(func, entries)) orderby = self.options.get('orderby') if orderby: def func(a, b): va = getattr(a, orderby, '') vb = getattr(b, orderby, '') return cmp(va, vb) entries = sorted(entries, func) headers = self.get_headers() rows = [] for e in entries: rows.append(self.format_entry(e)) return rstgen.table(headers, rows)
def analyze_rst(*packages): """ Example: >>> from lino.utils.code import analyze_rst >>> print analyze_rst('lino') """ fields = 'count_code count_doc count_comment count_total'.split() headers = ["name", "code lines", "doc lines", "comment lines", "total lines"] rows = [] def fmt(n): return "{}k".format(round(n/1000.0, 1)) total_sums = [0] * len(fields) for package in packages: sums = [0] * len(fields) for name, filename in codefiles(package + '*'): sf = SourceFile(name, filename) for i, k in enumerate(fields): sums[i] += getattr(sf, k) rows.append([package] + [fmt(n) for n in sums]) for i, k in enumerate(fields): total_sums[i] += sums[i] rows.append(['total'] + [fmt(n) for n in total_sums]) return rstgen.table(headers, rows)
def summary(*cmdline_args): """Print a summary to stdout.""" from atelier.projects import load_projects headers = ( # ~ '#','Location', 'Project', # 'Old version', 'Version') def cells(self): self.load_fabfile() # print 20140116, self.module desc = "%s -- " % self.nickname desc += "(doc_trees : %s)\n" % ', '.join(self.doc_trees) url = self.SETUP_INFO.get('url', None) version = self.SETUP_INFO.get('version', '') if url: desc += "`%s <%s>`__ -- %s" % ( self.name, url, self.SETUP_INFO['description']) return ( '\n'.join(textwrap.wrap(desc, 60)), # self.dist.version, version) print(rstgen.table(headers, [cells(p) for p in load_projects()]))
def analyze_rst(*packages): """ Example: >>> from lino.utils.code import analyze_rst >>> print analyze_rst('lino') """ fields = 'count_code count_doc count_comment count_total'.split() headers = [ "name", "code lines", "doc lines", "comment lines", "total lines" ] rows = [] total_sums = [0] * len(fields) for package in packages: sums = [0] * len(fields) for name, filename in codefiles(package + '*'): sf = SourceFile(name, filename) for i, k in enumerate(fields): sums[i] += getattr(sf, k) rows.append([package] + [str(n) for n in sums]) for i, k in enumerate(fields): total_sums[i] += sums[i] rows.append(['total'] + [str(n) for n in total_sums]) return rstgen.table(headers, rows)
def get_db_overview_rst(self): """ Returns a reStructredText-formatted "database overview" report. Used by the :mod:`diag <lino.management.commands.diag>` command and in test cases. """ from atelier import rstgen from lino.core.dbutils import (full_model_name, sorted_models_list, app_labels) #~ writeln("Lino %s" % lino.__version__) #~ yield (settings.SITE.verbose_name, settings.SITE.version) #~ writeln(settings.SITE.title) models_list = sorted_models_list() apps = app_labels() s = "%d apps: %s." % (len(apps), ", ".join(apps)) s += "\n%d models:\n" % len(models_list) i = 0 headers = [ #~ "No.", "Name", #~ "Class", #~ "M", "#fields", "#rows", #~ ,"first","last" ] rows = [] for model in models_list: if model._meta.managed: i += 1 cells = [] #~ cells.append(str(i)) cells.append(full_model_name(model)) #~ cells.append(str(model)) #~ if model._meta.managed: #~ cells.append('X') #~ else: #~ cells.append('') cells.append(str(len(model._meta.fields))) #~ qs = model.objects.all() qs = model.objects.order_by('pk') n = qs.count() cells.append(str(n)) #~ if n: #~ cells.append(obj2str(qs[0])) #~ cells.append(obj2str(qs[n-1])) #~ else: #~ cells.append('') #~ cells.append('') rows.append(cells) s += rstgen.table(headers, rows) return s
def sql_summary(lines, show_times=False, show_details=False, **options): """Parse the SQL queries from `lines` and print a summary. `lines` is an iterable of text lines from a logfile or from :func:`lino.api.doctest.show_sql_summary`. Any backticks and double quotes are removed for readability. MySQL uses backticks where SQLite uses double quotes around table and field names in the SQL syntax. `Here <https://stackoverflow.com/questions/11321491/when-to-use-single-quotes-double-quotes-and-backticks-in-mysql>`__ is an interesting discussion with examples. """ # matches = [] d = {} for l in lines: l = l.replace('"', '') l = l.replace('`', '') m = re.match(regex, l) # print m if m: g = m.groupdict() g['time'] = float(g['time']) r = d.setdefault(g['table'], {}) r['count'] = r.get('count', 0) + 1 r["total_time"] = r.get("total_time", 0) + float(g['time']) if r.get('time', -1) < g['time']: d[g['table']].update(g) else: print("Invalid line {!r}".format(l)) if d: if show_details: for kw in sorted(d.values(), key=lambda x: x['total_time']): p(kw, **options) print("-------------------") print("The slowest SQL call was:") #find max kw = d[max(d, key=lambda x: float(d[x].get('time', 0)))] p(kw, **options) print("-------------------") else: if show_times: headers = 'total_time count table time'.split() values = sorted(d.values(), key=lambda x: -x['total_time']) else: headers = 'table count'.split() values = sorted(d.values(), key=lambda x: x['table']) rows = [] for kw in values: rows.append([kw[h] for h in headers]) print(rstgen.table(headers, rows)) else: print("No sql queries found")
def show_choicelist(cls): """ Similar to :func:`rt.show`, but the `text` is shown in all languages instead of just the current language. """ headers = ["value", "name"] + [lng.name for lng in settings.SITE.languages] rows = [] for i in cls.get_list_items(): row = [i.value, i.name] + str2languages(i.text) rows.append(row) print(table(headers, rows))
def show_fields(model, fieldnames=None, columns=False, all=None): """ Print an overview description of the specified fields of the specified model. If model is an action or table, print the parameter fields of that action or table. If model is a table and you want the columns instead of the parameter fields, then specify `columns=True`. By default this shows only fields which have a help text. If you specify `all=True`, then also fields that have no help text will be shown. """ cells = [] cols = ["Internal name", "Verbose name", "Help text"] if all is None: all = fieldnames is not None if isinstance(model, BoundAction): get_field = model.action.parameters.get if fieldnames is None: fieldnames = model.action.params_layout elif isinstance(model, Action): get_field = model.parameters.get if fieldnames is None: fieldnames = model.params_layout.main elif issubclass(model, Model): get_field = model._meta.get_field # get_field = model.get_data_elem if fieldnames is None: fieldnames = [f.name for f in model._meta.get_fields()] elif issubclass(model, AbstractTable): if columns: get_field = model.get_data_elem if fieldnames is None: fieldnames = model.column_names # get_handle().list_layout.main.columns else: get_field = model.parameters.get if fieldnames is None: fieldnames = model.params_layout.main if isinstance(fieldnames, six.string_types): fieldnames = fieldnames.split() for n in fieldnames: fld = get_field(n) if fld is not None and hasattr(fld, 'verbose_name'): ht = fld.help_text or '' if ht or all: cells.append([n, fld.verbose_name, unindent(ht)]) print(table(cols, cells).strip())
def get_rst(self): #~ print 'MainBlogIndexDirective.get_rst()' #~ env = self.state.document.settings.env #~ print self.arguments, self.options, self.content left = '\n'.join(self.content) right = '' for arg in self.arguments[0].split(): right += '.. figure:: %s\n' % arg for i in list(self.options.items()): right += " :%s: %s\n" % i right += "\n %s\n\n" % arg #~ right += "\n \n\n" % arg return rstgen.table(["", ""], [[left, right]], show_headers=False)
def doit(): cells = [] cols = ["Action name", "Verbose name", "Help text", "Target state", "Required states"] # , "Required roles"] for a in actions: ht = a.help_text or '' if ht or all: # required_roles = ' '.join( # [str(r) for r in a.required_roles]) cells.append( [a.action_name, a.label, unindent(ht), a.target_state, a.required_states or '', # required_roles ]) print(table(cols, cells).strip())
def show_db_overview(self): """Return a reStructredText-formatted "database overview" report. Used by test cases in tested documents. """ from lino.core.utils import (full_model_name, sorted_models_list) models_list = sorted_models_list() apps = [p.app_label for p in settings.SITE.installed_plugins] s = "%d apps: %s." % (len(apps), ", ".join(apps)) s += "\n%d models:\n" % len(models_list) i = 0 headers = [ #~ "No.", "Name", "Default table", #~ "M", "#fields", "#rows", #~ ,"first","last" ] rows = [] for model in models_list: if True: # model._meta.managed: i += 1 cells = [] #~ cells.append(str(i)) cells.append(full_model_name(model)) cells.append(model.get_default_table()) #~ cells.append(str(model)) #~ if model._meta.managed: #~ cells.append('X') #~ else: #~ cells.append('') cells.append(str(len(model._meta.concrete_fields))) qs = model.objects.all() n = qs.count() cells.append(str(n)) #~ if n: #~ cells.append(obj2str(qs[0])) #~ cells.append(obj2str(qs[n-1])) #~ else: #~ cells.append('') #~ cells.append('') rows.append(cells) s += rstgen.table(headers, rows) return s
def fields_table(fields): headers = ["name", "type"] #~ formatters = [ #~ lambda f: f.name, #~ lambda f: f.__class__.__name__, #~ ] headers.append("verbose name") headers.append("help text") def rowfmt(f): cells = [f.name, fieldtype(f), f.verbose_name, f.help_text] #~ for lng in babel.AVAILABLE_LANGUAGES: #~ babel.set_language(lng) #~ cells.append(force_unicode(_(f.verbose_name))) #~ cells.append(f.help_text) return cells rows = [rowfmt(f) for f in fields if not hasattr(f, '_lino_babel_field')] return rstgen.table(headers, rows)
def fields_table(fields): headers = ["name", "type"] #~ formatters = [ #~ lambda f: f.name, #~ lambda f: f.__class__.__name__, #~ ] headers.append("verbose name") headers.append("help text") def rowfmt(f): cells = [ f.name, fieldtype(f), f.verbose_name, f.help_text ] #~ for lng in babel.AVAILABLE_LANGUAGES: #~ babel.set_language(lng) #~ cells.append(force_text(_(f.verbose_name))) #~ cells.append(f.help_text) return cells rows = [rowfmt(f) for f in fields if not hasattr(f, '_lino_babel_field')] return rstgen.table(headers, rows)
def sql_summary(lines, show_times=False, show_details=False, **options): """ Parse the SQL queries from `lines` and print a summary. `lines` is an iterable of text lines from a logfile or from :func:`lino.api.doctest.show_sql_summary`. Any backticks and double quotes are removed for readability. MySQL uses backticks where SQLite uses double quotes around table and field names in the SQL syntax. `Here <https://stackoverflow.com/questions/11321491/when-to-use-single-quotes-double-quotes-and-backticks-in-mysql>`__ is an interesting discussion with examples. """ if sqlparse is None: raise Exception("sql_summary() requires the sqlparse package") # matches = [] d = {} for l in lines: l = l.replace('"', '') l = l.replace('`', '') m = re.match(regex, l) if m: g = m.groupdict() entry = Entry(g['sql'], g['time']) k = entry.group_key() if k in d: d[k].collect(entry) else: d[k] = entry else: raise Exception("Invalid line {!r}".format(l)) # k = None # for op, regex in operations: # m = re.match(regex, l) # if m: # g = m.groupdict() # k = g['table'] + op # g['operation'] = op # break # if k: # g['time'] = float(g['time']) # r = d.setdefault(k, {}) # r['count'] = r.get('count', 0) + 1 # r["total_time"] = r.get("total_time", 0 ) + float(g['time']) # if r.get('time', -1) < g['time']: # d[k].update(g) # else: # raise Exception("Invalid line {!r}".format(l)) if d: if show_details: for e in sorted(d.values(), key=lambda x: x.total_time): p(e, **options) print("-------------------") print("The slowest SQL call was:") # find max e = d[max(d, key=lambda x: x.time)] p(e, **options) print("-------------------") else: if show_times: headers = 'total_time count table stmt_type time'.split() values = sorted(d.values(), key=lambda x: -x.total_time) else: headers = 'table stmt_type count'.split() values = sorted(d.values(), key=lambda x: x.table) rows = [] for e in values: rows.append([getattr(e, h) for h in headers]) rows.sort() print(rstgen.table(headers, rows)) else: print("No sql queries found")