Exemple #1
0
def page(photon, content, sub=None):
    from os import path
    from photon.util.locations import search_location, change_location
    from photon.util.system import get_timestamp, get_hostname

    settings = photon.settings.get
    pwd = path.dirname(__file__)

    out = path.join(settings['web']['output'], sub if sub else '', 'index.html')
    search_location(out, create_in=path.dirname(out))

    if sub: prfx, sub = '../', '— %s' %(sub)
    else:
        prfx, sub = './', ''
        change_location(path.join(pwd, 'static'), path.join(settings['web']['output'], 'static'))

    template = photon.template_handler(
        path.join(pwd, 'main.tpl'),
        fields=dict(
            hostname=get_hostname(),
            prfx=prfx,
            sub=sub,
            content=content,
            timestamp=get_timestamp()
        )
    )
    template.write(out, append=False)
Exemple #2
0
def page(photon, content, sub=None):
    '''
    Helps creating webpages by placing the **content** into the ``main.tpl``
    and write the output to ``web/output/`` **sub/** ``index.html``.
    '''

    settings = photon.settings.get
    pwd = path.dirname(__file__)

    out = path.join(settings['web']['output'], sub if sub else '',
                    'index.html')
    search_location(out, create_in=path.dirname(out))

    if sub:
        prfx, sub = '../', '— %s' % (sub)
    else:
        prfx, sub = './', ''
        change_location(path.join(pwd, 'static'),
                        path.join(settings['web']['output'], 'static'))

    template = photon.template_handler(path.join(pwd, 'main.tpl'),
                                       fields=dict(hostname=get_hostname(),
                                                   prfx=prfx,
                                                   sub=sub,
                                                   content=content,
                                                   timestamp=get_timestamp()))
    template.write(out, append=False)
Exemple #3
0
    def __init__(self, defaults, config='config.yaml', verbose=True):

        super().__init__()

        self.__verbose = verbose
        self.__settings = {'locations': get_locations(), 'files': dict()}

        loaders = [(
            '!str_join',
            yaml_str_join,
        ), (
            '!loc_join',
            yaml_loc_join,
        )]

        defaults, sdict = ('startup import', defaults) if isinstance(
            defaults, dict) else (search_location(defaults), None)

        if not self.load(
                'defaults', defaults, sdict=sdict, loaders=loaders,
                merge=True):
            shell_notify('could not load defaults',
                         state=True,
                         more=dict(defaults=defaults, sdict=sdict))

        if config:
            config = search_location(config, create_in='conf_dir')
            if self.__settings != self.load(
                    'config', config, loaders=loaders, merge=True,
                    writeback=True):
                shell_notify('settings config written',
                             more=config,
                             verbose=verbose)
Exemple #4
0
    def __init__(self, defaults, config='config.yaml', verbose=True):

        super().__init__()

        self.__verbose = verbose
        self.__settings = {
            'locations': get_locations(),
            'files': dict()
        }

        loaders = [
            ('!str_join', yaml_str_join,),
            ('!loc_join', yaml_loc_join,)
        ]

        defaults, sdict = (
            'startup import',
            defaults
        ) if isinstance(defaults, dict) else (
            search_location(defaults),
            None
        )

        if not self.load(
            'defaults',
            defaults,
            sdict=sdict,
            loaders=loaders,
            merge=True
        ):
            shell_notify(
                'could not load defaults',
                state=True,
                more=dict(defaults=defaults, sdict=sdict)
            )

        if config:
            config = search_location(config, create_in='conf_dir')
            if self.__settings != self.load(
                'config',
                config,
                loaders=loaders,
                merge=True,
                writeback=True
            ):
                shell_notify(
                    'settings config written',
                    more=config,
                    verbose=verbose
                )
