<commit_before># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import collections
import flask_login
import logging
import time

import re
import rest

from sqlalchemy import and_
from sqlalchemy import desc
from sqlalchemy import func
from sqlalchemy import not_
from sqlalchemy import or_

from flask import Blueprint
from flask import g
from flask import request
from flask import url_for
from flask.ext.login import current_user

from models import Build
from models import ClobberTime
from models import DB_DECLARATIVE_BASE

from relengapi import apimethod
from relengapi.lib import angular
from relengapi.lib import api

logger = logging.getLogger(__name__)

bp = Blueprint(
    'clobberer',
    __name__,
    template_folder='templates',
    static_folder='static'
)

bp.root_widget_template('clobberer_root_widget.html', priority=100)

# prefix which denotes release builddirs
BUILDDIR_REL_PREFIX = 'rel-'
BUILDER_REL_PREFIX = 'release-'

@bp.route('/')
@bp.route('/<string:branch>')
@flask_login.login_required
def root(branch=None):
    return angular.template(
        'clobberer.html',
        url_for('.static', filename='clobberer.js'),
        url_for('.static', filename='clobberer.css'),
        branches=api.get_data(branches),
        selected_branch=branch
    )

def _add_clobber(session, branch, builddir, slave=None):
    """
    A common method for adding clobber times to a session. The session passed
    in is returned; but is only committed if the commit option is True.
    """
    if re.search('^' + BUILDDIR_REL_PREFIX + '.*', builddir) is None:
        who = 'anonymous'
        if current_user.anonymous is False:
            who = current_user.authenticated_email
        clobber_time = ClobberTime.as_unique(
            session,
            branch=branch,
            builddir=builddir,
            slave=slave,
        )
        clobber_time.lastclobber = int(time.time())
        clobber_time.who = who
        session.add(clobber_time)
        return None
    logger.debug('Rejecting clobber of builddir with release prefix: {}'.format(
        builddir))
    return None

@bp.route('/clobber', methods=['POST'])
@apimethod(None, body=[rest.ClobberRequest])
def clobber(body):
    "Request clobbers for particular branches and builddirs."
    session = g.db.session(DB_DECLARATIVE_BASE)
    for clobber in body:
        _add_clobber(
            session,
            branch=clobber.branch,
            builddir=clobber.builddir,
            slave=clobber.slave
        )
    session.commit()
    return None

@bp.route('/clobber/by-builder', methods=['POST'])
@apimethod(None, body=[rest.ClobberRequestByBuilder])
def clobber_by_builder(body):
    """
    Request clobbers for app builddirs associated with a particular buildername.
    """
    session = g.db.session(DB_DECLARATIVE_BASE)
    for clobber in body:
        builddirs_query = session.query(Build.builddir, Build.branch).filter(
            Build.buildername == clobber.buildername
        )
        if clobber.branch is not None:
            builddirs_query = builddirs_query.filter(Build.branch == clobber.branch)

        for result in builddirs_query.distinct():
            _add_clobber(
                session,
                builddir=result[0],
                branch=result[1],
                slave=clobber.slave
            )
    session.commit()
    return None

@bp.route('/branches')
@apimethod([unicode])
def branches():
    "Return a list of all the branches clobberer knows about."
    session = g.db.session(DB_DECLARATIVE_BASE)
    branches = session.query(Build.branch).distinct()
    # Users shouldn't see any branch associated with a release builddir
    branches = branches.filter(not_(Build.builddir.startswith(BUILDDIR_REL_PREFIX)))
    branches = branches.order_by(Build.branch)
    return [branch[0] for branch in branches]

@bp.route('/lastclobber/all', methods=['GET'])
@apimethod([rest.ClobberTime])
def lastclobber_all():
    "Return a sorted list of all clobbers"
    session = g.db.session(DB_DECLARATIVE_BASE)
    return session.query(ClobberTime).order_by(ClobberTime.lastclobber)

@bp.route('/lastclobber/branch/by-builder/<string:branch>', methods=['GET'])
@apimethod({unicode: [rest.ClobberTime]}, unicode)
def lastclobber_by_builder(branch):
    "Return a dictionary of most recent ClobberTimes grouped by buildername."
    session = g.db.session(DB_DECLARATIVE_BASE)

    # Isolates the maximum lastclobber for each builddir on a branch
    max_ct_sub_query = session.query(
        func.max(ClobberTime.lastclobber).label('lastclobber'),
        ClobberTime.builddir,
        ClobberTime.branch
    ).group_by(
        ClobberTime.builddir,
        ClobberTime.branch
    ).filter(ClobberTime.branch == branch).subquery()

    # Finds the "greatest n per group" by joining with the max_ct_sub_query
    # This is necessary to get the correct "who" values
    sub_query = session.query(ClobberTime).join(max_ct_sub_query, and_(
        ClobberTime.builddir == max_ct_sub_query.c.builddir,
        ClobberTime.lastclobber == max_ct_sub_query.c.lastclobber,
        ClobberTime.branch == max_ct_sub_query.c.branch)).subquery()

    # Attaches builddirs, along with their max lastclobber to a buildername
    full_query = session.query(
        Build.buildername,
        Build.builddir,
        sub_query.c.lastclobber,
        sub_query.c.who
    ).outerjoin(
        sub_query,
        Build.builddir == sub_query.c.builddir,
    ).filter(
        Build.branch == branch,
        not_(Build.buildername.startswith(BUILDER_REL_PREFIX))
        ).distinct().order_by(Build.buildername)

    summary = collections.defaultdict(list)
    for result in full_query:
        buildername, builddir, lastclobber, who = result
        summary[buildername].append(
            rest.ClobberTime(
                branch=branch,
                builddir=builddir,
                lastclobber=lastclobber,
                who=who
            )
        )
    return summary

@bp.route('/lastclobber', methods=['GET'])
def lastclobber():
    "Get the max/last clobber time for a particular builddir and branch."

    session = g.db.session(DB_DECLARATIVE_BASE)
    now = int(time.time())
    branch = request.args.get('branch')
    slave = request.args.get('slave')
    builddir = request.args.get('builddir')
    buildername = request.args.get('buildername')
    # TODO: Move the builds update to a separate endpoint (requires client changes)
    build = Build.as_unique(
        session,
        branch=branch,
        builddir=builddir,
        buildername=buildername,
    )
    # Always force the time to update
    build.last_build_time = now
    session.add(build)
    session.commit()

    max_ct = session.query(ClobberTime).filter(
        ClobberTime.builddir == builddir,
        ClobberTime.branch == branch,
        # a NULL slave value signifies all slaves
        or_(ClobberTime.slave == slave, ClobberTime.slave == None)  # noqa
    ).order_by(desc(ClobberTime.lastclobber)).first()

    if max_ct:
        # The client parses this result by colon as:
        # builddir, lastclobber, who = urlib2.open.split(':')
        # as such it's important for this to be plain text and have
        # no extra colons within the field values themselves
        return "{}:{}:{}\n".format(max_ct.builddir, max_ct.lastclobber, max_ct.who)
    return ""

@bp.route('/forceclobber', methods=['GET'])
def forceclobber():
    """
    Coerce the client to clobber by always returning a future clobber time.
    This works because the client decides to clobber based on a timestamp
    comparison.
    """
    future_time = int(time.time()) + 3600
    builddir = request.args.get('builddir')
    return "{}:{}:forceclobber".format(builddir, future_time)

_ROR = "https://github.com/mozilla/build-relengapi-clobberer"
_ISSUE_URL = "%s/issues" % _ROR

# See <relengapi>/docs/development/@relengapi/blueprints/#project-metadata
data = {
    "repository_of_record": _ROR,
    "bug_report_url": _ISSUE_URL,
}
<commit_msg>s/data/metadata/ from typo<commit_after># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import collections
import flask_login
import logging
import time

import re
import rest

from sqlalchemy import and_
from sqlalchemy import desc
from sqlalchemy import func
from sqlalchemy import not_
from sqlalchemy import or_

from flask import Blueprint
from flask import g
from flask import request
from flask import url_for
from flask.ext.login import current_user

from models import Build
from models import ClobberTime
from models import DB_DECLARATIVE_BASE

from relengapi import apimethod
from relengapi.lib import angular
from relengapi.lib import api

logger = logging.getLogger(__name__)

bp = Blueprint(
    'clobberer',
    __name__,
    template_folder='templates',
    static_folder='static'
)

bp.root_widget_template('clobberer_root_widget.html', priority=100)

# prefix which denotes release builddirs
BUILDDIR_REL_PREFIX = 'rel-'
BUILDER_REL_PREFIX = 'release-'

@bp.route('/')
@bp.route('/<string:branch>')
@flask_login.login_required
def root(branch=None):
    return angular.template(
        'clobberer.html',
        url_for('.static', filename='clobberer.js'),
        url_for('.static', filename='clobberer.css'),
        branches=api.get_data(branches),
        selected_branch=branch
    )

def _add_clobber(session, branch, builddir, slave=None):
    """
    A common method for adding clobber times to a session. The session passed
    in is returned; but is only committed if the commit option is True.
    """
    if re.search('^' + BUILDDIR_REL_PREFIX + '.*', builddir) is None:
        who = 'anonymous'
        if current_user.anonymous is False:
            who = current_user.authenticated_email
        clobber_time = ClobberTime.as_unique(
            session,
            branch=branch,
            builddir=builddir,
            slave=slave,
        )
        clobber_time.lastclobber = int(time.time())
        clobber_time.who = who
        session.add(clobber_time)
        return None
    logger.debug('Rejecting clobber of builddir with release prefix: {}'.format(
        builddir))
    return None

@bp.route('/clobber', methods=['POST'])
@apimethod(None, body=[rest.ClobberRequest])
def clobber(body):
    "Request clobbers for particular branches and builddirs."
    session = g.db.session(DB_DECLARATIVE_BASE)
    for clobber in body:
        _add_clobber(
            session,
            branch=clobber.branch,
            builddir=clobber.builddir,
            slave=clobber.slave
        )
    session.commit()
    return None

