Beispiel #1
0
    def show_memo_commands(self, doctestfmt=False):
        rst = ""
        mp = settings.SITE.plugins.memo.parser
        items = []
        for cmd, func in sorted(mp.commands.items()):
            doc = unindent(func.__doc__ or '')
            if doc:
                # doc = doc.splitlines()[0]
                items.append("[{0} ...] : {1}".format(cmd, doc))

        # rst += "\n**Commands**"
        # rst += rstgen.boldheader("Commands")
        rst += rstgen.ul(items)

        if False:
            items = []
            for model, func in sorted(mp.renderers.items()):
                doc = unindent(func.__doc__ or '')
                if doc:
                    items.append("[{0} ...] : {1}".format(model, doc))
            if len(items):
                rst += "\n**Renderers**"
                rst += rstgen.ul(items)

        return rst
Beispiel #2
0
    def get_rst(self):
        user_type = UserTypes.get_by_value('900')
        with translation.override(self.language):
            #~ set_language(lng)
            actor_names = ' '.join(self.content).split()
            items = []
            for an in actor_names:
                cls = settings.SITE.models.resolve(an)
                if not isinstance(cls, type):
                    raise Exception("%s is not an actor." % self.content[0])
                desc = "**{0}** (:class:`{1} <{2}>`)".format(
                    force_text(cls.label),
                    cls.__name__,
                    cls.__module__ + '.' + cls.__name__
                )
                mi = user_type.find_menu_item(cls.default_action)
                if mi is not None:
                    desc += _(" (Menu %s)") % menuselection(mi)
                    #~ print(str(mi.label).strip())
                if cls.help_text:
                    desc += "  : " + force_text(cls.help_text).strip()

                # items.append("%s : %s" % (actor_ref(cls), cls.help_text or ''))
                items.append(desc)
            return rstgen.ul(items)
Beispiel #3
0
def fields_ul(fields):
    helpless = []

    def field2li(fld):
        s = "**%s**" % str(f.verbose_name).strip()
        s += " (``%s``, %s)" % (f.name, fieldtype(f))
        if f.help_text:
            s += " -- " + str(f.help_text)
            return s
        helpless.append(s)
        return None

    items = []
    for f in fields:
        if not hasattr(f, '_lino_babel_field'):
            s = field2li(f)
            if s:
                items.append(s)
    #~ items = [ field2li(f) for f in fields if not hasattr(f,'_lino_babel_field')]
    if len(helpless):
        s = ', '.join(helpless)
        if len(items):
            s = _("... and %s") % s
        items.append(s)
    return rstgen.ul(items)
Beispiel #4
0
    def doit(ar):
        if ar is None:
            user_type = None
        else:
            user_type = ar.user.user_type
            test_client.force_login(ar.user)
        mnu = settings.SITE.get_site_menu(user_type)
        items = []
        for mi in mnu.walk_items():
            if mi.bound_action:
                if isinstance(mi.bound_action.action, ShowTable):
                    mt = mi.bound_action.actor
                    url = 'api/{}/{}'.format(mt.app_label, mt.__name__)
                    url = str(settings.SITE.buildurl(url, fmt='json'))

                    item = menuselection_text(mi) + " : "
                    try:
                        response = test_client.get(url,
                                                   REMOTE_USER=str(username))
                        result = check_json_result(
                            response, None,
                            "GET %s for user %s" % (url, username))
                        item += str(result['count'])
                    except Exception as e:
                        if severe:
                            raise
                        else:
                            item += str(e)
                    items.append(item)

        s = rstgen.ul(items)
        print(s)
Beispiel #5
0
    def show_window_permissions(self):
        self.analyze()
        items = []
        for ba in analyzer.window_actions:
            items.append("{0} : visible for {1}".format(
                ba.full_name(), visible_for(ba)))

        return rstgen.ul(items)