Exemple #5
0
    def __init__(self, m, local, remote_url=None, mbranch=None):
        super().__init__()

        self.m = check_m(m)
        self.__local = search_location(local, create_in=local)
        self.__remote_url = remote_url
        if not mbranch:
            mbranch = 'master'
        self.__mbranch = mbranch

        if self.m(
            'checking for git repo',
            cmdd=dict(cmd='git rev-parse --show-toplevel', cwd=self.local),
            critical=False,
            verbose=False
        ).get('out') != self.local:
            if not self.remote_url:
                self.m(
                    'a new git clone without remote url is not possible.',
                    state=True,
                    more=dict(local=self.local)
                )
            self.m(
                'cloning into repo',
                cmdd=dict(
                    cmd='git clone %s %s' % (self.remote_url, self.local)
                )
            )

        self.m(
            'git tool startup done',
            more=dict(remote_url=self.remote_url, local=self.local),
            verbose=False
        )
Exemple #6
0
    def __init__(self, m, pid, sudo=True, cmdd_if_no_pid=None):
        super().__init__()

        self.m = check_m(m)

        pidfile = read_file(search_location(str(pid)))
        if pidfile and pidfile.strip().isdigit():
            pid = int(pidfile)

        if not isinstance(pid, int):
            if cmdd_if_no_pid:
                self.m('running post command',
                       cmdd=cmdd_if_no_pid,
                       critical=True)
            self.m('could not determine pid%s' %
                   (' from file' if pidfile else '!'),
                   more=dict(pid=pid, pidfile=pidfile),
                   state=True)

        self.__pid = pid
        self.__sudo = 'sudo' if sudo else ''

        self.m('signal tool startup done',
               more=dict(pid=self.__pid,
                         pidfile=pidfile if pidfile else 'passed directly'),
               verbose=False)
Exemple #7
0
    def stage(self, name, clean=False):
        '''
        Switch stage

        :param name:
            Filename of new meta file. |filelocate|

            * File must not already exist, will be created in 'data_dir' \
            from :func:`util.locations.get_locations`

            * Can also be a full path to place it anywhere desired

        :param clean: What to do with preexisting meta files?

            * ``False``: Merge current meta with preexisting one
            * ``True``: Replace preexisting meta with current one
        '''

        name = search_location(name, create_in='data_dir')
        if not clean:
            self.load('stage', name, merge=True)

        self.__meta['header'].update({'stage': name})
        self.log = shell_notify('%s stage' %
                                ('new clean' if clean else 'loaded'),
                                more=dict(meta=name, clean=clean),
                                verbose=self.__verbose)
Exemple #8
0
    def stage(self, name, clean=False):
        '''
        Switch stage

        :param name:
            Filename of new meta file. |filelocate|

            * File must not already exist, will be created in 'data_dir' \
            from :func:`util.locations.get_locations`

            * Can also be a full path to place it anywhere desired

        :param clean: What to do with preexisting meta files?

            * ``False``: Merge current meta with preexisting one
            * ``True``: Replace preexisting meta with current one
        '''

        name = search_location(name, create_in='data_dir')
        if not clean:
            self.load('stage', name, merge=True)

        self.__meta['header'].update({'stage': name})
        self.log = shell_notify(
            '%s stage' % ('new clean' if clean else 'loaded'),
            more=dict(meta=name, clean=clean),
            verbose=self.__verbose
        )
def pinit(mname, clean=False, verbose=True):
    '''
    Creates a new Photon instance and stages into common stage directory
    defined in :ref:`defaults`.
    It is some subfolder of the httpd-dir, so you can see what's going on
    while building.

    :param mname: |mname|
    :param clean: Starts a new meta file replacing the old one.
        Used in :func:`prepare`
    :param verbose: |verbose|
    :returns: a new :py:class:`photon.Photon` instance with it's
        :py:class:`settings.Settings` as tuple
    '''
    photon = _pinit(mname, verbose)
    settings = photon.settings.get

    if clean:
        change_location(settings['prepare']['stage_dir'], False, move=True)

    photon.meta.stage(
        search_location(
            'builder_meta.json',
            create_in=settings['prepare']['stage_dir']
        ),
        clean=clean
    )
    return photon, settings