@bp.route('/clobber/by-builder', methods=['POST'])
@apimethod(None, body=[rest.ClobberRequestByBuilder])
def clobber_by_builder(body):
    """
    Request clobbers for app builddirs associated with a particular buildername.
    """
    session = g.db.session(DB_DECLARATIVE_BASE)
    for clobber in body:
        builddirs_query = session.query(Build.builddir, Build.branch).filter(
            Build.buildername == clobber.buildername
        )
        if clobber.branch is not None:
            builddirs_query = builddirs_query.filter(Build.branch == clobber.branch)

        for result in builddirs_query.distinct():
            _add_clobber(
                session,
                builddir=result[0],
                branch=result[1],
                slave=clobber.slave
            )
    session.commit()
    return None

@bp.route('/branches')
@apimethod([unicode])
def branches():
    "Return a list of all the branches clobberer knows about."
    session = g.db.session(DB_DECLARATIVE_BASE)
    branches = session.query(Build.branch).distinct()
    # Users shouldn't see any branch associated with a release builddir
    branches = branches.filter(not_(Build.builddir.startswith(BUILDDIR_REL_PREFIX)))
    branches = branches.order_by(Build.branch)
    return [branch[0] for branch in branches]

@bp.route('/lastclobber/all', methods=['GET'])
@apimethod([rest.ClobberTime])
def lastclobber_all():
    "Return a sorted list of all clobbers"
    session = g.db.session(DB_DECLARATIVE_BASE)
    return session.query(ClobberTime).order_by(ClobberTime.lastclobber)

@bp.route('/lastclobber/branch/by-builder/<string:branch>', methods=['GET'])
@apimethod({unicode: [rest.ClobberTime]}, unicode)
def lastclobber_by_builder(branch):
    "Return a dictionary of most recent ClobberTimes grouped by buildername."
    session = g.db.session(DB_DECLARATIVE_BASE)

    # Isolates the maximum lastclobber for each builddir on a branch
    max_ct_sub_query = session.query(
        func.max(ClobberTime.lastclobber).label('lastclobber'),
        ClobberTime.builddir,
        ClobberTime.branch
    ).group_by(
        ClobberTime.builddir,
        ClobberTime.branch
    ).filter(ClobberTime.branch == branch).subquery()

    # Finds the "greatest n per group" by joining with the max_ct_sub_query
    # This is necessary to get the correct "who" values
    sub_query = session.query(ClobberTime).join(max_ct_sub_query, and_(
        ClobberTime.builddir == max_ct_sub_query.c.builddir,
        ClobberTime.lastclobber == max_ct_sub_query.c.lastclobber,
        ClobberTime.branch == max_ct_sub_query.c.branch)).subquery()

    # Attaches builddirs, along with their max lastclobber to a buildername
    full_query = session.query(
        Build.buildername,
        Build.builddir,
        sub_query.c.lastclobber,
        sub_query.c.who
    ).outerjoin(
        sub_query,
        Build.builddir == sub_query.c.builddir,
    ).filter(
        Build.branch == branch,
        not_(Build.buildername.startswith(BUILDER_REL_PREFIX))
        ).distinct().order_by(Build.buildername)

    summary = collections.defaultdict(list)
    for result in full_query:
        buildername, builddir, lastclobber, who = result
        summary[buildername].append(
            rest.ClobberTime(
                branch=branch,
                builddir=builddir,
                lastclobber=lastclobber,
                who=who
            )
        )
    return summary

@bp.route('/lastclobber', methods=['GET'])
def lastclobber():
    "Get the max/last clobber time for a particular builddir and branch."

    session = g.db.session(DB_DECLARATIVE_BASE)
    now = int(time.time())
    branch = request.args.get('branch')
    slave = request.args.get('slave')
    builddir = request.args.get('builddir')
    buildername = request.args.get('buildername')
    # TODO: Move the builds update to a separate endpoint (requires client changes)
    build = Build.as_unique(
        session,
        branch=branch,
        builddir=builddir,
        buildername=buildername,
    )
    # Always force the time to update
    build.last_build_time = now
    session.add(build)
    session.commit()

    max_ct = session.query(ClobberTime).filter(
        ClobberTime.builddir == builddir,
        ClobberTime.branch == branch,
        # a NULL slave value signifies all slaves
        or_(ClobberTime.slave == slave, ClobberTime.slave == None)  # noqa
    ).order_by(desc(ClobberTime.lastclobber)).first()

    if max_ct:
        # The client parses this result by colon as:
        # builddir, lastclobber, who = urlib2.open.split(':')
        # as such it's important for this to be plain text and have
        # no extra colons within the field values themselves
        return "{}:{}:{}\n".format(max_ct.builddir, max_ct.lastclobber, max_ct.who)
    return ""

@bp.route('/forceclobber', methods=['GET'])
def forceclobber():
    """
    Coerce the client to clobber by always returning a future clobber time.
    This works because the client decides to clobber based on a timestamp
    comparison.
    """
    future_time = int(time.time()) + 3600
    builddir = request.args.get('builddir')
    return "{}:{}:forceclobber".format(builddir, future_time)

_ROR = "https://github.com/mozilla/build-relengapi-clobberer"
_ISSUE_URL = "%s/issues" % _ROR

# See <relengapi>/docs/development/@relengapi/blueprints/#project-metadata
metadata = {
    "repository_of_record": _ROR,
    "bug_report_url": _ISSUE_URL,
}
<|endoftext|>


<commit_before># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# XXX Much of this functionality should probably be its own
#     Separate relengapi blueprint

from __future__ import absolute_import

import structlog
from bzrest.client import BugzillaClient
from flask import current_app
from flask import url_for

log = structlog.get_logger()

MAX_ALIAS = 15
DEFAULT_BUGZILLA_URL = "https://bugzilla-dev.allizom.org/rest/"

def init_app(app):
    bzurl = app.config.get('BUGZILLA_URL', DEFAULT_BUGZILLA_URL)
    if not app.config.get('BUGZILLA_API_KEY', None):
        log.warning("No bugzilla api key specified. (Set BUGZILLA_API_KEY in config to fix)")
    bzclient = BugzillaClient()
    bzclient.configure(bzurl=bzurl,
                       apikey=app.config.get('BUGZILLA_API_KEY', None))
    app.bzclient = bzclient

class Bug(object):
    alias = None
    id = None

    def __init__(self, id_=None, loadInfo=True):
        if isinstance(id_, int):
            self.id = id_
        else:
            self.alias = id_
        self.data = {}
        if id_ and loadInfo:
            self.refresh()

    @property
    def id_(self):
        return self.id or self.alias

    def refresh(self):
        self.data = current_app.bzclient.get_bug(self.id_)
        self.id = self.data["id"]
        self.alias = self.data["alias"]

    def add_comment(self, comment, data={}):
        return current_app.bzclient.add_comment(self.id_, comment, data)

class ProblemTrackingBug(Bug):
    product = "Release Engineering"
    component = "Buildduty"

    def __init__(self, slave_name, *args, **kwargs):
        self.slave_name = slave_name
        Bug.__init__(self, id_=slave_name, *args, **kwargs)

    def create(self, comment=None, depends_on=None):
        if len(self.slave_name) > MAX_ALIAS:
            alias = None
        else:
            alias = self.slave_name
        data = {
            "product": self.product,
            "component": self.component,
            "summary": "%s problem tracking" % self.slave_name,
            "version": "other",
            "alias": alias,
            # todo: do we care about setting these correctly?
            "op_sys": "All",
            "platform": "All"
        }
        if comment:
            data['comment'] = comment
        if depends_on:
            data['depends_on'] = depends_on
        resp = current_app.bzclient.create_bug(data)
        self.id = resp["id"]

class LoanerBug(Bug):
    product = "Release Engineering"
    component = "Loan Requests"

    def __init__(self, *args, **kwargs):
        Bug.__init__(self, *args, **kwargs)

    def create(self, summary=None, comment=None, blocks=None):
        data = {
            "product": self.product,
            "component": self.component,
            "summary": summary,
            "version": "other",
            # todo: do we care about setting these correctly?
            "op_sys": "All",
            "platform": "All"
        }
        if comment:
            data['comment'] = comment
        if blocks:
            data['blocks'] = blocks
        resp = current_app.bzclient.create_bug(data)
        self.id = resp["id"]
        return self

LOAN_SUMMARY = u"Loan a slave of {slavetype} to {human}"
COMMENT_ZERO = u"""{human} is in need of a slaveloan from slavetype {slavetype}

(this bug was auto-created from the slaveloan tool)
{loan_url}"""

def create_loan_bug(loan_id=None, slavetype=None, bugzilla_username=None):
    if None in (loan_id, slavetype, bugzilla_username):
        raise ValueError("Missing arguments")

    summary = LOAN_SUMMARY.format(slavetype=slavetype,
                                  human=bugzilla_username)
    c_zero = COMMENT_ZERO.format(
        slavetype=slavetype,
        human=bugzilla_username,
        loan_url=url_for("slaveloan.loan_details", id=loan_id))
    loan_bug = LoanerBug(loadInfo=False)
    bug = loan_bug.create(comment=c_zero, summary=summary)
    return bug.id
<commit_msg>updated loan_url by pointing to https instead of http for bugzilla comments<commit_after># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# XXX Much of this functionality should probably be its own
#     Separate relengapi blueprint

from __future__ import absolute_import

import structlog
from bzrest.client import BugzillaClient
from flask import current_app
from flask import url_for

log = structlog.get_logger()

MAX_ALIAS = 15
DEFAULT_BUGZILLA_URL = "https://bugzilla-dev.allizom.org/rest/"

def init_app(app):
    bzurl = app.config.get('BUGZILLA_URL', DEFAULT_BUGZILLA_URL)
    if not app.config.get('BUGZILLA_API_KEY', None):
        log.warning("No bugzilla api key specified. (Set BUGZILLA_API_KEY in config to fix)")
    bzclient = BugzillaClient()
    bzclient.configure(bzurl=bzurl,
                       apikey=app.config.get('BUGZILLA_API_KEY', None))
    app.bzclient = bzclient

class Bug(object):
    alias = None
    id = None

    def __init__(self, id_=None, loadInfo=True):
        if isinstance(id_, int):
            self.id = id_
        else:
            self.alias = id_
        self.data = {}
        if id_ and loadInfo:
            self.refresh()

    @property
    def id_(self):
        return self.id or self.alias

    def refresh(self):
        self.data = current_app.bzclient.get_bug(self.id_)
        self.id = self.data["id"]
        self.alias = self.data["alias"]

    def add_comment(self, comment, data={}):
        return current_app.bzclient.add_comment(self.id_, comment, data)