Beispiel #6
0
def commited_today(ctx, today=None):
    """Print all today's commits to stdout."""
    from git import Repo

    list_options = dict()
    if True:
        today = get_current_date(today)
        ONEDAY = timedelta(days=1)
        yesterday = today - ONEDAY
        tomorrow = today + ONEDAY
        list_options.update(after=yesterday.strftime("%Y-%m-%d"),
                            before=tomorrow.strftime("%Y-%m-%d"))
    if False:
        list_options.update(max_count=5)

    rows = []

    def load(prj):

        # prj.load_info()
        # repo = Repo(cfg['root_dir'])
        repo = Repo(prj.root_dir)

        it = list(repo.iter_commits(**list_options))
        if len(it) == 0:
            # print("20160816 no commits in {}".format(prj.nickname))
            return

        def fmtcommit(c):

            url = repo.remotes.origin.url
            if url.startswith("*****@*****.**"):
                url = "https://github.com/" + url[15:-4] \
                      + "/commit/" + c.hexsha
            elif url.startswith("git+ssh://[email protected]"):
                url = "https://github.com/" + url[25:-4] \
                      + "/commit/" + c.hexsha

            s = "`{0} <{1}>`__".format(c.hexsha[-7:], url)
            # if c.message and not c.message.startswith("http://"):
            s += "\n({})".format(c.message.strip())
            return s

        # url = prj.SETUP_INFO.get('url', "oops")
        # desc = "`%s <%s>`__" % (prj.name, url)
        desc = "*{}*".format(prj.nickname)

        for c in it:
            # ts = time.strftime("%H:%M", time.gmtime(c.committed_date))
            ts = time.strftime("%Y-%m-%d %H:%M",
                               time.localtime(c.committed_date))
            rows.append([ts, desc, fmtcommit(c)])

    for p in git_projects():
        load(p)

    rows.sort(key=lambda a: a[0])
    print(rstgen.ul(["{0} in {1}:\n{2}".format(*row) for row in rows]))
Beispiel #7
0
    def show_window_fields(self):
        """List all window actions and the form fields they contain.
        """
        self.analyze()
        items = []
        for ba in analyzer.window_actions:
            items.append("{0} : {1}".format(ba.full_name(), layout_fields(ba)))

        return rstgen.ul(items)
Beispiel #8
0
    def show_action_permissions(self, *classes):
        self.analyze()
        items = []
        for ba in analyzer.custom_actions + analyzer.window_actions:
            if isinstance(ba.action, classes):
                items.append("{0} : visible for {1}".format(
                    ba.full_name(), visible_for(ba)))

        return rstgen.ul(items)
Beispiel #9
0
    def show_dialog_actions(self, doctestfmt=False):
        self.analyze()
        items = []
        for ba in analyzer.custom_actions + analyzer.window_actions:
            # if ba.action.parameters and not ba.action.no_params_window:
            if ba.action.parameters:
                items.append("{0} : {1}".format(ba.full_name(),
                                                py2rst(ba.action, doctestfmt)))

        print(rstgen.ul(items))
Beispiel #10
0
    def show_foreign_keys(self):
        """Return a list that shows how database objects are being referred to
        by some other database object. This information is important
        (1) before deleting objects and (2) when merging them.

        For every model we see a list of "delete handlers" and a list
        of fields from other models that point to this model using
        that delete handler.

        Delete handlers are:

        - PROTECT : refuse to delete when other objects refer to this object
        - CASCADE : delete objects refering to this object
        - set_on_delete : make other objects point to something else (or set
          their pointer to None)

        """
        self.analyze()
        tdp = dict()  # target model -> delete handler -> pointer list
        for target in get_models():
            dp = tdp.setdefault(target, dict())
            for m, fk in target._lino_ddh.fklist:
                k = fk.remote_field.on_delete
                p = dp.setdefault(k, [])
                p.append((m, fk))

        def fk2str(mfk):
            return "{0}.{1}".format(fmn(mfk[0]), mfk[1].name)

        items1 = []
        for target, dp in list(tdp.items()):
            items2 = []
            for dh, pl in list(dp.items()):
                items2.append("{0} : {1}".format(
                    dh.__name__, ', '.join([fk2str(mfk) for mfk in pl])))
            if len(items2):
                items2 = sorted(items2)
                items1.append("{0} :\n{1}".format(fmn(target),
                                                  rstgen.ul(items2)))

        items1 = sorted(items1)
        return rstgen.ul(items1)
Beispiel #11
0
def actions_ul(action_list):
    items = []
    for ba in action_list:
        label = ba.action.label
        desc = "**%s** (" % str(label).strip()
        if ba.action.action_name:
            desc += "``%s``" % ba.action.action_name

        desc += ", %s)" % typeref(ba.action.__class__)
        if ba.action.help_text:
            desc += " -- " + str(ba.action.help_text)
        items.append(desc)
    return rstgen.ul(items)
Beispiel #12
0
    def show_database_structure(self):
        """Show a bullet list of all models and their fields."""
        self.analyze()
        items = []
        for model in get_models():
            names = []
            # for f, m in model._meta.get_fields_with_model():
            for f in model._meta.concrete_fields:
                names.append(f.name)
            items.append("{0} : {1}".format(fmn(model), ', '.join(names)))

        items = sorted(items)
        return rstgen.ul(items)