Exemple #10
0
    def __init__(self, m, pid, sudo=True, cmdd_if_no_pid=None):
        super().__init__()

        self.m = check_m(m)

        pidfile = read_file(search_location(str(pid)))
        if pidfile and pidfile.strip().isdigit():
            pid = int(pidfile)

        if not isinstance(pid, int):
            if cmdd_if_no_pid:
                self.m(
                    'running post command',
                    cmdd=cmdd_if_no_pid,
                    critical=True
                )
            self.m(
                'could not determine pid%s' % (
                    ' from file' if pidfile else '!'
                ),
                more=dict(pid=pid, pidfile=pidfile),
                state=True
            )

        self.__pid = pid
        self.__sudo = 'sudo' if sudo else ''

        self.m(
            'signal tool startup done',
            more=dict(
                pid=self.__pid,
                pidfile=pidfile if pidfile else 'passed directly'
            ),
            verbose=False
        )
Exemple #11
0
    def __init__(self, m, local, remote_url=None, mbranch=None):
        super().__init__()

        self.m = check_m(m)
        self.__local = search_location(local, create_in=local)
        self.__remote_url = remote_url
        if not mbranch:
            mbranch = 'master'
        self.__mbranch = mbranch

        if self.m('checking for git repo',
                  cmdd=dict(cmd='git rev-parse --show-toplevel',
                            cwd=self.local),
                  critical=False,
                  verbose=False).get('out') != self.local:
            if not self.remote_url:
                self.m('a new git clone without remote url is not possible.',
                       state=True,
                       more=dict(local=self.local))
            self.m('cloning into repo',
                   cmdd=dict(cmd='git clone %s %s' %
                             (self.remote_url, self.local)))

        self.m('git tool startup done',
               more=dict(remote_url=self.remote_url, local=self.local),
               verbose=False)
def draw_traffic():
    from os import path
    from photon.util.locations import search_location
    from common import pinit
    from common.html import page

    photon, settings = pinit('draw_traffic', verbose=True)

    traffic = '<small>click to show or hide</small><br />'
    avail_if = photon.m(
        'checking for available interfaces',
        cmdd=dict(
            cmd='sudo vnstat --iflist'
        )
    ).get('out', '')
    interfaces = settings['web']['traffic']['interfaces'] + [settings['fastd'][community]['interface'] for community in settings['fastd'].keys()]
    for interface in interfaces:
        if interface in avail_if:
            if not search_location(path.join(settings['web']['traffic']['dbdir'], interface)):
                photon.m(
                    'creating vnstat db for %s' %(interface),
                    cmdd=dict(
                        cmd='sudo vnstat -u -i %s' %(interface)
                    ),
                    verbose=True
                )

            images = ''
            for flag, itype in settings['web']['traffic']['types']:
                image = '%s-%s.png' %(interface, itype)
                photon.m(
                    'drawing %s graph for %s' %(itype, interface),
                    cmdd=dict(
                        cmd='vnstati -i %s -%s -o %s' %(interface, flag, path.join(settings['web']['output'], 'traffic', image))
                    ),
                    critical=False
                )

                images += photon.template_handler(
                    IMAGE,
                    fields=dict(
                        interface=interface,
                        itype=itype,
                        image=image
                    )
                ).sub

            traffic += photon.template_handler(
                IFBLOCK,
                fields=dict(
                    interface=interface,
                    images=images
                )
            ).sub

    page(photon, traffic, sub='traffic')