class ProblemTrackingBug(Bug):
    product = "Release Engineering"
    component = "Buildduty"

    def __init__(self, slave_name, *args, **kwargs):
        self.slave_name = slave_name
        Bug.__init__(self, id_=slave_name, *args, **kwargs)

    def create(self, comment=None, depends_on=None):
        if len(self.slave_name) > MAX_ALIAS:
            alias = None
        else:
            alias = self.slave_name
        data = {
            "product": self.product,
            "component": self.component,
            "summary": "%s problem tracking" % self.slave_name,
            "version": "other",
            "alias": alias,
            # todo: do we care about setting these correctly?
            "op_sys": "All",
            "platform": "All"
        }
        if comment:
            data['comment'] = comment
        if depends_on:
            data['depends_on'] = depends_on
        resp = current_app.bzclient.create_bug(data)
        self.id = resp["id"]

class LoanerBug(Bug):
    product = "Release Engineering"
    component = "Loan Requests"

    def __init__(self, *args, **kwargs):
        Bug.__init__(self, *args, **kwargs)

    def create(self, summary=None, comment=None, blocks=None):
        data = {
            "product": self.product,
            "component": self.component,
            "summary": summary,
            "version": "other",
            # todo: do we care about setting these correctly?
            "op_sys": "All",
            "platform": "All"
        }
        if comment:
            data['comment'] = comment
        if blocks:
            data['blocks'] = blocks
        resp = current_app.bzclient.create_bug(data)
        self.id = resp["id"]
        return self

LOAN_SUMMARY = u"Loan a slave of {slavetype} to {human}"
COMMENT_ZERO = u"""{human} is in need of a slaveloan from slavetype {slavetype}

(this bug was auto-created from the slaveloan tool)
{loan_url}"""

def create_loan_bug(loan_id=None, slavetype=None, bugzilla_username=None):
    if None in (loan_id, slavetype, bugzilla_username):
        raise ValueError("Missing arguments")

    summary = LOAN_SUMMARY.format(slavetype=slavetype,
                                  human=bugzilla_username)
    c_zero = COMMENT_ZERO.format(
        slavetype=slavetype,
        human=bugzilla_username,
        loan_url=url_for("slaveloan.loan_details", id=loan_id, _scheme="https", _external=True))
    loan_bug = LoanerBug(loadInfo=False)
    bug = loan_bug.create(comment=c_zero, summary=summary)
    return bug.id
<|endoftext|>


<commit_before>#!/usr/bin/env python

import os
import sys

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import appindicator

import pulsectl

class PulseCardXLink(object):

    cards = {}
    xlinks = {}

    def __init__(self):

        self.pa = pulsectl.Pulse('PulseAudio Card XLink')

        self.ai = appindicator.Indicator(
            'pa-card-xlink',
            'audio-headset',
            appindicator.CATEGORY_HARDWARE)
        self.ai.set_status(appindicator.STATUS_ACTIVE)

        # create a menu
        menu = gtk.Menu()

        self.default_device_menu = gtk.MenuItem('Default device')
        menu.append(self.default_device_menu)
        self.default_device_menu.connect('activate', self.default_device_activate)
        self.default_device_menu.show()
        self.default_device_menu.set_submenu(gtk.Menu())

        self.xlink_devices_menu = gtk.MenuItem('Cross links')
        menu.append(self.xlink_devices_menu)
        self.xlink_devices_menu.connect('activate', self.xlink_devices_activate)
        self.xlink_devices_menu.show()
        self.xlink_devices_menu.set_submenu(gtk.Menu())

        item = gtk.SeparatorMenuItem()
        menu.append(item)
        item.show()

        item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        menu.append(item)
        item.connect('activate', self.quit_activate)
        item.show()

        self.ai.set_menu(menu)

    def quit_activate(self, w):
        #print 'exit indicator'
        gtk.main_quit()

    def default_device_activate(self, w):
        self.refresh_cards()

        #submenu = gtk.Menu()
        submenu = w.get_submenu()
        for child in submenu.get_children():
            submenu.remove(child)

        # populate devices menu
        for card in self.cards.values():
            #print 'default:', card.index, card.display_name
            self.add_card_to_menu(submenu, card, self.card_set_as_default_activate, card.index)

        w.set_submenu(submenu)

    def xlink_devices_activate(self, w):
        self.refresh_cards()

        #submenu = gtk.Menu()
        submenu = w.get_submenu()
        for child in submenu.get_children():
            submenu.remove(child)

        # populate devices menu
        for card in self.cards.values():
            #print 'xlink:', card.index, card.display_name
            item = self.add_card_to_menu(submenu, card, self.card_xlink_with_activate, card.index)
            item.set_submenu(gtk.Menu())

        if len(self.xlinks):
            item = gtk.SeparatorMenuItem()
            submenu.append(item)
            item.show()

        for xlink in self.xlinks:
            props = self.xlinks[xlink]

            item = gtk.MenuItem(props[2])

            submenu.append(item)
            item.connect('activate', self.xlink_drop_activate, xlink)
            item.show()

        w.set_submenu(submenu)

    def card_xlink_with_activate(self, w, ci):
        self.refresh_cards()
        if ci not in self.cards:
            return
        card = self.cards[ci]

        #submenu = gtk.Menu()
        submenu = w.get_submenu()
        for child in submenu.get_children():
            submenu.remove(child)

        for c in self.cards.values():
            if c.index == card.index:
                continue

            xlink = (card.index, c.index)
            if (c.index, card.index) < xlink:
                xlink = (c.index, card.index)
            if xlink in self.xlinks.keys():
                continue

            #print 'xlink with:', c.index, c.display_name
            self.add_card_to_menu(submenu, c, self.xlink_activate, xlink)

        w.set_submenu(submenu)

    def card_set_as_default_activate(self, w, ci):
        self.refresh_cards()
        if ci not in self.cards:
            return
        card = self.cards[ci]

        for source in self.pa.source_list():
            if source.card == card.index and not source.monitor_of_sink_name:
                self.pa.default_set(source)
                break

        for sink in self.pa.sink_list():
            if sink.card == card.index:
                self.pa.default_set(sink)
                break

    def xlink_activate(self, w, xlink):
        self.refresh_cards()
        if xlink[0] not in self.cards:
            return
        if xlink[1] not in self.cards:
            return
        card_a = self.cards[xlink[0]]
        card_b = self.cards[xlink[1]]

        card_a_source = None
        card_b_source = None

        for source in self.pa.source_list():
            if source.card == card_a.index and not card_a_source and not source.monitor_of_sink_name:
                card_a_source = source
            if source.card == card_b.index and not card_b_source and not source.monitor_of_sink_name:
                card_b_source = source

        card_a_sink = None
        card_b_sink = None

        for sink in self.pa.sink_list():
            if sink.card == card_a.index and not card_a_sink:
                card_a_sink = sink
            if sink.card == card_b.index and not card_b_sink:
                card_b_sink = sink

        loop_a_b = None
        if card_a_source and card_b_sink:
            loop_a_b = self.pa.module_load('module-loopback',
                    ('latency_msec=1',
                    'source=%s' % (card_a_source.name,),
                    'sink=%s' % (card_b_sink.name,),
                    'source_dont_move=on',
                    'sink_dont_move=on'))

        loop_b_a = None
        if card_b_source and card_a_sink:
            loop_b_a = self.pa.module_load('module-loopback',
                    ('latency_msec=1',
                    'source=%s' % (card_b_source.name,),
                    'sink=%s' % (card_a_sink.name,)))

        if (loop_a_b, loop_b_a) == (None, None):
            return

        if loop_a_b is not None and loop_b_a is None:
            name = card_a.display_name + ' > ' + card_b.display_name
        elif loop_a_b is None and loop_b_a is not None:
            name = card_a.display_name + ' < ' + card_b.display_name
        else: #loop_a_b is not None and loop_b_a is not None
            name = card_a.display_name + ' x ' + card_b.display_name

        self.xlinks[xlink] = (loop_a_b, loop_b_a, name)

    def xlink_drop_activate(self, w, xlink):
        self.refresh_cards()
        if xlink not in self.xlinks:
            return
        xlink_props = self.xlinks.pop(xlink)

        if xlink_props[0] is not None:
            self.pa.module_unload(xlink_props[0])
        if xlink_props[1] is not None:
            self.pa.module_unload(xlink_props[1])

    def add_card_to_menu(self, menu, card, action, *args):

        card.icon_name = None
        if 'device.icon_name' in card.proplist.keys():
            card.icon_name = '-'.join(card.proplist['device.icon_name'].split('-')[:-1])

        item = gtk.ImageMenuItem()
        item.set_label(card.display_name)
        if card.icon_name:
            image = gtk.image_new_from_icon_name(card.icon_name, gtk.ICON_SIZE_MENU)
            item.set_image(image)
            item.set_always_show_image(True)

        menu.append(item)
        item.connect('activate', action, *args)
        item.show()

        return item

    def refresh_cards(self):
        self.cards = {}

        for card in self.pa.card_list():
            name = card.name
            if 'device.product.name' in card.proplist.keys():
                name = card.proplist['device.product.name']
            if 'alsa.long_card_name' in card.proplist.keys():
                name = card.proplist['alsa.long_card_name']
            if 'alsa.card_name' in card.proplist.keys():
                name = card.proplist['alsa.card_name']
            card.display_name = name
            self.cards[card.index] = card
            #print card.index, name

        # drop xlinks, for cards which do not exists anymore
        for xlink in self.xlinks:
            if xlink[0] in self.cards and xlink[1] in self.cards:
                continue

            props = self.xlinks.pop(xlink)
            if xlink_props[0] is not None:
                self.pa.module_unload(props[0])
            if xlink_props[1] is not None:
                self.pa.module_unload(props[1])

if __name__ == '__main__':
    i = PulseCardXLink()

    try:
        gtk.main()
    except:
        pass
<commit_msg>Move also runnning apps to the new default device.<commit_after>#!/usr/bin/env python

import os
import sys

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import appindicator

import pulsectl