Beispiel #13
0
 def show_fields(self, model, field_names=None, languages=None):
     model = dd.resolve_model(model)
     if field_names is not None:
         field_names = dd.fields_list(model, field_names)
     items = []
     for f in model._meta.fields:
         if field_names is None or f.name in field_names:
             name = f.name
             ref = model.__module__ + '.' + model.__name__ + '.' + name
             verbose_name = force_text(f.verbose_name).strip()
             help_text = force_text(f.help_text).replace('\n', ' ')
             txt = "**{verbose_name}** (:attr:`{name} <{ref}>`) : " \
                   "{help_text}".format(**locals())
             items.append(txt)
     return rstgen.ul(items)
Beispiel #14
0
def show_fields_by_type(fldtype):
    """Print a list of all fields (in all models) that have the specified type.
    """
    from lino.core.utils import (sorted_models_list)
    items = []
    for model in sorted_models_list():
        flds = []
        for f in model._meta.fields:
            if isinstance(f, fldtype):
                name = f.name
                verbose_name = force_text(f.verbose_name).strip()
                txt = "{verbose_name} ({name})".format(**locals())
                flds.append(txt)
        if len(flds):
            txt = "{model} : {fields}".format(model=full_model_name(model),
                                              fields=", ".join(flds))
            items.append(txt)
    print(rstgen.ul(items))
Beispiel #15
0
def actors_overview_ul(model_reports):
    user_type = UserTypes.get_by_value('900')
    # deprecated
    items = []
    for tb in model_reports:
        desc = actor_ref(tb)
        #~ label = str(tb.title or tb.label)
        #~ desc += " (%s)" % str(tb)
        desc += " (%s)" % typeref(tb)
        # mi = find_menu_item(tb.default_action)
        mi = user_type.find_menu_item(tb.default_action)
        if mi is not None:
            desc += _(" (Menu %s)") % menuselection(mi)
            #~ print(unicode(mi.label).strip())
        if tb.help_text:
            desc += " -- " + str(tb.help_text).strip()

        items.append(desc)
    return rstgen.ul(items)
Beispiel #16
0
    def menu2rst(self, ar, mnu, level=1):
        """Used by :meth:`show_menu`."""

        if not isinstance(mnu, Menu):
            return str(mnu.label)

        has_submenus = False
        for i in mnu.items:
            if isinstance(i, Menu):
                has_submenus = True
        items = [self.menu2rst(ar, mi, level + 1) for mi in mnu.items]
        if has_submenus:
            s = rstgen.ul(items).strip() + '\n'
            if mnu.label is not None:
                s = str(mnu.label) + ' :\n\n' + s
        else:
            s = ', '.join(items)
            if mnu.label is not None:
                s = str(mnu.label) + ' : ' + s
        return s
Beispiel #17
0
def show_excerpts(severe=True):
    ses = rt.login()
    # dd.logger.info("20141029 %s", settings.SITE)
    coll = {}

    def collect(obj):
        l = coll.setdefault(obj.excerpt_type, [])
        mf = obj.build_method.get_target(None, obj)
        tmppath = Path(mf.name)
        if tmppath.exists():
            tail = tmppath.name
            tail = 'dl/excerpts/' + tail
            kw = dict(tail=tail)
            kw.update(type=obj.excerpt_type)
            kw.update(owner=obj.owner)
            try:
                # dd.logger.info("20141029 copy %s to %s", tmppath, tail)
                shutil.copyfile(tmppath, tail)
            except IOError as e:
                kw.update(error=str(e))
                msg = "%(type)s %(owner)s %(tail)s Oops: %(error)s" % kw
                # raise Exception(msg)
                kw.update(owner=msg)

            l.append(kw)

    for o in rt.models.excerpts.Excerpt.objects.order_by('excerpt_type'):
        collect(o)

    def asli(et, items):
        s = str(et)
        s += " : " + ', '.join("`%(owner)s <../%(tail)s>`__" % kw % kw
                               for kw in items)
        return s

    return rstgen.ul([asli(k, v) for k, v in coll.items()])