def gen_documentation():
    '''
    Pulls updates from our repositories containing (Sphinx) documentation,
    builds them, and on success copies over the generated files.

    You may or may not see the results on
    `rtfm.freifunk-mwu.de <http://rtfm.freifunk-mwu.de>`_,
    the mirrored repos are currently:

        :backend_scripts: https://github.com/freifunk-mwu/backend-scripts
        :gluon_builder: https://github.com/freifunk-mwu/gluon-builder-ffmwu
        :gluon_gateway: https://github.com/freifunk-mwu/technik-meta
        :photon: https://github.com/spookey/photon

    '''
    photon, settings = pinit('gen_documentation', verbose=True)
    result = {
        'build': {},
        'result': {},
        'update': {}
    }

    lroot = search_location(
        settings['documentation']['local'],
        create_in=settings['documentation']['local']
    )

    for name, data in settings['documentation']['repositories'].items():
        local = path.join(lroot, name)
        builddir = path.join(settings['documentation']['builddir'], name)
        outdir = path.join(settings['documentation']['output'], name)

        result['update'][name] = photon.git_handler(
            local,
            remote_url=data['remote']
        )._pull()

        build = photon.m(
            'building documentation for %s' % (name),
            cmdd=dict(
                cmd='sphinx-build -a -b html %s %s' % (
                    path.join(local, data['docpath']),
                    builddir
                )
            ),
            critical=False
        )
        result['build'][name] = build
        if build.get('returncode') == 0:
            change_location(outdir, False, move=True)
            change_location(builddir, outdir, move=True)
            result['result'] = photon.m('build for %s successful')

    photon.m('all done', more=result)
Exemple #14
0
    def __init__(self, m, template, fields=None):
        super().__init__()

        self.m = check_m(m)

        tfile = search_location(template)

        self.__template = read_file(tfile) if tfile else template
        self.__fields = fields

        self.m('template tool startup done',
               more=dict(fields=self.__fields, file=tfile),
               verbose=False)
Exemple #15
0
def draw_traffic():
    '''
    Draws `vnstat <http://humdi.net/vnstat/>`_  Graphs, and glues them
    into a Webseite.

    Run only on machines which are connected to the mesh (Gateways,
    Service-Machines).

    * If a specified interface does not exist on this machine, it's skipped.
    * If no vnstat database was found for one interface, it will be created.
    '''
    photon, settings = pinit('draw_traffic', verbose=True)

    traffic = '<small>click to show or hide</small><br />'
    avail_if = photon.m('checking for available interfaces',
                        cmdd=dict(cmd='sudo vnstat --iflist')).get('out', '')

    interfaces = settings['web']['traffic']['interfaces'] + [
        settings['fastd'][com]['interface']
        for com in settings['common']['communities']
    ]
    for interface in interfaces:
        if interface in avail_if:
            if not search_location(
                    path.join(settings['web']['traffic']['dbdir'], interface)):
                photon.m('creating vnstat db for %s' % (interface),
                         cmdd=dict(cmd='sudo vnstat -u -i %s' % (interface)),
                         verbose=True)

            images = ''
            for flag, itype in settings['web']['traffic']['types']:
                image = '%s-%s.png' % (interface, itype)
                photon.m('drawing %s graph for %s' % (itype, interface),
                         cmdd=dict(cmd='vnstati -i %s -%s -o %s' %
                                   (interface, flag,
                                    path.join(settings['web']['output'],
                                              'traffic', image))),
                         critical=False)

                images += photon.template_handler(IMAGE,
                                                  fields=dict(
                                                      interface=interface,
                                                      itype=itype,
                                                      image=image)).sub

            traffic += photon.template_handler(IFBLOCK,
                                               fields=dict(interface=interface,
                                                           images=images)).sub

    page(photon, traffic, sub='traffic')
Exemple #16
0
    def __init__(self, m, template, fields=None):
        super().__init__()

        self.m = check_m(m)

        tfile = search_location(template)

        self.__template = read_file(tfile) if tfile else template
        self.__fields = fields

        self.m(
            'template tool startup done',
            more=dict(fields=self.__fields, file=tfile),
            verbose=False
        )