class PulseCardXLink(object):

    cards = {}
    xlinks = {}

    def __init__(self):

        self.pa = pulsectl.Pulse('PulseAudio Card XLink')

        self.ai = appindicator.Indicator(
            'pa-card-xlink',
            'audio-headset',
            appindicator.CATEGORY_HARDWARE)
        self.ai.set_status(appindicator.STATUS_ACTIVE)

        # create a menu
        menu = gtk.Menu()

        self.default_device_menu = gtk.MenuItem('Default device')
        menu.append(self.default_device_menu)
        self.default_device_menu.connect('activate', self.default_device_activate)
        self.default_device_menu.show()
        self.default_device_menu.set_submenu(gtk.Menu())

        self.xlink_devices_menu = gtk.MenuItem('Cross links')
        menu.append(self.xlink_devices_menu)
        self.xlink_devices_menu.connect('activate', self.xlink_devices_activate)
        self.xlink_devices_menu.show()
        self.xlink_devices_menu.set_submenu(gtk.Menu())

        item = gtk.SeparatorMenuItem()
        menu.append(item)
        item.show()

        item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        menu.append(item)
        item.connect('activate', self.quit_activate)
        item.show()

        self.ai.set_menu(menu)

    def quit_activate(self, w):
        #print 'exit indicator'
        gtk.main_quit()

    def default_device_activate(self, w):
        self.refresh_cards()

        #submenu = gtk.Menu()
        submenu = w.get_submenu()
        for child in submenu.get_children():
            submenu.remove(child)

        # populate devices menu
        for card in self.cards.values():
            #print 'default:', card.index, card.display_name
            self.add_card_to_menu(submenu, card, self.card_set_as_default_activate, card.index)

        w.set_submenu(submenu)

    def xlink_devices_activate(self, w):
        self.refresh_cards()

        #submenu = gtk.Menu()
        submenu = w.get_submenu()
        for child in submenu.get_children():
            submenu.remove(child)

        # populate devices menu
        for card in self.cards.values():
            #print 'xlink:', card.index, card.display_name
            item = self.add_card_to_menu(submenu, card, self.card_xlink_with_activate, card.index)
            item.set_submenu(gtk.Menu())

        if len(self.xlinks):
            item = gtk.SeparatorMenuItem()
            submenu.append(item)
            item.show()

        for xlink in self.xlinks:
            props = self.xlinks[xlink]

            item = gtk.MenuItem(props[2])

            submenu.append(item)
            item.connect('activate', self.xlink_drop_activate, xlink)
            item.show()

        w.set_submenu(submenu)

    def card_xlink_with_activate(self, w, ci):
        self.refresh_cards()
        if ci not in self.cards:
            return
        card = self.cards[ci]

        #submenu = gtk.Menu()
        submenu = w.get_submenu()
        for child in submenu.get_children():
            submenu.remove(child)

        for c in self.cards.values():
            if c.index == card.index:
                continue

            xlink = (card.index, c.index)
            if (c.index, card.index) < xlink:
                xlink = (c.index, card.index)
            if xlink in self.xlinks.keys():
                continue

            #print 'xlink with:', c.index, c.display_name
            self.add_card_to_menu(submenu, c, self.xlink_activate, xlink)

        w.set_submenu(submenu)

    def card_set_as_default_activate(self, w, ci):
        self.refresh_cards()
        if ci not in self.cards:
            return
        card = self.cards[ci]

        for source in self.pa.source_list():
            if source.card == card.index and not source.monitor_of_sink_name:
                self.pa.default_set(source)
                for source_output in self.pa.source_output_list():
                    if 'application.id' in source_output.proplist and \
                        source_output.proplist['application.id'] in [
                            'org.PulseAudio.pavucontrol',
                            'org.gnome.VolumeControl',
                            'org.mate.VolumeControl',
                            'org.kde.kmixd']:
                        continue
                    self.pa.source_output_move(source_output.index, source.index)
                break

        for sink in self.pa.sink_list():
            if sink.card == card.index:
                self.pa.default_set(sink)
                for sink_input in self.pa.sink_input_list():
                    self.pa.sink_input_move(sink_input.index, sink.index)
                break

    def xlink_activate(self, w, xlink):
        self.refresh_cards()
        if xlink[0] not in self.cards:
            return
        if xlink[1] not in self.cards:
            return
        card_a = self.cards[xlink[0]]
        card_b = self.cards[xlink[1]]

        card_a_source = None
        card_b_source = None

        for source in self.pa.source_list():
            if source.card == card_a.index and not card_a_source and not source.monitor_of_sink_name:
                card_a_source = source
            if source.card == card_b.index and not card_b_source and not source.monitor_of_sink_name:
                card_b_source = source

        card_a_sink = None
        card_b_sink = None

        for sink in self.pa.sink_list():
            if sink.card == card_a.index and not card_a_sink:
                card_a_sink = sink
            if sink.card == card_b.index and not card_b_sink:
                card_b_sink = sink

        loop_a_b = None
        if card_a_source and card_b_sink:
            loop_a_b = self.pa.module_load('module-loopback',
                    ('latency_msec=1',
                    'source=%s' % (card_a_source.name,),
                    'sink=%s' % (card_b_sink.name,),
                    'source_dont_move=on',
                    'sink_dont_move=on'))

        loop_b_a = None
        if card_b_source and card_a_sink:
            loop_b_a = self.pa.module_load('module-loopback',
                    ('latency_msec=1',
                    'source=%s' % (card_b_source.name,),
                    'sink=%s' % (card_a_sink.name,)))

        if (loop_a_b, loop_b_a) == (None, None):
            return

        if loop_a_b is not None and loop_b_a is None:
            name = card_a.display_name + ' > ' + card_b.display_name
        elif loop_a_b is None and loop_b_a is not None:
            name = card_a.display_name + ' < ' + card_b.display_name
        else: #loop_a_b is not None and loop_b_a is not None
            name = card_a.display_name + ' x ' + card_b.display_name

        self.xlinks[xlink] = (loop_a_b, loop_b_a, name)

    def xlink_drop_activate(self, w, xlink):
        self.refresh_cards()
        if xlink not in self.xlinks:
            return
        xlink_props = self.xlinks.pop(xlink)

        if xlink_props[0] is not None:
            self.pa.module_unload(xlink_props[0])
        if xlink_props[1] is not None:
            self.pa.module_unload(xlink_props[1])

    def add_card_to_menu(self, menu, card, action, *args):

        card.icon_name = None
        if 'device.icon_name' in card.proplist.keys():
            card.icon_name = '-'.join(card.proplist['device.icon_name'].split('-')[:-1])

        item = gtk.ImageMenuItem()
        item.set_label(card.display_name)
        if card.icon_name:
            image = gtk.image_new_from_icon_name(card.icon_name, gtk.ICON_SIZE_MENU)
            item.set_image(image)
            item.set_always_show_image(True)

        menu.append(item)
        item.connect('activate', action, *args)
        item.show()

        return item

    def refresh_cards(self):
        self.cards = {}

        for card in self.pa.card_list():
            name = card.name
            if 'device.product.name' in card.proplist.keys():
                name = card.proplist['device.product.name']
            if 'alsa.long_card_name' in card.proplist.keys():
                name = card.proplist['alsa.long_card_name']
            if 'alsa.card_name' in card.proplist.keys():
                name = card.proplist['alsa.card_name']
            card.display_name = name
            self.cards[card.index] = card
            #print card.index, name

        # drop xlinks, for cards which do not exists anymore
        for xlink in self.xlinks:
            if xlink[0] in self.cards and xlink[1] in self.cards:
                continue

            props = self.xlinks.pop(xlink)
            if xlink_props[0] is not None:
                self.pa.module_unload(props[0])
            if xlink_props[1] is not None:
                self.pa.module_unload(props[1])

if __name__ == '__main__':
    i = PulseCardXLink()

    try:
        gtk.main()
    except:
        pass
<|endoftext|>


<commit_before>import os
import collections
import mistune
import re
import yaml
from pygments import highlight
from pygments.util import ClassNotFound
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
from slugify import slugify
from django.conf import settings
from django.contrib.staticfiles import finders

FRONT_MATTER_PATTERN = re.compile(r'^---\n(.*?\n)---', re.DOTALL)