Beispiel #18
0
def py2rst(self, doctestfmt=False, fmt=None):
    """
    Return a textual representation of the given Python object as a
    reStructuredText bullet list.

    The Python object can be a layout, a layout element, an action or a
    database object.

    If it is an action, it must have parameters, and py2rst will render the
    params_layout.

    If it is a database object, you will get  a textual representation of a
    detail window on that object.

    If the optional argument `doctestfmt` is specified as `True`, then
    output contains less blank lines, which might be invalid
    reStructuredText but is more doctest-friendly.

    TODO: move this functionality to lino.api.doctests and rename it to
    something that reflects better what it does.

    """
    from lino.core.store import get_atomizer

    if isinstance(self, models.Model) and fmt is None:
        ar = self.get_default_table().request()

        def fmt(e):
            s = elem_label(e)
            if isinstance(e, FieldElement):
                sf = get_atomizer(self.__class__, e.field, e.field.name)
                getter = sf.full_value_from_object
                value = getter(self, ar)
                # value = e.value_from_object(self, None)
                if value is not None:
                    s += ": " + e.format_value(ar, value)
            return s

        dt = self.get_default_table()
        lh = dt.detail_layout.get_layout_handle()
        return py2rst(lh.main, doctestfmt, fmt)

    if isinstance(self, actions.Action):
        s = str(self)
        if self.params_layout:
            lh = self.params_layout.get_layout_handle(
                settings.SITE.kernel.default_ui)
            s += '\n'
            s += py2rst(lh.main, doctestfmt, fmt)
        return s

    if isinstance(self, BaseLayout):
        lh = self.get_layout_handle(settings.SITE.kernel.default_ui)
        return py2rst(lh.main, doctestfmt, fmt)

    if isinstance(self, Wrapper):
        self = self.wrapped

    if fmt is None:

        def fmt(e):
            s = elem_label(e)
            if visible_for(e) != visible_for(e.parent):
                s += " [visible for %s]" % visible_for(e)
            return s

    s = fmt(self)
    if isinstance(self, Container):
        use_ul = False
        for e in self.elements:
            if isinstance(e, Container):
                use_ul = True
        children = [py2rst(e, doctestfmt, fmt) for e in self.elements]
        if len(children):
            if use_ul:
                s += ':\n'
                if not doctestfmt:
                    s += '\n'
                s += rstgen.ul(children)
            else:
                s += ": " + ', '.join(children)

    return s
Beispiel #19
0
 def show_complexity_factors(self):
     return rstgen.ul(list(self.get_complexity_factors()))
Beispiel #20
0
    def get_rst(self):
        # return str(self.state.document.refnames)
        env = self.state.document.settings.env
        target = ' '.join(self.content).strip()
        if not target:
            target = env.temp_data['docname']
            # print("20140409 target is %r" % target)
        found = set()
        rows = set()

        # headers = 'children attributes \
        # resolved referenced indirect_reference_name \
        # tagname'.split()

        for docname in env.found_docs:
            if env.temp_data['docname'] == docname:  # skip myself
                continue

            try:
                doc = env.get_doctree(docname)
            except Exception:
                # 20140117 i had the following after a fab clean:
                #   File "/home/luc/pythonenvs/py27/local/lib/python2.7/site-packages/sphinx/environment.py", line 1077, in get_doctree
                #     f = open(doctree_filename, 'rb')
                # IOError: [Errno 2] No such file or directory: u'/home/luc/hgwork/lino/docs/.build/.doctrees/topics/names.doctree'

                continue

            # print("20140115 traversing", docname)
            for ref in doc.traverse(addnodes.pending_xref):
                if ref['reftype'] == 'doc':
                    other = docname_join(ref['refdoc'], ref['reftarget'])
                else:
                    other = ref['reftarget']
                if other == target:
                    found.add(ref['refdoc'])
                    # print("20140409 found", ref)
                else:
                    # rows.add(ref['reftarget'])
                    rows.add(other)
                    # rows.add(repr(ref.attributes))
                    # row = []
                    # for h in headers:
                    #     row.append(py2rst(getattr(ref, h, 'N/A')))
                    # rows.append(unicode(row))
    
        if len(found) == 0:
            s = """No documents found for target %r.""" % target
            # s += """\nPending xrefs were %r.""" % rows
            return s

        entries = []
        for refdoc in found:
            mtime = path.getmtime(env.doc2path(refdoc))
            entries.append((mtime, refdoc))
    
        def f(a):
            return a[0]
        entries.sort(key=f)
        entries.reverse()
    
        import time
        # from time import strftime
    
        items = [':doc:`/%(doc)s` (%(time)s)' % dict(
            time=time.ctime(e[0]),
            doc=e[1]) for e in entries]

        if 'debug' in self.options:
            items.append("DEBUG: pending xrefs were %r." % rows)

        return rstgen.ul(items)