Exemple #17
0
def page(photon, content, sub=None):
    '''
    Helps creating webpages by placing the **content** into the ``main.tpl``
    and write the output to ``web/output/`` **sub/** ``index.html``.
    '''

    settings = photon.settings.get
    pwd = path.dirname(__file__)

    out = path.join(
        settings['web']['output'],
        sub if sub else '',
        'index.html'
    )
    search_location(out, create_in=path.dirname(out))

    if sub:
        prfx, sub = '../', '&mdash; %s' % (sub)
    else:
        prfx, sub = './', ''
        change_location(
            path.join(pwd, 'static'),
            path.join(settings['web']['output'], 'static')
        )

    template = photon.template_handler(
        path.join(pwd, 'main.tpl'),
        fields=dict(
            hostname=get_hostname(),
            prfx=prfx,
            sub=sub,
            content=content,
            timestamp=get_timestamp()
        )
    )
    template.write(out, append=False)
Exemple #18
0
    def getpub_ssh():
        if not search_location(settings['crypt']['ssh']['prv']):
            mkprv_ssh()

        pub = photon.m(
            'generating new public ssh key from private',
            cmdd=dict(
                cmd='ssh-keygen -f %s -y' % (settings['crypt']['ssh']['prv']),
                cwd=settings['crypt']['ssh']['folder']
            )
        )
        if not pub.get('returncode') == 0:
            photon.m('Error creating public ssh key', state=False)

        if read_file(settings['crypt']['ssh']['pub']) != pub.get('out'):
            write_file(settings['crypt']['ssh']['pub'], pub.get('out'))
            photon.m('wrote public ssh key', more=pub)

        return pub.get('out')
def gen_documentation():
    '''
    Pulls updates from our repositories containing (Sphinx) documentation,
    builds them, and on success copies over the generated files.

    You may or may not see the results on
    `rtfm.freifunk-mwu.de <http://rtfm.freifunk-mwu.de>`_,
    the mirrored repos are currently:

        :backend_scripts: https://github.com/freifunk-mwu/backend-scripts
        :gluon_builder: https://github.com/freifunk-mwu/gluon-builder-ffmwu
        :gluon_gateway: https://github.com/freifunk-mwu/technik-meta
        :photon: https://github.com/spookey/photon

    '''
    photon, settings = pinit('gen_documentation', verbose=True)
    result = {'build': {}, 'result': {}, 'update': {}}

    lroot = search_location(settings['documentation']['local'],
                            create_in=settings['documentation']['local'])

    for name, data in settings['documentation']['repositories'].items():
        local = path.join(lroot, name)
        builddir = path.join(settings['documentation']['builddir'], name)
        outdir = path.join(settings['documentation']['output'], name)

        result['update'][name] = photon.git_handler(
            local, remote_url=data['remote'])._pull()

        build = photon.m(
            'building documentation for %s' % (name),
            cmdd=dict(cmd='sphinx-build -a -b html %s %s' %
                      (path.join(local, data['docpath']), builddir)),
            critical=False)
        result['build'][name] = build
        if build.get('returncode') == 0:
            change_location(outdir, False, move=True)
            change_location(builddir, outdir, move=True)
            result['result'] = photon.m('build for %s successful')

    photon.m('all done', more=result)