class MarkdownRenderer(mistune.Renderer):
    """Custom Markdown to HTML renderer.
    """
    def __init__(self, formatter, bundlepath, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.bundlepath = bundlepath or ''
        self.formatter = formatter
        self.id_slugs = collections.defaultdict(lambda: 0)

    def header(self, text, level, raw=None):
        """Auto header ID from slug of text.
        """
        slug = slugify(text)
        if self.id_slugs[slug]:
            slug = '{slug}-{n}'.format(slug=slug, n=self.id_slugs[slug])
        self.id_slugs[slug] += 1
        return '<h{level} id="{id}">{text}</h{level}>\n'.format(
            level=level, text=text, id=slug,
        )

    def block_code(self, code, lang):
        """Implement syntax highlighting with Pygments.
        """
        try:
            lexer = get_lexer_by_name(lang)
        except ClassNotFound:
            return super().block_code(code, lang)
        return highlight(code, lexer, self.formatter)

    def image(self, src, title, text):
        """Implement local static file resolving.
        """
        src = self._resolve_asset_path(src)
        return super().image(src, title, text)

    def _resolve_asset_path(self, path):
        if path.startswith('javascript:'):  # Taken from mistune.
            return ''
        elif path.startswith('//') or '://' in path:    # Probably absolute.
            return path
        abspath = '/'.join([
            c.strip('/') for c in (
                '', settings.STATIC_URL, self.bundlepath, path,
            )
        ])
        return abspath

def markdown_to_html(path, style=None):
    """Renders given Markdown input to HTML.

    :path str: Static file path to a given post. The "post" should be a
        directory containing file ``text.md``.
    :prefix str: Prefix prepended to :path: when resolving static file path.
        Default is ``posts``.
    :return: HTML output, front-matter meta, and CSS. If no valid front-matter
        can be found, the second item returned will be an empty ``dict``.
    :rtype: A three-tuple (``str``, ``dict``, ``str``), or ``None`` on errors.
    """
    try:
        with open(os.path.join(finders.find(path) or '', 'text.md')) as f:
            text = f.read()
    except OSError:
        return None
    if style is None:
        style = 'default'
    try:
        formatter = HtmlFormatter(style=style)
    except ClassNotFound:
        formatter = HtmlFormatter(style='default')
    renderer = MarkdownRenderer(formatter=formatter, bundlepath=path)
    md = mistune.Markdown(renderer=renderer)
    fm_match = FRONT_MATTER_PATTERN.match(text)
    if fm_match:
        try:
            front_matter = yaml.load(fm_match.group(1))
        except yaml.YAMLError:
            front_matter = {}
        else:
            offset = fm_match.end(0) + 1
            text = text[offset:]
    html = md.render(text)
    return html, front_matter, formatter.get_style_defs('.highlight > pre')
<commit_msg>Fix logic for javascript: href<commit_after>import os
import collections
import mistune
import re
import yaml
from pygments import highlight
from pygments.util import ClassNotFound
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
from slugify import slugify
from django.conf import settings
from django.contrib.staticfiles import finders

FRONT_MATTER_PATTERN = re.compile(r'^---\n(.*?\n)---', re.DOTALL)

class MarkdownRenderer(mistune.Renderer):
    """Custom Markdown to HTML renderer.
    """
    def __init__(self, formatter, bundlepath, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.bundlepath = bundlepath or ''
        self.formatter = formatter
        self.id_slugs = collections.defaultdict(lambda: 0)

    def header(self, text, level, raw=None):
        """Auto header ID from slug of text.
        """
        slug = slugify(text)
        if self.id_slugs[slug]:
            slug = '{slug}-{n}'.format(slug=slug, n=self.id_slugs[slug])
        self.id_slugs[slug] += 1
        return '<h{level} id="{id}">{text}</h{level}>\n'.format(
            level=level, text=text, id=slug,
        )

    def block_code(self, code, lang):
        """Implement syntax highlighting with Pygments.
        """
        try:
            lexer = get_lexer_by_name(lang)
        except ClassNotFound:
            return super().block_code(code, lang)
        return highlight(code, lexer, self.formatter)

    def image(self, src, title, text):
        """Implement local static file resolving.
        """
        src = self._resolve_asset_path(src)
        return super().image(src, title, text)

    def _resolve_asset_path(self, path):
        if path.startswith('javascript:'):  # Taken from mistune.
            return path
        elif path.startswith('//') or '://' in path:    # Probably absolute.
            return path
        abspath = '/'.join([
            c.strip('/') for c in (
                '', settings.STATIC_URL, self.bundlepath, path,
            )
        ])
        return abspath

def markdown_to_html(path, style=None):
    """Renders given Markdown input to HTML.

    :path str: Static file path to a given post. The "post" should be a
        directory containing file ``text.md``.
    :prefix str: Prefix prepended to :path: when resolving static file path.
        Default is ``posts``.
    :return: HTML output, front-matter meta, and CSS. If no valid front-matter
        can be found, the second item returned will be an empty ``dict``.
    :rtype: A three-tuple (``str``, ``dict``, ``str``), or ``None`` on errors.
    """
    try:
        with open(os.path.join(finders.find(path) or '', 'text.md')) as f:
            text = f.read()
    except OSError:
        return None
    if style is None:
        style = 'default'
    try:
        formatter = HtmlFormatter(style=style)
    except ClassNotFound:
        formatter = HtmlFormatter(style='default')
    renderer = MarkdownRenderer(formatter=formatter, bundlepath=path)
    md = mistune.Markdown(renderer=renderer)
    fm_match = FRONT_MATTER_PATTERN.match(text)
    if fm_match:
        try:
            front_matter = yaml.load(fm_match.group(1))
        except yaml.YAMLError:
            front_matter = {}
        else:
            offset = fm_match.end(0) + 1
            text = text[offset:]
    html = md.render(text)
    return html, front_matter, formatter.get_style_defs('.highlight > pre')
<|endoftext|>


<commit_before>#    Copyright 2015 Mirantis, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import logging

import six

from oslo_messaging._drivers.zmq_driver.server.consumers \
    import zmq_consumer_base
from oslo_messaging._drivers.zmq_driver.server import zmq_incoming_message
from oslo_messaging._drivers.zmq_driver import zmq_address
from oslo_messaging._drivers.zmq_driver import zmq_async
from oslo_messaging._drivers.zmq_driver import zmq_socket
from oslo_messaging._i18n import _LE

LOG = logging.getLogger(__name__)

zmq = zmq_async.import_zmq()

class SubConsumer(zmq_consumer_base.ConsumerBase):

    def __init__(self, conf, poller, server):
        super(SubConsumer, self).__init__(conf, poller, server)
        self.matchmaker = server.matchmaker
        self.target = server.target
        self.socket = zmq_socket.ZmqSocket(self.conf, self.context, zmq.SUB)
        self.sockets.append(self.socket)
        self._subscribe_on_target(self.target)
        self.on_publishers(self.matchmaker.get_publishers())
        self.poller.register(self.socket, self.receive_message)

    def on_publishers(self, publishers):
        for host, sync in publishers:
            self.socket.connect(zmq_address.get_tcp_direct_address(host))
        LOG.debug("[%s] SUB consumer connected to publishers %s",
                  self.socket.handle.identity, publishers)

    def _subscribe_on_target(self, target):
        topic_filter = zmq_address.target_to_subscribe_filter(target)
        if target.topic:
            self.socket.setsockopt(zmq.SUBSCRIBE, six.b(target.topic))
        if target.server:
            self.socket.setsockopt(zmq.SUBSCRIBE, six.b(target.server))
        if target.topic and target.server:
            self.socket.setsockopt(zmq.SUBSCRIBE, topic_filter)
        LOG.debug("[%(host)s] Subscribing to topic %(filter)s",
                  {"host": self.socket.handle.identity,
                   "filter": topic_filter})

    @staticmethod
    def _receive_request(socket):
        topic_filter = socket.recv()
        message_id = socket.recv()
        context, message = socket.recv_loaded()
        LOG.debug("Received %(topic_filter)s topic message %(id)s",
                  {'id': message_id, 'topic_filter': topic_filter})
        return context, message

    def receive_message(self, socket):
        try:
            context, message = self._receive_request(socket)
            if not message:
                return None
            return zmq_incoming_message.ZmqIncomingMessage(context, message)
        except (zmq.ZMQError, AssertionError) as e:
            LOG.error(_LE("Receiving message failed: %s"), str(e))

    def cleanup(self):
        super(SubConsumer, self).cleanup()
<commit_msg>[zmq] Discover new publisher proxy<commit_after>#    Copyright 2015 Mirantis, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import logging

import six

from oslo_messaging._drivers.zmq_driver.server.consumers \
    import zmq_consumer_base
from oslo_messaging._drivers.zmq_driver.server import zmq_incoming_message
from oslo_messaging._drivers.zmq_driver import zmq_address
from oslo_messaging._drivers.zmq_driver import zmq_async
from oslo_messaging._drivers.zmq_driver import zmq_socket
from oslo_messaging._drivers.zmq_driver import zmq_updater
from oslo_messaging._i18n import _LE

LOG = logging.getLogger(__name__)

zmq = zmq_async.import_zmq()

class SubConsumer(zmq_consumer_base.ConsumerBase):

    def __init__(self, conf, poller, server):
        super(SubConsumer, self).__init__(conf, poller, server)
        self.matchmaker = server.matchmaker
        self.target = server.target
        self.socket = zmq_socket.ZmqSocket(self.conf, self.context, zmq.SUB)
        self.sockets.append(self.socket)
        self._subscribe_on_target(self.target)
        self.connection_updater = SubscriberConnectionUpdater(
            conf, self.matchmaker, self.socket)
        self.poller.register(self.socket, self.receive_message)

    def _subscribe_on_target(self, target):
        topic_filter = zmq_address.target_to_subscribe_filter(target)
        if target.topic:
            self.socket.setsockopt(zmq.SUBSCRIBE, six.b(target.topic))
        if target.server:
            self.socket.setsockopt(zmq.SUBSCRIBE, six.b(target.server))
        if target.topic and target.server:
            self.socket.setsockopt(zmq.SUBSCRIBE, topic_filter)
        LOG.debug("[%(host)s] Subscribing to topic %(filter)s",
                  {"host": self.socket.handle.identity,
                   "filter": topic_filter})

    @staticmethod
    def _receive_request(socket):
        topic_filter = socket.recv()
        message_id = socket.recv()
        context, message = socket.recv_loaded()
        LOG.debug("Received %(topic_filter)s topic message %(id)s",
                  {'id': message_id, 'topic_filter': topic_filter})
        return context, message

    def receive_message(self, socket):
        try:
            context, message = self._receive_request(socket)
            if not message:
                return None
            return zmq_incoming_message.ZmqIncomingMessage(context, message)
        except (zmq.ZMQError, AssertionError) as e:
            LOG.error(_LE("Receiving message failed: %s"), str(e))

    def cleanup(self):
        self.connection_updater.cleanup()
        super(SubConsumer, self).cleanup()

class SubscriberConnectionUpdater(zmq_updater.ConnectionUpdater):

    def _update_connection(self):
        publishers = self.matchmaker.get_publishers()
        for host, sync in publishers:
            self.socket.connect(zmq_address.get_tcp_direct_address(host))
        LOG.debug("[%s] SUB consumer connected to publishers %s",
                  self.socket.handle.identity, publishers)
<|endoftext|>


<commit_before>#!/usr/bin/python -OO
# -*- coding: utf-8 -*-
#
# This file is part of Archivematica.
#
# Copyright 2010-2013 Artefactual Systems Inc. <http://artefactual.com>
#
# Archivematica is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Archivematica is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Archivematica.    If not, see <http://www.gnu.org/licenses/>.

# @package Archivematica
# @subpackage Dashboard
# @author Joseph Perry <joseph@artefactual.com>
# @autho Justin Simpson <jsimpson@artefactual.com>
#import sys
#sys.path.append("/usr/lib/archivematica/archivematicaCommon")

#import databaseInterface
#databaseInterface.printSQL = True
from components import helpers
from django.db import connection

def getNormalizationReportQuery(sipUUID, idsRestriction=""):
    if idsRestriction:
        idsRestriction = 'AND (%s)' % idsRestriction

    cursor = connection.cursor()

    # not fetching name of ID Tool, don't think we need it.

    sql = """
    select
        CONCAT(a.currentLocation, ' ', a.fileUUID,' ', IFNULL(b.fileID, "")) AS 'pagingIndex',
        a.fileUUID,
        a.location,
        substring(a.currentLocation,23) as fileName,
        a.fileID,
        a.description,
        a.already_in_access_format,
        a.already_in_preservation_format,
        b.access_normalization_attempted,
        b.preservation_normalization_attempted,
        b.access_normalization_task_uuid,
        b.preservation_normalization_task_uuid,
        b.access_normalization_failed,
        b.preservation_normalization_failed,
        b.access_task_exitCode,
        b.preservation_task_exitCode
    from
        (select
            f.fileUUID,
            f.sipUUID,
            f.originalLocation as location,
            f.currentLocation,
            fid.uuid as 'fileID',
            fid.description,
            fid.validAccessFormat AS 'already_in_access_format',
            fid.validPreservationFormat AS 'already_in_preservation_format'
        from
        Files f
        Join
        FilesIdentifiedIDs fii on f.fileUUID = fii.fileUUID
        Join
        fpr_formatversion fid on fii.fileID = fid.uuid
        where
            f.fileGrpUse in ('original', 'service')
            and f.sipUUID = '{0}'
        ) a
    Left Join
        (select
            cr.fileID,
            j.sipUUID,
            max(if(cr.purpose = 'access', t.taskUUID, null)) IS NOT NULL as access_normalization_attempted,
            max(if(cr.purpose = 'preservation', t.taskUUID, null)) IS NOT NULL as preservation_normalization_attempted,
            max(if(cr.purpose = 'access', t.taskUUID, null)) as access_normalization_task_uuid,
            max(if(cr.purpose = 'preservation', t.taskUUID, null)) as preservation_normalization_task_uuid,
            max(if(cr.purpose = 'access', t.exitCode, null)) != 0 AS access_normalization_failed,
            max(if(cr.purpose = 'preservation', t.exitCode, null)) != 0 AS preservation_normalization_failed,
            max(if(cr.purpose = 'access', t.exitCode, null)) as access_task_exitCode,
            max(if(cr.purpose = 'preservation', t.exitCode, null)) as preservation_task_exitCode
        from
            fpr_fprule cr
            Join
            TasksConfigs tc on tc.taskTypePKReference = cr.pk
            join
            MicroServiceChainLinks ml on tc.pk = ml.currentTask
            Join
            Jobs j on j.MicroServiceChainLinksPK = ml.pk
            join
            Tasks t on t.jobUUID = j.jobUUID
        where
            cc.classification in ('preservation', 'access')
            and j.sipUUID = '{0}'
        group by cr.fileID
        ) b
    on a.fileID = b.fileID and a.sipUUID = b.sipUUID
    where a.sipUUID = '{0}'
    ORDER BY b.preservation_normalization_failed DESC,
        b.access_normalization_failed DESC,
        IF(b.preservation_normalization_attempted=0 AND a.already_in_preservation_format=0, 0, 1),
        fileName,
        fileID;
    """.format(sipUUID)

    cursor.execute(sql)
    objects = helpers.dictfetchall(cursor)
    #objects = databaseInterface.queryAllSQL(sql)
    return objects

if __name__ == '__main__':
    import sys
    uuid = "'%s'" % (sys.argv[1])
    sys.path.append("/usr/lib/archivematica/archivematicaCommon")
    #import databaseInterface
    #databaseInterface.printSQL = True
    print "testing normalization report"
    sql = getNormalizationReportQuery(sipUUID=uuid)
    print sql
    #rows = databaseInterface.queryAllSQL(sql)
    #for row in rows:
    #    print row
    #    print
<commit_msg>typo in normalization report.<commit_after>#!/usr/bin/python -OO
# -*- coding: utf-8 -*-
#
# This file is part of Archivematica.
#
# Copyright 2010-2013 Artefactual Systems Inc. <http://artefactual.com>
#
# Archivematica is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Archivematica is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Archivematica.    If not, see <http://www.gnu.org/licenses/>.

# @package Archivematica
# @subpackage Dashboard
# @author Joseph Perry <joseph@artefactual.com>
# @autho Justin Simpson <jsimpson@artefactual.com>
#import sys
#sys.path.append("/usr/lib/archivematica/archivematicaCommon")

#import databaseInterface
#databaseInterface.printSQL = True
from components import helpers
from django.db import connection

def getNormalizationReportQuery(sipUUID, idsRestriction=""):
    if idsRestriction:
        idsRestriction = 'AND (%s)' % idsRestriction

    cursor = connection.cursor()

    # not fetching name of ID Tool, don't think we need it.

    sql = """
    select
        CONCAT(a.currentLocation, ' ', a.fileUUID,' ', IFNULL(b.fileID, "")) AS 'pagingIndex',
        a.fileUUID,
        a.location,
        substring(a.currentLocation,23) as fileName,
        a.fileID,
        a.description,
        a.already_in_access_format,
        a.already_in_preservation_format,
        b.access_normalization_attempted,
        b.preservation_normalization_attempted,
        b.access_normalization_task_uuid,
        b.preservation_normalization_task_uuid,
        b.access_normalization_failed,
        b.preservation_normalization_failed,
        b.access_task_exitCode,
        b.preservation_task_exitCode
    from
        (select
            f.fileUUID,
            f.sipUUID,
            f.originalLocation as location,
            f.currentLocation,
            fid.uuid as 'fileID',
            fid.description,
            fid.access_format AS 'already_in_access_format',
            fid.preservation_format AS 'already_in_preservation_format'
        from
        Files f
        Join
        FilesIdentifiedIDs fii on f.fileUUID = fii.fileUUID
        Join
        fpr_formatversion fid on fii.fileID = fid.uuid
        where
            f.fileGrpUse in ('original', 'service')
            and f.sipUUID = '{0}'
        ) a
    Left Join
        (select
            cr.fileID,
            j.sipUUID,
            max(if(cr.purpose = 'access', t.taskUUID, null)) IS NOT NULL as access_normalization_attempted,
            max(if(cr.purpose = 'preservation', t.taskUUID, null)) IS NOT NULL as preservation_normalization_attempted,
            max(if(cr.purpose = 'access', t.taskUUID, null)) as access_normalization_task_uuid,
            max(if(cr.purpose = 'preservation', t.taskUUID, null)) as preservation_normalization_task_uuid,
            max(if(cr.purpose = 'access', t.exitCode, null)) != 0 AS access_normalization_failed,
            max(if(cr.purpose = 'preservation', t.exitCode, null)) != 0 AS preservation_normalization_failed,
            max(if(cr.purpose = 'access', t.exitCode, null)) as access_task_exitCode,
            max(if(cr.purpose = 'preservation', t.exitCode, null)) as preservation_task_exitCode
        from
            fpr_fprule cr
            Join
            TasksConfigs tc on tc.taskTypePKReference = cr.pk
            join
            MicroServiceChainLinks ml on tc.pk = ml.currentTask
            Join
            Jobs j on j.MicroServiceChainLinksPK = ml.pk
            join
            Tasks t on t.jobUUID = j.jobUUID
        where
            cc.classification in ('preservation', 'access')
            and j.sipUUID = '{0}'
        group by cr.fileID
        ) b
    on a.fileID = b.fileID and a.sipUUID = b.sipUUID
    where a.sipUUID = '{0}'
    ORDER BY b.preservation_normalization_failed DESC,
        b.access_normalization_failed DESC,
        IF(b.preservation_normalization_attempted=0 AND a.already_in_preservation_format=0, 0, 1),
        fileName,
        fileID;
    """.format(sipUUID)

    cursor.execute(sql)
    objects = helpers.dictfetchall(cursor)
    #objects = databaseInterface.queryAllSQL(sql)
    return objects

if __name__ == '__main__':
    import sys
    uuid = "'%s'" % (sys.argv[1])
    sys.path.append("/usr/lib/archivematica/archivematicaCommon")
    #import databaseInterface
    #databaseInterface.printSQL = True
    print "testing normalization report"
    sql = getNormalizationReportQuery(sipUUID=uuid)
    print sql
    #rows = databaseInterface.queryAllSQL(sql)
    #for row in rows:
    #    print row
    #    print
<|endoftext|>


<commit_before>from django.core.management.base import BaseCommand

from django.contrib.gis.geos import Point
from pollingstations.models import PollingStation, PollingDistrict, ResidentialAddress
from councils.models import Council
from addressbase.models import Address, Blacklist

def update_station_point(council_id, station_id, point):
    stations = PollingStation.objects.filter(
        council_id=council_id, internal_council_id=station_id
    )
    if len(stations) == 1:
        station = stations[0]
        station.location = point
        station.save()
        print("..updated")
    else:
        print("..NOT updated")

class Command(BaseCommand):
    def handle(self, *args, **kwargs):

        print("updating Watford address...")
        watford = Council.objects.get(pk="E07000103")
        watford.address = "Electoral Services Office\nRoom 22\nTown Hall\nWatford"
        watford.postcode = "WD17 3EX"
        watford.save()
        print("..updated")

        print("updating Harrogate address...")
        harrogate = Council.objects.get(pk="E07000165")
        harrogate.address = "Civic Centre\nSt Lukes Avenue\nHarrogate"
        harrogate.postcode = "HG1 2AE"
        harrogate.save()
        print("..updated")

        print("updating Oadby & Wigston name...")
        oadby = Council.objects.get(pk="E07000135")
        oadby.name = "Oadby & Wigston Borough Council"
        oadby.save()
        print("..updated")

        print("updating Swansea name...")
        swansea = Council.objects.get(pk="W06000011")
        swansea.name = "City & County of Swansea"
        swansea.save()
        print("..updated")

        print("removing bad points from AddressBase")
        bad_uprns = [
            "10023906550",
            "2630153843",
            "14059977",
            "10007921239",
            "10007920387",
            "10007920390",
            "10024288188",
            "10024288190",
            "10024288189",
            "10023117526",
            "10009922833",
        ]
        addresses = Address.objects.filter(pk__in=bad_uprns)
        for address in addresses:
            print(address.uprn)
            address.delete()
        print("..deleted")

        print("removing dodgy blacklist entries (result of bad point in AddressBase)..")
        blacklist = Blacklist.objects.filter(postcode="RH122LP")
        if len(blacklist) == 2:
            for b in blacklist:
                b.delete()
                print("..deleted")
        else:
            print("..NOT deleted")

        print(
            "removing dodgy blacklist entries (result of bad points in AddressBase).."
        )
        blacklist = Blacklist.objects.filter(postcode="S24AX")
        if len(blacklist) == 2:
            for b in blacklist:
                b.delete()
                print("..deleted")
        else:
            print("..NOT deleted")

        print("updating: Meppershall Village Hall...")
        stations = PollingStation.objects.filter(
            council_id="E06000056", internal_council_id="10361"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-0.340481, 52.018151, srid=4326)
            station.address = (
                "Meppershall Village Hall\nWalnut Tree Way\nMeppershall\nSG17 5AB"
            )
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #49
        print("updating: WI Hall, Faversham Road...")
        update_station_point("E07000105", "5707", Point(0.885308, 51.169796, srid=4326))

        # user issue report #50
        print("updating: Sandhurst School Sports Hall...")
        update_station_point(
            "E06000036", "4019", Point(-0.782442, 51.350179, srid=4326)
        )

        # user issue report #51
        print("updating: Weobley Village Hall...")
        update_station_point(
            "E06000019",
            "99-weobley-village-hall",
            Point(-2.869103, 52.159915, srid=4326),
        )

        # user issue report #47 (again)
        print("updating: Southill Community Centre...")
        stations = PollingStation.objects.filter(
            council_id="E06000059", internal_council_id="30560"
        )
        if len(stations) == 1:
            station = stations[0]
            station.postcode = "DT4 9SS"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #52
        print("updating: Rhodes Arts Complex...")
        update_station_point("E07000242", "1919", Point(0.163535, 51.863442, srid=4326))

        # user issue report #53
        print("updating: Moose Lodge...")
        update_station_point(
            "E06000059", "30570", Point(-2.466883, 50.606307, srid=4326)
        )

        print("updating: SW&T station 6753...")
        # All those electors who were going to Staplegrove Church School
        # are actually going to
        # Staplegrove Village Hall, 214 Staplegrove Road, Taunton TA2 6AL
        stations = PollingStation.objects.filter(
            council_id="E07000246", internal_council_id="6753"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-3.122027, 51.028508, srid=4326)
            station.address = "Staplegrove Village Hall\n214 Staplegrove Road\nTaunton"
            station.postcode = "TA2 6AL"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #54
        print("updating: West Moors Memorial Hall...")
        update_station_point(
            "E06000059", "30798", Point(-1.889868, 50.828982, srid=4326)
        )
        update_station_point(
            "E06000059", "30801", Point(-1.889868, 50.828982, srid=4326)
        )

        # user issue report #55
        print("updating: Dorset Fire & Rescue, Peverell Avenue West...")
        update_station_point(
            "E06000059", "30244", Point(-2.471750, 50.713013, srid=4326)
        )

        # user issue report #56
        print("updating: Higher Failsworth Primary School...")
        update_station_point(
            "E08000004", "5063", Point(-2.148726, 53.514296, srid=4326)
        )

        # user issue report #65
        print("updating: Penistone Cricket Club...")
        update_station_point("E08000016", "110", Point(-1.618343, 53.525626, srid=4326))

        # user issue report #66
        print("updating: St Mary's Catholic Primary School...")
        update_station_point(
            "E06000040",
            "23-st-marys-catholic-primary-school",
            Point(-0.724786, 51.535229, srid=4326),
        )
        update_station_point(
            "E06000040",
            "24-st-marys-catholic-primary-school",
            Point(-0.724786, 51.535229, srid=4326),
        )

        # user issue report #67
        print("updating: St Philips Church...")
        update_station_point(
            "E08000013", "2618", Point(-2.686908, 53.447048, srid=4326)
        )

        # user issue report #68
        for ps_id in ["BCL-11/1", "BCA-11", "BNB-18", "BEL-17"]:
            print("updating: Alton Manor Community Centre {}...".format(ps_id))
            update_station_point(
                "E07000032", ps_id, Point(-1.462416, 53.030518, srid=4326)
            )

        print("updating: Seabrook Curch 5290...")
        # All those electors who were going to Seabrook Church, 141 Seabrook Road
        # are actually going to
        # The Fountain Pub 171 Seabrook Road Hythe Kent CT21 5RT UPRN: 50022189
        # Council request.
        stations = PollingStation.objects.filter(
            council_id="E07000112", internal_council_id="5290"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(1.119211, 51.072634, srid=4326)
            station.address = "The Fountain Pub\n171 Seabrook Road\nHythe\nKent"
            station.postcode = "CT21 5RT"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #71
        print("updating: Bletchingdon Village Hall...")
        update_station_point(
            "E07000177", "17104", Point(-1.275286, 51.856428, srid=4326)
        )

        # user issue report #76
        print("updating: Heatherside Community Centre...")
        update_station_point(
            "E07000214", "2275", Point(-0.702364, 51.329003, srid=4326)
        )

        # user issue report #80
        print("updating: Darby and Joan Club...")
        update_station_point(
            "E08000034", "7820", Point(-1.6100925, 53.5945822, srid=4326)
        )

        # user issue report #81
        print("updating: Radford Semele Community Hall {}...".format(ps_id))
        stations = PollingStation.objects.filter(
            council_id="E07000222", internal_council_id__in=["7471", "7467"]
        )
        if len(stations) == 2:
            for station in stations:
                station.location = Point(-1.496585, 52.274189, srid=4326)
                station.address = "Radford Semele Community Hall\n68 Lewis Road\nRadford Semele\nLeamington Spa"
                station.postcode = "CV31 1UQ"
                station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #82
        print("updating: Hillsborough Trinity Methodist Church...")
        update_station_point(
            "E08000019",
            "116-hillsborough-trinity-methodist-church-lennox-rd-entrance",
            Point(-1.504240, 53.408718, srid=4326),
        )

        # user issue report #86
        print("updating: Guildhall, Lichfield...")
        stations = PollingStation.objects.filter(
            council_id="E07000194", internal_council_id="4413"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-1.827210, 52.683079, srid=4326)
            station.postcode = "WS13 6LU"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #87
        print("updating: The Grange Public House...")
        update_station_point(
            "E08000015", "4862", Point(-3.122875, 53.396797, srid=4326)
        )

        # user issue report #88
        print("updating: St Margaret's Parish Centre...")
        stations = PollingStation.objects.filter(
            council_id="E06000044", internal_council_id="3516"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-1.067090, 50.786643, srid=4326)
            station.postcode = ""
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #90
        print("updating: Removing point from Charminster Village Hall...")
        update_station_point("E06000059", "30105", None)

        deleteme = [
            # nothing yet
        ]
        for council_id in deleteme:
            print("Deleting data for council %s..." % (council_id))
            # check this council exists
            c = Council.objects.get(pk=council_id)
            print(c.name)

            PollingStation.objects.filter(council=council_id).delete()
            PollingDistrict.objects.filter(council=council_id).delete()
            ResidentialAddress.objects.filter(council=council_id).delete()
            print("..deleted")

        print("..done")
<commit_msg>Update Trust Hall-Stoke Gifford<commit_after>from django.core.management.base import BaseCommand

from django.contrib.gis.geos import Point
from pollingstations.models import PollingStation, PollingDistrict, ResidentialAddress
from councils.models import Council
from addressbase.models import Address, Blacklist

def update_station_point(council_id, station_id, point):
    stations = PollingStation.objects.filter(
        council_id=council_id, internal_council_id=station_id
    )
    if len(stations) == 1:
        station = stations[0]
        station.location = point
        station.save()
        print("..updated")
    else:
        print("..NOT updated")

class Command(BaseCommand):
    def handle(self, *args, **kwargs):

        print("updating Watford address...")
        watford = Council.objects.get(pk="E07000103")
        watford.address = "Electoral Services Office\nRoom 22\nTown Hall\nWatford"
        watford.postcode = "WD17 3EX"
        watford.save()
        print("..updated")

        print("updating Harrogate address...")
        harrogate = Council.objects.get(pk="E07000165")
        harrogate.address = "Civic Centre\nSt Lukes Avenue\nHarrogate"
        harrogate.postcode = "HG1 2AE"
        harrogate.save()
        print("..updated")

        print("updating Oadby & Wigston name...")
        oadby = Council.objects.get(pk="E07000135")
        oadby.name = "Oadby & Wigston Borough Council"
        oadby.save()
        print("..updated")

        print("updating Swansea name...")
        swansea = Council.objects.get(pk="W06000011")
        swansea.name = "City & County of Swansea"
        swansea.save()
        print("..updated")

        print("removing bad points from AddressBase")
        bad_uprns = [
            "10023906550",
            "2630153843",
            "14059977",
            "10007921239",
            "10007920387",
            "10007920390",
            "10024288188",
            "10024288190",
            "10024288189",
            "10023117526",
            "10009922833",
        ]
        addresses = Address.objects.filter(pk__in=bad_uprns)
        for address in addresses:
            print(address.uprn)
            address.delete()
        print("..deleted")

        print("removing dodgy blacklist entries (result of bad point in AddressBase)..")
        blacklist = Blacklist.objects.filter(postcode="RH122LP")
        if len(blacklist) == 2:
            for b in blacklist:
                b.delete()
                print("..deleted")
        else:
            print("..NOT deleted")

        print(
            "removing dodgy blacklist entries (result of bad points in AddressBase).."
        )
        blacklist = Blacklist.objects.filter(postcode="S24AX")
        if len(blacklist) == 2:
            for b in blacklist:
                b.delete()
                print("..deleted")
        else:
            print("..NOT deleted")

        print("updating: Meppershall Village Hall...")
        stations = PollingStation.objects.filter(
            council_id="E06000056", internal_council_id="10361"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-0.340481, 52.018151, srid=4326)
            station.address = (
                "Meppershall Village Hall\nWalnut Tree Way\nMeppershall\nSG17 5AB"
            )
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #49
        print("updating: WI Hall, Faversham Road...")
        update_station_point("E07000105", "5707", Point(0.885308, 51.169796, srid=4326))

        # user issue report #50
        print("updating: Sandhurst School Sports Hall...")
        update_station_point(
            "E06000036", "4019", Point(-0.782442, 51.350179, srid=4326)
        )

        # user issue report #51
        print("updating: Weobley Village Hall...")
        update_station_point(
            "E06000019",
            "99-weobley-village-hall",
            Point(-2.869103, 52.159915, srid=4326),
        )

        # user issue report #47 (again)
        print("updating: Southill Community Centre...")
        stations = PollingStation.objects.filter(
            council_id="E06000059", internal_council_id="30560"
        )
        if len(stations) == 1:
            station = stations[0]
            station.postcode = "DT4 9SS"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #52
        print("updating: Rhodes Arts Complex...")
        update_station_point("E07000242", "1919", Point(0.163535, 51.863442, srid=4326))

        # user issue report #53
        print("updating: Moose Lodge...")
        update_station_point(
            "E06000059", "30570", Point(-2.466883, 50.606307, srid=4326)
        )

        print("updating: SW&T station 6753...")
        # All those electors who were going to Staplegrove Church School
        # are actually going to
        # Staplegrove Village Hall, 214 Staplegrove Road, Taunton TA2 6AL
        stations = PollingStation.objects.filter(
            council_id="E07000246", internal_council_id="6753"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-3.122027, 51.028508, srid=4326)
            station.address = "Staplegrove Village Hall\n214 Staplegrove Road\nTaunton"
            station.postcode = "TA2 6AL"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #54
        print("updating: West Moors Memorial Hall...")
        update_station_point(
            "E06000059", "30798", Point(-1.889868, 50.828982, srid=4326)
        )
        update_station_point(
            "E06000059", "30801", Point(-1.889868, 50.828982, srid=4326)
        )

        # user issue report #55
        print("updating: Dorset Fire & Rescue, Peverell Avenue West...")
        update_station_point(
            "E06000059", "30244", Point(-2.471750, 50.713013, srid=4326)
        )

        # user issue report #56
        print("updating: Higher Failsworth Primary School...")
        update_station_point(
            "E08000004", "5063", Point(-2.148726, 53.514296, srid=4326)
        )

        # user issue report #65
        print("updating: Penistone Cricket Club...")
        update_station_point("E08000016", "110", Point(-1.618343, 53.525626, srid=4326))

        # user issue report #66
        print("updating: St Mary's Catholic Primary School...")
        update_station_point(
            "E06000040",
            "23-st-marys-catholic-primary-school",
            Point(-0.724786, 51.535229, srid=4326),
        )
        update_station_point(
            "E06000040",
            "24-st-marys-catholic-primary-school",
            Point(-0.724786, 51.535229, srid=4326),
        )

        # user issue report #67
        print("updating: St Philips Church...")
        update_station_point(
            "E08000013", "2618", Point(-2.686908, 53.447048, srid=4326)
        )

        # user issue report #68
        for ps_id in ["BCL-11/1", "BCA-11", "BNB-18", "BEL-17"]:
            print("updating: Alton Manor Community Centre {}...".format(ps_id))
            update_station_point(
                "E07000032", ps_id, Point(-1.462416, 53.030518, srid=4326)
            )

        print("updating: Seabrook Curch 5290...")
        # All those electors who were going to Seabrook Church, 141 Seabrook Road
        # are actually going to
        # The Fountain Pub 171 Seabrook Road Hythe Kent CT21 5RT UPRN: 50022189
        # Council request.
        stations = PollingStation.objects.filter(
            council_id="E07000112", internal_council_id="5290"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(1.119211, 51.072634, srid=4326)
            station.address = "The Fountain Pub\n171 Seabrook Road\nHythe\nKent"
            station.postcode = "CT21 5RT"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #71
        print("updating: Bletchingdon Village Hall...")
        update_station_point(
            "E07000177", "17104", Point(-1.275286, 51.856428, srid=4326)
        )

        # user issue report #76
        print("updating: Heatherside Community Centre...")
        update_station_point(
            "E07000214", "2275", Point(-0.702364, 51.329003, srid=4326)
        )

        # user issue report #80
        print("updating: Darby and Joan Club...")
        update_station_point(
            "E08000034", "7820", Point(-1.6100925, 53.5945822, srid=4326)
        )

        # user issue report #81
        print("updating: Radford Semele Community Hall {}...".format(ps_id))
        stations = PollingStation.objects.filter(
            council_id="E07000222", internal_council_id__in=["7471", "7467"]
        )
        if len(stations) == 2:
            for station in stations:
                station.location = Point(-1.496585, 52.274189, srid=4326)
                station.address = "Radford Semele Community Hall\n68 Lewis Road\nRadford Semele\nLeamington Spa"
                station.postcode = "CV31 1UQ"
                station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #82
        print("updating: Hillsborough Trinity Methodist Church...")
        update_station_point(
            "E08000019",
            "116-hillsborough-trinity-methodist-church-lennox-rd-entrance",
            Point(-1.504240, 53.408718, srid=4326),
        )

        # user issue report #86
        print("updating: Guildhall, Lichfield...")
        stations = PollingStation.objects.filter(
            council_id="E07000194", internal_council_id="4413"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-1.827210, 52.683079, srid=4326)
            station.postcode = "WS13 6LU"
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #87
        print("updating: The Grange Public House...")
        update_station_point(
            "E08000015", "4862", Point(-3.122875, 53.396797, srid=4326)
        )

        # user issue report #88
        print("updating: St Margaret's Parish Centre...")
        stations = PollingStation.objects.filter(
            council_id="E06000044", internal_council_id="3516"
        )
        if len(stations) == 1:
            station = stations[0]
            station.location = Point(-1.067090, 50.786643, srid=4326)
            station.postcode = ""
            station.save()
            print("..updated")
        else:
            print("..NOT updated")

        # user issue report #90
        print("updating: Removing point from Charminster Village Hall...")
        update_station_point("E06000059", "30105", None)

        # user issue report #83
        print("updating: Trust Hall-Stoke Gifford...")
        update_station_point(
            "E06000025", "10161", Point(-2.540965, 51.516655, srid=4326)
        )

        deleteme = [
            # nothing yet
        ]
        for council_id in deleteme:
            print("Deleting data for council %s..." % (council_id))
            # check this council exists
            c = Council.objects.get(pk=council_id)
            print(c.name)

            PollingStation.objects.filter(council=council_id).delete()
            PollingDistrict.objects.filter(council=council_id).delete()
            ResidentialAddress.objects.filter(council=council_id).delete()
            print("..deleted")

        print("..done")
<|endoftext|>


<commit_before>from django import template

from wagtail.wagtailimages.templatetags.wagtailimages_tags import (
    ImageNode
)

register = template.Library()

@register.tag(name="image")
def image(parser, token):
    bits = token.split_contents()[1:]
    image_var = bits[0]
    filter_spec = bits[1]
    bits = bits[2:]

    if len(bits) == 2 and bits[0] == 'as':
        # token is of the form {% image self.photo max-320x200 as img %}
        return VariableOrStringLiteralImageNode(
            image_var,
            filter_spec,
            output_var_name=bits[1]
        )
    else:
        # token is of the form {% image self.photo max-320x200 %} - all additional tokens
        # should be kwargs, which become attributes
        attrs = {}
        for bit in bits:
            try:
                name, value = bit.split('=')
            except ValueError:
                raise template.TemplateSyntaxError(
                    "'image' tag should be of the form {% image self.photo "
                    "max-320x200 [ custom-attr=\"value\" ... ] %} or "
                    "{% image self.photo max-320x200 as img %}"
                )
            # setup to resolve context variables as value
            attrs[name] = parser.compile_filter(value)

        return VariableOrStringLiteralImageNode(
            image_var,
            filter_spec,
            attrs=attrs
        )

class VariableOrStringLiteralImageNode(ImageNode):

    def __init__(self, image_var_name, filter_spec, output_var_name=None, attrs={}):
        self.image_var = template.Variable(image_var_name)
        self.output_var_name = output_var_name
        self.attrs = attrs
        self.filter_spec_raw = filter_spec
        self.filter_spec_as_var = template.Variable(filter_spec)

    def render(self, context):
        try:
            filter_spec = self.filter_spec_as_var.resolve(context)
        except template.VariableDoesNotExist:
            filter_spec = self.filter_spec_raw
        finally:
            self.filter_spec = filter_spec

        return super(VariableOrStringLiteralImageNode, self).render(context)
<commit_msg>Minor wagtail>=1.2 compatibility tweaks<commit_after>from django import template

from wagtail.wagtailimages.templatetags.wagtailimages_tags import (
    ImageNode
)

register = template.Library()

@register.tag(name="image")
def image(parser, token):
    bits = token.split_contents()[1:]
    image_expr = parser.compile_filter(bits[0])
    filter_spec = bits[1]
    bits = bits[2:]

    if len(bits) == 2 and bits[0] == 'as':
        # token is of the form {% image self.photo max-320x200 as img %}
        return VariableOrStringLiteralImageNode(
            image_expr,
            filter_spec,
            output_var_name=bits[1]
        )
    else:
        # token is of the form {% image self.photo max-320x200 %} - all additional tokens
        # should be kwargs, which become attributes
        attrs = {}
        for bit in bits:
            try:
                name, value = bit.split('=')
            except ValueError:
                raise template.TemplateSyntaxError(
                    "'image' tag should be of the form {% image self.photo "
                    "max-320x200 [ custom-attr=\"value\" ... ] %} or "
                    "{% image self.photo max-320x200 as img %}"
                )
            # setup to resolve context variables as value
            attrs[name] = parser.compile_filter(value)

        return VariableOrStringLiteralImageNode(
            image_expr,
            filter_spec,
            attrs=attrs
        )

class VariableOrStringLiteralImageNode(ImageNode):

    def __init__(self, image_expr, filter_spec, output_var_name=None, attrs={}):
        self.image_expr = image_expr
        self.output_var_name = output_var_name
        self.attrs = attrs
        self.filter_spec_raw = filter_spec
        self.filter_spec_as_var = template.Variable(filter_spec)

    def render(self, context):
        try:
            filter_spec = self.filter_spec_as_var.resolve(context)
        except template.VariableDoesNotExist:
            filter_spec = self.filter_spec_raw
        finally:
            self.filter_spec = filter_spec

        return super(VariableOrStringLiteralImageNode, self).render(context)
<|endoftext|>