Exemple #20
0
def gen_expansion_map():
    '''
    This script generates several expansion-maps.

    It pulls updates first, generates a map, patches assets, and then
    copies over the generated files.

    A common ``app.chache`` file is used for all builds, for speedup reasons.

    When finished, it leaves the clean repo behind.
    '''
    photon, settings = pinit('gen_expansion_map')

    # fetch updates from remote repository
    git = photon.git_handler(settings['expansion']['local'],
                             remote_url=settings['expansion']['remote'])
    git._pull()

    for name, sub in settings['expansion']['maps'].items():
        # generate map
        build = photon.m(
            'generate %s expansion map' % (name),
            cmdd=dict(
                cmd='./mkpoly -f nodelist %s' % (sub['url']),
                cwd=settings['expansion']['local'],
                timeout=600,  # for initial run, only (to create app.cache)
            ))
        if build.get('returncode') == 0:
            for patch in settings['expansion']['patch']:
                content = read_file(patch)
                if not content:
                    # skip empty files
                    continue
                # set title
                content = re_sub(r'<title>(.*?)</title>',
                                 '<title>%s</title>' % (sub['title']), content)
                # set description
                content = re_sub(
                    r'this._div.innerHTML\ =\ \'<h4>(.*?)</h4>\'',
                    'this._div.innerHTML = \'<h4>%s</h4>\'' % (sub['descr']),
                    content)
                # set initial position
                content = re_sub(
                    r'L\.map\(\'map\'\)\.setView\((.*?),\ 10\);',
                    'L.map(\'map\').setView([%s, %s], 10);' %
                    (sub['ipos'][0], sub['ipos'][1]), content)
                # save result
                photon.m('written %d bytes into %s' %
                         (write_file(patch, content), patch))

            # copy generated files & folders
            search_location(sub['output'], create_in=sub['output'])
            for folder in ['js', 'css']:
                change_location(path.join(settings['expansion']['local'],
                                          folder),
                                path.join(sub['output'], folder),
                                move=False)
            for fdoc in ['nodes.geojson', 'index.html', 'LICENSE']:
                change_location(path.join(settings['expansion']['local'],
                                          fdoc),
                                sub['output'],
                                move=False)

        # reset changed files
        for reset in settings['expansion']['patch'] + [
                path.join(settings['expansion']['local'], 'nodes.geojson')
        ]:
            photon.m('clean up %s' % (reset))
            git._checkout('-- %s' % (reset))
def gen_expansion_map():
    '''
    This script generates several expansion-maps.

    It pulls updates first, generates a map, patches assets, and then
    copies over the generated files.

    A common ``app.chache`` file is used for all builds, for speedup reasons.

    When finished, it leaves the clean repo behind.
    '''
    photon, settings = pinit('gen_expansion_map')

    # fetch updates from remote repository
    git = photon.git_handler(
        settings['expansion']['local'],
        remote_url=settings['expansion']['remote']
    )
    git._pull()

    for name, sub in settings['expansion']['maps'].items():
        # generate map
        build = photon.m(
            'generate %s expansion map' % (name),
            cmdd=dict(
                cmd='./mkpoly -f nodelist %s' % (sub['url']),
                cwd=settings['expansion']['local'],
                timeout=600,  # for initial run, only (to create app.cache)
            )
        )
        if build.get('returncode') == 0:
            for patch in settings['expansion']['patch']:
                content = read_file(patch)
                if not content:
                    # skip empty files
                    continue
                # set title
                content = re_sub(
                    r'<title>(.*?)</title>',
                    '<title>%s</title>' % (sub['title']),
                    content
                )
                # set description
                content = re_sub(
                    r'this._div.innerHTML\ =\ \'<h4>(.*?)</h4>\'',
                    'this._div.innerHTML = \'<h4>%s</h4>\'' % (sub['descr']),
                    content
                )
                # set initial position
                content = re_sub(
                    r'L\.map\(\'map\'\)\.setView\((.*?),\ 10\);',
                    'L.map(\'map\').setView([%s, %s], 10);' % (
                        sub['ipos'][0], sub['ipos'][1]
                    ),
                    content
                )
                # save result
                photon.m('written %d bytes into %s' % (
                    write_file(patch, content),
                    patch
                ))

            # copy generated files & folders
            search_location(sub['output'], create_in=sub['output'])
            for folder in ['js', 'css']:
                change_location(
                    path.join(settings['expansion']['local'], folder),
                    path.join(sub['output'], folder),
                    move=False
                )
            for fdoc in ['nodes.geojson', 'index.html', 'LICENSE']:
                change_location(
                    path.join(settings['expansion']['local'], fdoc),
                    sub['output'],
                    move=False
                )

        # reset changed files
        for reset in settings['expansion']['patch'] + [
            path.join(settings['expansion']['local'], 'nodes.geojson')
        ]:
            photon.m('clean up %s' % (reset))
            git._checkout('-- %s' % (reset))