<commit_before># The Hazard Library
# Copyright (C) 2012 GEM Foundation
#
# This program 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.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
Module :mod:`openquake.hazardlib.site` defines :class:`Site`.
"""
import numpy

from openquake.hazardlib.geo.mesh import Mesh
from openquake.hazardlib.slots import with_slots

@with_slots
class Site(object):
    """
    Site object represents a geographical location defined by its position
    as well as its soil characteristics.

    :param location:
        Instance of :class:`~openquake.hazardlib.geo.point.Point` representing
        where the site is located.
    :param vs30:
        Average shear wave velocity in the top 30 m, in m/s.
    :param vs30measured:
        Boolean value, ``True`` if ``vs30`` was measured on that location
        and ``False`` if it was inferred.
    :param z1pt0:
        Vertical distance from earth surface to the layer where seismic waves
        start to propagate with a speed above 1.0 km/sec, in meters.
    :param z2pt5:
        Vertical distance from earth surface to the layer where seismic waves
        start to propagate with a speed above 2.5 km/sec, in km.
    :param id:
        Optional parameter with default None. If given, it should be an
        integer identifying the site univocally.

    :raises ValueError:
        If any of ``vs30``, ``z1pt0`` or ``z2pt5`` is zero or negative.

    .. note::

        :class:`Sites <Site>` are pickleable
    """
    __slots__ = 'location vs30 vs30measured z1pt0 z2pt5 id'.split()

    def __init__(self, location, vs30, vs30measured, z1pt0, z2pt5, id=None):
        if not vs30 > 0:
            raise ValueError('vs30 must be positive')
        if not z1pt0 > 0:
            raise ValueError('z1pt0 must be positive')
        if not z2pt5 > 0:
            raise ValueError('z2pt5 must be positive')
        self.location = location
        self.vs30 = vs30
        self.vs30measured = vs30measured
        self.z1pt0 = z1pt0
        self.z2pt5 = z2pt5
        self.id = id

    def __str__(self):
        """
        >>> import openquake.hazardlib
        >>> loc = openquake.hazardlib.geo.point.Point(1, 2, 3)
        >>> str(Site(loc, 760.0, True, 100.0, 5.0))
        '<Location=<Latitude=2.000000, Longitude=1.000000, Depth=3.0000>, \
Vs30=760.0000, Vs30Measured=True, Depth1.0km=100.0000, Depth2.5km=5.0000>'
        """
        return (
            "<Location=%s, Vs30=%.4f, Vs30Measured=%r, Depth1.0km=%.4f, "
            "Depth2.5km=%.4f>") % (
                self.location, self.vs30, self.vs30measured, self.z1pt0,
                self.z2pt5)

    def __repr__(self):
        """
        >>> import openquake.hazardlib
        >>> loc = openquake.hazardlib.geo.point.Point(1, 2, 3)
        >>> site = Site(loc, 760.0, True, 100.0, 5.0)
        >>> str(site) == repr(site)
        True
        """
        return self.__str__()

class SiteCollection(object):
    """
    A collection of :class:`sites <Site>`.

    Instances of this class are intended to represent a large collection
    of sites in a most efficient way in terms of memory usage.

    .. note::

        Because calculations assume that :class:`Sites <Site>` are on the
        Earth's surface, all `depth` information in a :class:`SiteCollection`
        is discarded. The collection `mesh` will only contain lon and lat. So
        even if a :class:`SiteCollection` is created from sites containing
        `depth` in their geometry, iterating over the collection will yield
        :class:`Sites <Site>` with a reference depth of 0.0.

    :param sites:
        A list of instances of :class:`Site` class.
    """
    def __init__(self, sites):
        self.indices = None
        self.vs30 = numpy.zeros(len(sites))
        self.vs30measured = numpy.zeros(len(sites), dtype=bool)
        self.z1pt0 = self.vs30.copy()
        self.z2pt5 = self.vs30.copy()
        lons = self.vs30.copy()
        lats = self.vs30.copy()

        for i in xrange(len(sites)):
            self.vs30[i] = sites[i].vs30
            self.vs30measured[i] = sites[i].vs30measured
            self.z1pt0[i] = sites[i].z1pt0
            self.z2pt5[i] = sites[i].z2pt5
            lons[i] = sites[i].location.longitude
            lats[i] = sites[i].location.latitude

        self.mesh = Mesh(lons, lats, depths=None)

        # protect arrays from being accidentally changed. it is useful
        # because we pass these arrays directly to a GMPE through
        # a SiteContext object and if a GMPE is implemented poorly it could
        # modify the site values, thereby corrupting site and all the
        # subsequent calculation. note that this doesn't protect arrays from
        # being changed by calling itemset()
        for arr in (self.vs30, self.vs30measured, self.z1pt0, self.z2pt5,
                    self.mesh.lons, self.mesh.lats):
            arr.flags.writeable = False

    def __iter__(self):
        """
        Iterate through all :class:`sites <Site>` in the collection, yielding
        one at a time.
        """
        for i, location in enumerate(self.mesh):
            yield Site(location, self.vs30[i], self.vs30measured[i],
                       self.z1pt0[i], self.z2pt5[i])

    def expand(self, data, total_sites, placeholder):
        """
        Expand an array that was created for a filtered site collection
        with respect to indices of the sites that were :meth:`filtered
        <filter>`.

        The typical workflow is the following: there is a whole site
        collection, the one that has an information about all the sites.
        Then it gets filtered for performing some calculation on a limited
        set of sites (like for instance filtering sites by their proximity
        to a rupture). That filtering process can be repeated arbitrary
        number of times, i.e. a collection that is already filtered can
        be filtered for further limiting the set of sites to compute on.
        Then the (supposedly expensive) computation is done on a limited
        set of sites which still appears as just a :class:`SiteCollection`
        instance, so that computation code doesn't need to worry about
        filtering, it just needs to handle site collection objects. The
        calculation result comes in a form of 1d or 2d numpy array (that
        is, either one value per site or one 1d array per site) with length
        equal to number of sites in a filtered collection. That result
        needs to be expanded to an array of similar structure but the one
        that holds values for all the sites in the original (unfiltered)
        collection. This is what :meth:`expand` is for. It creates a result
        array of ``total_sites`` length and puts values from ``data`` into
        appropriate places in it remembering indices of sites that were
        chosen for actual calculation and leaving ``placeholder`` value
        everywhere else.

        :param data:
            1d or 2d numpy array with first dimension representing values
            computed for site from this collection.
        :param total_sites:
            Integer number representing a total number of sites in
            a collection this one was created from.
        :param placeholder:
            A scalar value to be put in result array for those sites that
            were filtered out and no real calculation was performed for them.
        :returns:
            Array of length ``total_sites`` with values from ``data``
            distributed in the appropriate places.
        """
        num_sites_computed = data.shape[0]
        assert num_sites_computed == len(self)

        if self.indices is None:
            assert total_sites == num_sites_computed
            # nothing to expand: this sites collection was not filtered
            return data

        assert num_sites_computed < total_sites
        assert self.indices[-1] < total_sites

        if data.ndim == 1:
            # single-dimensional array
            result = numpy.empty(total_sites)
            result.fill(placeholder)
            result.put(self.indices, data)
            return result

        assert data.ndim == 2
        # two-dimensional array
        num_values = data.shape[1]
        result = numpy.empty((total_sites, num_values))
        result.fill(placeholder)
        #for i in xrange(num_values):
        #    result[:, i].put(self.indices, data[:, i])
        for i, idx in enumerate(self.indices):
            result[idx] = data[i]
        return result

    def filter(self, mask):
        """
        Create a new collection with only a subset of sites from this one.

        :param mask:
            Numpy array of boolean values of the same length as this sites
            collection. ``True`` values should indicate that site with that
            index should be included into the filtered collection.
        :returns:
            A new :class:`SiteCollection` instance, unless all the values
            in ``mask`` are ``True``, in which case this site collection
            is returned, or if all the values in ``mask`` are ``False``,
            in which case method returns ``None``. New collection has data
            of only those sites that were marked for inclusion in mask.

        See also :meth:`expand`.
        """
        assert len(mask) == len(self)
        if mask.all():
            # all sites satisfy the filter, return
            # this collection unchanged
            return self
        if not mask.any():
            # no sites pass the filter, return None
            return None
        col = object.__new__(SiteCollection)
        # extract indices of Trues from the mask
        [indices] = mask.nonzero()
        # take only needed values from this collection
        # to a new one
        col.vs30 = self.vs30.take(indices)
        col.vs30measured = self.vs30measured.take(indices)
        col.z1pt0 = self.z1pt0.take(indices)
        col.z2pt5 = self.z2pt5.take(indices)
        col.mesh = Mesh(self.mesh.lons.take(indices),
                        self.mesh.lats.take(indices),
                        depths=None)
        if self.indices is not None:
            # if this collection was already a subset of some other
            # collection (a result of :meth:`filter` itself) than mask's
            # indices represent values in a filtered collection, but
            # we need to keep track of original indices in the whole
            # (unfiltered) collection. here we save original indices
            # of sites in this double- (or more times) filtered
            # collection
            col.indices = self.indices.take(indices)
        else:
            col.indices = indices
        # do the same as in the constructor
        for arr in (col.vs30, col.vs30measured, col.z1pt0, col.z2pt5,
                    col.mesh.lons, col.mesh.lats):
            arr.flags.writeable = False
        return col

    def __len__(self):
        """
        Return a number of sites in a collection.
        """
        return len(self.mesh)
<commit_msg>site:<commit_after># The Hazard Library
# Copyright (C) 2012 GEM Foundation
#
# This program 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.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
Module :mod:`openquake.hazardlib.site` defines :class:`Site`.
"""
import numpy

from openquake.hazardlib.geo.mesh import Mesh
from openquake.hazardlib.slots import with_slots

@with_slots
class Site(object):
    """
    Site object represents a geographical location defined by its position
    as well as its soil characteristics.

    :param location:
        Instance of :class:`~openquake.hazardlib.geo.point.Point` representing
        where the site is located.
    :param vs30:
        Average shear wave velocity in the top 30 m, in m/s.
    :param vs30measured:
        Boolean value, ``True`` if ``vs30`` was measured on that location
        and ``False`` if it was inferred.
    :param z1pt0:
        Vertical distance from earth surface to the layer where seismic waves
        start to propagate with a speed above 1.0 km/sec, in meters.
    :param z2pt5:
        Vertical distance from earth surface to the layer where seismic waves
        start to propagate with a speed above 2.5 km/sec, in km.
    :param id:
        Optional parameter with default None. If given, it should be an
        integer identifying the site univocally.

    :raises ValueError:
        If any of ``vs30``, ``z1pt0`` or ``z2pt5`` is zero or negative.

    .. note::

        :class:`Sites <Site>` are pickleable
    """
    __slots__ = 'location vs30 vs30measured z1pt0 z2pt5 id'.split()

    def __init__(self, location, vs30, vs30measured, z1pt0, z2pt5, id=None):
        if not vs30 > 0:
            raise ValueError('vs30 must be positive')
        if not z1pt0 > 0:
            raise ValueError('z1pt0 must be positive')
        if not z2pt5 > 0:
            raise ValueError('z2pt5 must be positive')
        self.location = location
        self.vs30 = vs30
        self.vs30measured = vs30measured
        self.z1pt0 = z1pt0
        self.z2pt5 = z2pt5
        self.id = id

    def __str__(self):
        """
        >>> import openquake.hazardlib
        >>> loc = openquake.hazardlib.geo.point.Point(1, 2, 3)
        >>> str(Site(loc, 760.0, True, 100.0, 5.0))
        '<Location=<Latitude=2.000000, Longitude=1.000000, Depth=3.0000>, \
Vs30=760.0000, Vs30Measured=True, Depth1.0km=100.0000, Depth2.5km=5.0000>'
        """
        return (
            "<Location=%s, Vs30=%.4f, Vs30Measured=%r, Depth1.0km=%.4f, "
            "Depth2.5km=%.4f>") % (
                self.location, self.vs30, self.vs30measured, self.z1pt0,
                self.z2pt5)

    def __repr__(self):
        """
        >>> import openquake.hazardlib
        >>> loc = openquake.hazardlib.geo.point.Point(1, 2, 3)
        >>> site = Site(loc, 760.0, True, 100.0, 5.0)
        >>> str(site) == repr(site)
        True
        """
        return self.__str__()

class SiteCollection(object):
    """
    A collection of :class:`sites <Site>`.

    Instances of this class are intended to represent a large collection
    of sites in a most efficient way in terms of memory usage.

    .. note::

        Because calculations assume that :class:`Sites <Site>` are on the
        Earth's surface, all `depth` information in a :class:`SiteCollection`
        is discarded. The collection `mesh` will only contain lon and lat. So
        even if a :class:`SiteCollection` is created from sites containing
        `depth` in their geometry, iterating over the collection will yield
        :class:`Sites <Site>` with a reference depth of 0.0.

    :param sites:
        A list of instances of :class:`Site` class.
    """
    def __init__(self, sites):
        self.indices = None
        self.vs30 = numpy.zeros(len(sites))
        self.vs30measured = numpy.zeros(len(sites), dtype=bool)
        self.z1pt0 = self.vs30.copy()
        self.z2pt5 = self.vs30.copy()
        lons = self.vs30.copy()
        lats = self.vs30.copy()

        for i in xrange(len(sites)):
            self.vs30[i] = sites[i].vs30
            self.vs30measured[i] = sites[i].vs30measured
            self.z1pt0[i] = sites[i].z1pt0
            self.z2pt5[i] = sites[i].z2pt5
            lons[i] = sites[i].location.longitude
            lats[i] = sites[i].location.latitude

        self.mesh = Mesh(lons, lats, depths=None)

        # protect arrays from being accidentally changed. it is useful
        # because we pass these arrays directly to a GMPE through
        # a SiteContext object and if a GMPE is implemented poorly it could
        # modify the site values, thereby corrupting site and all the
        # subsequent calculation. note that this doesn't protect arrays from
        # being changed by calling itemset()
        for arr in (self.vs30, self.vs30measured, self.z1pt0, self.z2pt5,
                    self.mesh.lons, self.mesh.lats):
            arr.flags.writeable = False

    def __iter__(self):
        """
        Iterate through all :class:`sites <Site>` in the collection, yielding
        one at a time.
        """
        for i, location in enumerate(self.mesh):
            yield Site(location, self.vs30[i], self.vs30measured[i],
                       self.z1pt0[i], self.z2pt5[i])

    def expand(self, data, total_sites, placeholder):
        """
        Expand an array that was created for a filtered site collection
        with respect to indices of the sites that were :meth:`filtered
        <filter>`.

        The typical workflow is the following: there is a whole site
        collection, the one that has an information about all the sites.
        Then it gets filtered for performing some calculation on a limited
        set of sites (like for instance filtering sites by their proximity
        to a rupture). That filtering process can be repeated arbitrary
        number of times, i.e. a collection that is already filtered can
        be filtered for further limiting the set of sites to compute on.
        Then the (supposedly expensive) computation is done on a limited
        set of sites which still appears as just a :class:`SiteCollection`
        instance, so that computation code doesn't need to worry about
        filtering, it just needs to handle site collection objects. The
        calculation result comes in a form of 1d or 2d numpy array (that
        is, either one value per site or one 1d array per site) with length
        equal to number of sites in a filtered collection. That result
        needs to be expanded to an array of similar structure but the one
        that holds values for all the sites in the original (unfiltered)
        collection. This is what :meth:`expand` is for. It creates a result
        array of ``total_sites`` length and puts values from ``data`` into
        appropriate places in it remembering indices of sites that were
        chosen for actual calculation and leaving ``placeholder`` value
        everywhere else.

        :param data:
            1d or 2d numpy array with first dimension representing values
            computed for site from this collection.
        :param total_sites:
            Integer number representing a total number of sites in
            a collection this one was created from.
        :param placeholder:
            A scalar value to be put in result array for those sites that
            were filtered out and no real calculation was performed for them.
        :returns:
            Array of length ``total_sites`` with values from ``data``
            distributed in the appropriate places.
        """
        num_sites_computed = data.shape[0]
        assert num_sites_computed == len(self)

        if self.indices is None:
            assert total_sites == num_sites_computed
            # nothing to expand: this sites collection was not filtered
            return data

        assert num_sites_computed < total_sites
        assert self.indices[-1] < total_sites

        if data.ndim == 1:
            # single-dimensional array
            result = numpy.empty(total_sites)
            result.fill(placeholder)
            result.put(self.indices, data)
            return result

        assert data.ndim == 2
        # two-dimensional array
        num_values = data.shape[1]
        result = numpy.empty((total_sites, num_values))
        result.fill(placeholder)
        for i in xrange(num_values):
            result[:, i].put(self.indices, data[:, i])
        return result

    def filter(self, mask):
        """
        Create a new collection with only a subset of sites from this one.

        :param mask:
            Numpy array of boolean values of the same length as this sites
            collection. ``True`` values should indicate that site with that
            index should be included into the filtered collection.
        :returns:
            A new :class:`SiteCollection` instance, unless all the values
            in ``mask`` are ``True``, in which case this site collection
            is returned, or if all the values in ``mask`` are ``False``,
            in which case method returns ``None``. New collection has data
            of only those sites that were marked for inclusion in mask.

        See also :meth:`expand`.
        """
        assert len(mask) == len(self)
        if mask.all():
            # all sites satisfy the filter, return
            # this collection unchanged
            return self
        if not mask.any():
            # no sites pass the filter, return None
            return None
        col = object.__new__(SiteCollection)
        # extract indices of Trues from the mask
        [indices] = mask.nonzero()
        # take only needed values from this collection
        # to a new one
        col.vs30 = self.vs30.take(indices)
        col.vs30measured = self.vs30measured.take(indices)
        col.z1pt0 = self.z1pt0.take(indices)
        col.z2pt5 = self.z2pt5.take(indices)
        col.mesh = Mesh(self.mesh.lons.take(indices),
                        self.mesh.lats.take(indices),
                        depths=None)
        if self.indices is not None:
            # if this collection was already a subset of some other
            # collection (a result of :meth:`filter` itself) than mask's
            # indices represent values in a filtered collection, but
            # we need to keep track of original indices in the whole
            # (unfiltered) collection. here we save original indices
            # of sites in this double- (or more times) filtered
            # collection
            col.indices = self.indices.take(indices)
        else:
            col.indices = indices
        # do the same as in the constructor
        for arr in (col.vs30, col.vs30measured, col.z1pt0, col.z2pt5,
                    col.mesh.lons, col.mesh.lats):
            arr.flags.writeable = False
        return col

    def __len__(self):
        """
        Return a number of sites in a collection.
        """
        return len(self.mesh)
<|endoftext|>


<commit_before># Copyright 2017-2019 TensorHub, 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.

from __future__ import absolute_import
from __future__ import division

import os
import subprocess

__version__ = "0.6.6.dev4"

# Used by bootstrap_main to ensure minimum required set of modules
# before continuing.
__requires__ = [
    # (<required module>, <distutils package req>)
    ("pip", "pip"),
    ("yaml", "PyYAML"),
    ("setuptools", "setuptools"),
    ("six", "six"),
    ("tabview", "tabview"),
    ("twine", "twine"),
    ("werkzeug", "Werkzeug"),
]

__pkgdir__ = os.path.dirname(os.path.dirname(__file__))

__git_commit__ = None
__git_status__ = None

def _try_init_git_attrs():
    try:
        _init_git_commit()
    except (OSError, subprocess.CalledProcessError):
        pass
    else:
        try:
            _init_git_status()
        except (OSError, subprocess.CalledProcessError):
            pass

def _init_git_commit():
    repo = _guild_repo()
    if repo:
        line = _cmd_out("git --work-tree \"%s\" log -1 --oneline" % repo)
        commit = line.split(" ")[0]
    else:
        commit = None
    globals()["__git_commit__"] = commit

def _guild_repo():
    repo = os.path.dirname(os.path.dirname(__file__))
    if os.path.isdir(os.path.join(repo, ".git")):
        return repo
    return None

def _init_git_status():
    repo = _guild_repo()
    if repo:
        raw = _cmd_out("git -C \"%s\" status -s" % repo)
    else:
        raw = None
    globals()["__git_status__"] = raw.split("\n") if raw else []

def _cmd_out(cmd):
    null = open(os.devnull, "w")
    out = subprocess.check_output(cmd, stderr=null, shell=True)
    return out.decode("utf-8").strip()

def version():
    if __git_commit__:
        workspace_changed_marker = "*" if __git_status__ else ""
        return "%s (dev %s%s)" % (
            __version__, __git_commit__,
            workspace_changed_marker)
    else:
        return __version__

_try_init_git_attrs()
<commit_msg>0.6.6.dev5<commit_after># Copyright 2017-2019 TensorHub, 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.

from __future__ import absolute_import
from __future__ import division

import os
import subprocess

__version__ = "0.6.6.dev5"

# Used by bootstrap_main to ensure minimum required set of modules
# before continuing.
__requires__ = [
    # (<required module>, <distutils package req>)
    ("pip", "pip"),
    ("yaml", "PyYAML"),
    ("setuptools", "setuptools"),
    ("six", "six"),
    ("tabview", "tabview"),
    ("twine", "twine"),
    ("werkzeug", "Werkzeug"),
]

__pkgdir__ = os.path.dirname(os.path.dirname(__file__))

__git_commit__ = None
__git_status__ = None

def _try_init_git_attrs():
    try:
        _init_git_commit()
    except (OSError, subprocess.CalledProcessError):
        pass
    else:
        try:
            _init_git_status()
        except (OSError, subprocess.CalledProcessError):
            pass

def _init_git_commit():
    repo = _guild_repo()
    if repo:
        line = _cmd_out("git --work-tree \"%s\" log -1 --oneline" % repo)
        commit = line.split(" ")[0]
    else:
        commit = None
    globals()["__git_commit__"] = commit

def _guild_repo():
    repo = os.path.dirname(os.path.dirname(__file__))
    if os.path.isdir(os.path.join(repo, ".git")):
        return repo
    return None

def _init_git_status():
    repo = _guild_repo()
    if repo:
        raw = _cmd_out("git -C \"%s\" status -s" % repo)
    else:
        raw = None
    globals()["__git_status__"] = raw.split("\n") if raw else []

def _cmd_out(cmd):
    null = open(os.devnull, "w")
    out = subprocess.check_output(cmd, stderr=null, shell=True)
    return out.decode("utf-8").strip()

def version():
    if __git_commit__:
        workspace_changed_marker = "*" if __git_status__ else ""
        return "%s (dev %s%s)" % (
            __version__, __git_commit__,
            workspace_changed_marker)
    else:
        return __version__

_try_init_git_attrs()
<|endoftext|>


<commit_before>import pygame

# Initialize Pygame Library
pygame.init()

# Display is an object inside Pygame
# Set Mode method creates a screen with the size inputted
screen = pygame.display.set_mode((900,700))

# Variable to keep track if our game is finished
finished = False

# While our game is not finished
while (finished == False):
  # get() method gives us all of the events that have happened since last check
  for event in pygame.event.get():
    # keyword to not do anything
    pass<commit_msg>Check for Quit Event<commit_after>import pygame

# Initialize Pygame Library
pygame.init()

# Display is an object inside Pygame
# Set Mode method creates a screen with the size inputted
screen = pygame.display.set_mode((900,700))

# Variable to keep track if our game is finished
finished = False

# While our game is not finished
while (finished == False):
  # get() method gives us all of the events that have happened since last check
  for event in pygame.event.get():
    # Looking at Event type. If type is a Quit Event then finish the game
    if event.type == pygame.QUIT:
      finished = True
<|endoftext|>


<commit_before>"""
Runs a pre-caching server against an ORES instance by listening to an RCStream
and submitting requests for scores to the web interface for each revision as it
happens.

:Usage:
    precached -h | --help
    precached <stream-url> <ores-url> [--config=<path>] [--verbose]

:Options:
    -h --help        Prints this documentation
    <stream-url>     URL of an RCStream
    <ores-url>       URL of base ORES webserver
    --config=<path>  The path to a yaml config file
                     [default: config/ores-localdev.yaml]
    --verbose        Print debugging information
"""
import concurrent.futures
import logging
import sys
import time
from collections import defaultdict

import docopt
import requests
import socketIO_client

import yamlconf

logger = logging.getLogger("ores.utilities.precached")

def main(argv=None):
    args = docopt.docopt(__doc__, argv=argv)

    config = yamlconf.load(open(args['--config']))
    run(args['<stream-url>'], args['<ores-url>'], config, args['--verbose'])

def run(stream_url, ores_url, config, verbose):

    if verbose:
        log_level = logging.DEBUG
    else:
        log_level = logging.INFO

    logging.basicConfig(
        level=log_level,
        format='%(asctime)s %(levelname)s:%(name)s -- %(message)s'
    )

    # Make requests and socketIO_client be quiet.  They are very noisy.
    logging.getLogger("requests").setLevel(logging.WARNING)
    logging.getLogger("socketIO_client").setLevel(logging.ERROR)  # SHUT UP!
    requests.packages.urllib3.disable_warnings()

    # Build a mapping of wikis and models from the configuration
    wiki_models = defaultdict(list)
    for wiki in config['ores']['scorers']:
        for model in config['scorers'][wiki]['scorer_models']:
            wiki_models[wiki].append(model)

    def get_score(wiki, model, rev_id):
        url = ores_url + "/scores/" + wiki + "/" + model + \
              "/" + str(rev_id) + "/"
        try:
            start = time.time()
            requests.get(url, timeout=20, verify=False)
            logger.debug("GET {0} completed in {1} seconds."
                         .format(url, time.time() - start))
        except Exception as e:
            logger.error(str(type(e)) + ": " + str(e))

    with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
        class WikiNamespace(socketIO_client.BaseNamespace):
            def on_change(self, change):
                if change['type'] in ('new', 'edit'):
                    wiki = change['wiki']
                    rev_id = change['revision']['new']
                    for model in wiki_models[wiki]:
                        start = time.time()
                        executor.submit(get_score, wiki, model, rev_id)
                        logger.debug("GET {0} started in {1} seconds."
                                     .format((wiki, model, rev_id),
                                             time.time() - start))

            def on_connect(self):
                logger.info("Connecting socketIO client to {0}."
                            .format(stream_url))

                # TODO: This should be limited to the wikis we actually care about
                # but we identify a wiki by it's dbname and this pattern matching
                # uses a domain name.
                self.emit('subscribe', '*')  # Subscribes to all wikis

        socketIO = socketIO_client.SocketIO(stream_url, 80)
        socketIO.define(WikiNamespace, '/rc')

        try:
            socketIO.wait(seconds=sys.maxsize)
        except KeyboardInterrupt:
            print("Keyboard interrupt detected.  Shutting down.")
<commit_msg>Updated for new config.<commit_after>"""
Runs a pre-caching server against an ORES instance by listening to an RCStream
and submitting requests for scores to the web interface for each revision as it
happens.

:Usage:
    precached -h | --help
    precached <stream-url> <ores-url> [--config=<path>] [--verbose]

:Options:
    -h --help        Prints this documentation
    <stream-url>     URL of an RCStream
    <ores-url>       URL of base ORES webserver
    --config=<path>  The path to a yaml config file
                     [default: config/ores-localdev.yaml]
    --verbose        Print debugging information
"""
import concurrent.futures
import logging
import sys
import time
from collections import defaultdict

import docopt
import requests
import socketIO_client

import yamlconf

logger = logging.getLogger("ores.utilities.precached")

def main(argv=None):
    args = docopt.docopt(__doc__, argv=argv)

    config = yamlconf.load(open(args['--config']))
    run(args['<stream-url>'], args['<ores-url>'], config, args['--verbose'])

def run(stream_url, ores_url, config, verbose):

    if verbose:
        log_level = logging.DEBUG
    else:
        log_level = logging.INFO

    logging.basicConfig(
        level=log_level,
        format='%(asctime)s %(levelname)s:%(name)s -- %(message)s'
    )

    # Make requests and socketIO_client be quiet.  They are very noisy.
    logging.getLogger("requests").setLevel(logging.WARNING)
    logging.getLogger("socketIO_client").setLevel(logging.ERROR)  # SHUT UP!
    requests.packages.urllib3.disable_warnings()

    # Build a mapping of wikis and models from the configuration
    wiki_models = defaultdict(list)
    sp_name = config['ores']['score_processor']
    for wiki in config['score_processors'][sp_name]['scoring_contexts']:
        for model in config['scoring_contexts'][wiki]['scorer_models']:
            wiki_models[wiki].append(model)

    def get_score(wiki, model, rev_id):
        url = ores_url + "/scores/" + wiki + "/" + model + \
              "/" + str(rev_id) + "/"
        try:
            start = time.time()
            requests.get(url, timeout=20, verify=False)
            logger.debug("GET {0} completed in {1} seconds."
                         .format(url, time.time() - start))
        except Exception as e:
            logger.error(str(type(e)) + ": " + str(e))

    with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
        class WikiNamespace(socketIO_client.BaseNamespace):
            def on_change(self, change):
                if change['type'] in ('new', 'edit'):
                    wiki = change['wiki']
                    rev_id = change['revision']['new']
                    for model in wiki_models[wiki]:
                        start = time.time()
                        executor.submit(get_score, wiki, model, rev_id)
                        logger.debug("GET {0} started in {1} seconds."
                                     .format((wiki, model, rev_id),
                                             time.time() - start))

            def on_connect(self):
                logger.info("Connecting socketIO client to {0}."
                            .format(stream_url))

                # TODO: This should be limited to the wikis we actually care about
                # but we identify a wiki by it's dbname and this pattern matching
                # uses a domain name.
                self.emit('subscribe', '*')  # Subscribes to all wikis

        socketIO = socketIO_client.SocketIO(stream_url, 80)
        socketIO.define(WikiNamespace, '/rc')

        try:
            socketIO.wait(seconds=sys.maxsize)
        except KeyboardInterrupt:
            print("Keyboard interrupt detected.  Shutting down.")
<|endoftext|>


<commit_before># -* encoding: utf-8 *-

# 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 shutil
import uuid

import aptly_api
import configargparse

from typing import Any, Sequence, Union, Dict, cast, List, Type

from gopythongo.shared.aptly_base import AptlyBaseStore
from gopythongo.utils import print_debug, highlight, print_info, run_process, ErrorMessage, print_warning, \
    create_script_path, cmdargs_unquote_split
from gopythongo.utils.buildcontext import the_context
from gopythongo.utils.debversion import DebianVersion
from gopythongo.versioners.parsers import VersionContainer
from gopythongo.versioners.parsers.debianparser import DebianVersionParser
from gopythongo.versioners.aptly import AptlyVersioner

class RemoteAptlyStore(AptlyBaseStore):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)

    @property
    def store_name(self) -> str:
        return "remote-aptly"

    @property
    def supported_version_parsers(self) -> List[str]:
        return ["debian"]

    def add_args(self, parser: configargparse.ArgumentParser) -> None:
        super().add_args(parser)

        gp_ast = parser.add_argument_group("Aptly Remote Store options")
        gp_ast.add_argument("--aptly-architecture", dest="aptly_architectures", action="append", default=[],
                            help="Define what architectures to publish via aptly.")
        # TODO: add aptly_api parameters for GPG

    def validate_args(self, args: configargparse.Namespace) -> None:
        super().validate_args(args)

        from gopythongo.versioners import get_version_parsers
        debvp = cast(DebianVersionParser, get_version_parsers()["debian"])  # type: DebianVersionParser
        if args.version_action not in debvp.supported_actions:
            raise ErrorMessage("Version Action is set to '%s', but you chose the Aptly Store which relies on Debian "
                               "version strings. Unfortunately the Debian Versioner does not support the '%s' action. "
                               "It only supports: %s." %
                               (highlight(args.version_action), highlight(args.version_action),
                                highlight(", ".join(debvp.supported_actions))))

    @staticmethod
    def _get_aptly_versioner() -> AptlyVersioner:
        from gopythongo.versioners import get_versioners
        from gopythongo.versioners.aptly import AptlyVersioner
        aptlyv = cast(AptlyVersioner, get_versioners()["aptly"])
        return aptlyv

    @staticmethod
    def _get_debian_versionparser() -> DebianVersionParser:
        from gopythongo.versioners import get_version_parsers
        debvp = cast(DebianVersionParser, get_version_parsers()["debian"])
        return debvp

    def _check_version_exists(self, package_name: str, version: str, args: configargparse.Namespace) -> bool:
        aptlyv = self._get_aptly_versioner()
        if aptlyv.query_repo_versions("Name (%s), $Version (= %s)" %
                                      (package_name, version), args,
                                      allow_fallback_version=False):
            return True
        else:
            return False

    def _check_package_exists(self, package_name: str, args: configargparse.Namespace) -> bool:
        aptlyv = self._get_aptly_versioner()
        if aptlyv.query_repo_versions("Name (%s)" % package_name, args, allow_fallback_version=False):
            return True
        else:
            return False

    def _find_new_version(self, package_name: str, version: VersionContainer[DebianVersion], action: str,
                          args: configargparse.Namespace) -> VersionContainer[DebianVersion]:
        """
        Find the next version given `action` in the target repo for `package_name`.
        """
        print_debug("Finding a version string in the aptly store for package %s" % highlight(package_name))
        aptlyv = self._get_aptly_versioner()
        debvp = self._get_debian_versionparser()

        debversions = aptlyv.query_repo_versions("Name (%s), $Version (%% *%s*)" %
                                                 (package_name, version.version), args, allow_fallback_version=False)

        if debversions:
            # we already have a version in the repo
            new_base = debversions[-1]
            print_debug("Found an existing version %s for package %s" %
                        (highlight(str(new_base)), highlight(package_name)))
            after_action = debvp.execute_action(debvp.deserialize(str(new_base)), action)
            if after_action.version < version.version:
                if args.aptly_overwrite_newer:
                    print_info("Will overwrite same or newer version in repo with older version (existing: %s, "
                               "new: %s)" % (highlight(str(version.version)), highlight(str(after_action.version))))
                    return after_action
                else:
                    raise ErrorMessage("Repo already contains a newer version of %s than the one that was going to be "
                                       "added (existing: %s new: %s)" %
                                       (highlight(package_name), highlight(str(new_base)),
                                        highlight(str(version.version))))
            if self._check_version_exists(package_name, str(after_action.version), args):
                print_debug("The new after-action (%s) version %s, based off %s, derived from %s is already taken, so "
                            "we now recursively search for an unused version string for %s" %
                            (action, highlight(str(after_action.version)), highlight(str(new_base)),
                             highlight(str(version.version)), highlight(package_name)))
                self._find_new_version(package_name, after_action, action, args)
            else:
                print_info("After executing action %s, the selected next version for %s is %s" %
                           (highlight(action), highlight(package_name), highlight(str(after_action.version))))
                return after_action
        else:
            print_info("%s seems to be as yet unused" % highlight(str(version.version)))
            return version

    def generate_future_versions(self, artifact_names: Sequence[str], base_version: VersionContainer[Any], action: str,
                                 args: configargparse.Namespace) -> Union[Dict[str, VersionContainer[DebianVersion]],
                                                                          None]:
        ret = {}  # type: Dict[str, VersionContainer[DebianVersion]]
        base_debv = base_version.convert_to("debian")
        for package_name in artifact_names:
            next_version = self._find_new_version(package_name, base_debv, action, args)
            ret[package_name] = next_version
        return ret

    def store(self, args: configargparse.Namespace) -> None:
        _aptly = aptly_api.Client(args.aptly_server_url)
        _tmpfolder = str(uuid.uuid4())
        # add each package to the repo
        for pkg in the_context.packer_artifacts:
            print_info("Adding %s to repo %s" % (highlight(pkg.artifact_filename), highlight(args.aptly_repo)))
            try:
                _aptly.files.upload(_tmpfolder, pkg.artifact_filename)
            except aptly_api.AptlyAPIException as e:
                raise ErrorMessage("Unable to upload package file %s to Aptly temporary folder %s. Error was: %s" %
                                   (pkg.artifact_filename, _tmpfolder, str(e))) from e

            report = _aptly.repos.add_uploaded_file(args.aptly_repo, _tmpfolder, pkg.artifact_filename,
                                                    remove_processed_files=True,
                                                    force_replace=not args.aptly_dont_remove)

        # TODO: CONTINUE IMPLEMENTATION HERE
        # publish the repo or update it if it has been previously published
        if args.aptly_publish_endpoint:
            print_info("Publishing repo %s to endpoint %s" %
                       (highlight(args.aptly_repo), highlight(args.aptly_publish_endpoint)))
            # override to use vault_wrapper if specified on the command-line
            _aptly_wrapper_cmd = create_script_path(the_context.gopythongo_path, "vaultwrapper")
            cmdline = [_aptly_wrapper_cmd, "--wrap-program", shutil.which("cat")]

            if args.aptly_passphrase:
                passphrase = args.aptly_passphrase
            elif args.use_aptly_wrapper:
                vault_ret = run_process(*cmdline, allow_nonzero_exitcode=False)
                if vault_ret.output.strip():
                    raise ErrorMessage("vaultwrapper returned an empty passphrase.")
                else:
                    passphrase = vault_ret.output.strip()

            # check whether the publishing endpoint is already in use by executing "aptly publish list" and if so,
            # execute "aptly publish update" instead of "aptly publish repo"
            publish_kwargs = {
                "sources": {"name": args.aptly_repo},
                "architectures": args.aptly_architectures,
            }
            aptly_kwargs = {
                "distribution": args.aptly_distribution,
                "prefix": args.aptly_publish_endpoint,
            }
            publish_kwargs.update(aptly_kwargs)
            aptly_oper = lambda: _aptly.publish.publish(**publish_kwargs)
            for published in  _aptly.publish.list():
                if "%s:%s" % (published.storage, published.prefix) == args.aptly_publish_endpoint:
                    print_info("Publishing endpoint %s already in use. Executing update..." %
                               highlight(args.aptly_publish_endpoint))
                    aptly_oper = lambda: _aptly.publish.update(**aptly_kwargs)
                    break

            # TODO: call aptly_oper with the correct parameters for signing

            if cmd == "repo":
                cmdline += cmdargs_unquote_split(args.aptly_publish_opts)
                cmdline += ["-distribution=%s" % args.aptly_distribution]
                cmdline += [args.aptly_repo, args.aptly_publish_endpoint]
            else:
                cmdline += cmdargs_unquote_split(args.aptly_publish_opts)
                cmdline += [args.aptly_distribution, args.aptly_publish_endpoint]

            run_process(*cmdline)

    def print_help(self) -> None:
        print("Remove Aptly Store\n"
              "==================\n"
              "\n"
              "Stores .deb packages in a remote package repository managed by aptly\n"
              "(https://aptly.info). The remote repository must run 'aptly api serve', i.e. an\n"
              "aptly API server that this storage plug-in can call. This functionality is\n"
              "especially useful if used inside an isolating build server like concourse.ci\n"
              "where the build result can then be uploaded to the repository through the API.\n")

store_class = RemoteAptlyStore  # type: Type[RemoteAptlyStore]
<commit_msg>this should be the first working implementation of the remote aptly store implementation<commit_after># -* encoding: utf-8 *-

# 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 shutil
import uuid

import aptly_api
import configargparse

from typing import Any, Sequence, Union, Dict, cast, List, Type

from gopythongo.shared.aptly_base import AptlyBaseStore
from gopythongo.utils import print_debug, highlight, print_info, run_process, ErrorMessage, print_warning, \
    create_script_path, cmdargs_unquote_split
from gopythongo.utils.buildcontext import the_context
from gopythongo.utils.debversion import DebianVersion
from gopythongo.versioners.parsers import VersionContainer
from gopythongo.versioners.parsers.debianparser import DebianVersionParser
from gopythongo.versioners.aptly import AptlyVersioner

class RemoteAptlyStore(AptlyBaseStore):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)

    @property
    def store_name(self) -> str:
        return "remote-aptly"

    @property
    def supported_version_parsers(self) -> List[str]:
        return ["debian"]

    def add_args(self, parser: configargparse.ArgumentParser) -> None:
        super().add_args(parser)

        gp_ast = parser.add_argument_group("Aptly Remote Store options")
        gp_ast.add_argument("--aptly-architecture", dest="aptly_architectures", action="append", default=[],
                            help="Define what architectures to publish via aptly.")
        gp_ast.add_argument("--aptly-skip-signing", dest="aptly_skip_signing", action="store_true", default=False,
                            help="Tell aptly via API to skip signing the repo.")
        gp_ast.add_argument("--aptly-gpgkey", dest="aptly_gpgkey", default=None,
                            help="The fingerprint or key id of the GPG key that aptly should use to sign the published "
                                 "repository. The GPG key must be known by the aptly API server, i.e. it must be in "
                                 "the secret keyring on the server. The best way to achieve this is by setting the "
                                 "GNUPGHOME environment variable on the 'aptly api serve' command.")

    def validate_args(self, args: configargparse.Namespace) -> None:
        super().validate_args(args)

        from gopythongo.versioners import get_version_parsers
        debvp = cast(DebianVersionParser, get_version_parsers()["debian"])  # type: DebianVersionParser
        if args.version_action not in debvp.supported_actions:
            raise ErrorMessage("Version Action is set to '%s', but you chose the Aptly Store which relies on Debian "
                               "version strings. Unfortunately the Debian Versioner does not support the '%s' action. "
                               "It only supports: %s." %
                               (highlight(args.version_action), highlight(args.version_action),
                                highlight(", ".join(debvp.supported_actions))))

        if args.aptly_skip_signing and args.aptly_gpgkey:
            raise ErrorMessage("Don't specify to skip signing (--aptly-skip-signing) and also specify a GPG key for "
                               "signing (--aptly-gpgkey).")
        if not args.aptly_skip_signing and not args.aptly_gpgkey:
            raise ErrorMessage("You must specify the key id or fingerprint of the GPG key to use to sign the published "
                               "apt repository.")

    @staticmethod
    def _get_aptly_versioner() -> AptlyVersioner:
        from gopythongo.versioners import get_versioners
        from gopythongo.versioners.aptly import AptlyVersioner
        aptlyv = cast(AptlyVersioner, get_versioners()["aptly"])
        return aptlyv

    @staticmethod
    def _get_debian_versionparser() -> DebianVersionParser:
        from gopythongo.versioners import get_version_parsers
        debvp = cast(DebianVersionParser, get_version_parsers()["debian"])
        return debvp

    def _check_version_exists(self, package_name: str, version: str, args: configargparse.Namespace) -> bool:
        aptlyv = self._get_aptly_versioner()
        if aptlyv.query_repo_versions("Name (%s), $Version (= %s)" %
                                      (package_name, version), args,
                                      allow_fallback_version=False):
            return True
        else:
            return False

    def _check_package_exists(self, package_name: str, args: configargparse.Namespace) -> bool:
        aptlyv = self._get_aptly_versioner()
        if aptlyv.query_repo_versions("Name (%s)" % package_name, args, allow_fallback_version=False):
            return True
        else:
            return False

    def _find_new_version(self, package_name: str, version: VersionContainer[DebianVersion], action: str,
                          args: configargparse.Namespace) -> VersionContainer[DebianVersion]:
        """
        Find the next version given `action` in the target repo for `package_name`.
        """
        print_debug("Finding a version string in the aptly store for package %s" % highlight(package_name))
        aptlyv = self._get_aptly_versioner()
        debvp = self._get_debian_versionparser()

        debversions = aptlyv.query_repo_versions("Name (%s), $Version (%% *%s*)" %
                                                 (package_name, version.version), args, allow_fallback_version=False)

        if debversions:
            # we already have a version in the repo
            new_base = debversions[-1]
            print_debug("Found an existing version %s for package %s" %
                        (highlight(str(new_base)), highlight(package_name)))
            after_action = debvp.execute_action(debvp.deserialize(str(new_base)), action)
            if after_action.version < version.version:
                if args.aptly_overwrite_newer:
                    print_info("Will overwrite same or newer version in repo with older version (existing: %s, "
                               "new: %s)" % (highlight(str(version.version)), highlight(str(after_action.version))))
                    return after_action
                else:
                    raise ErrorMessage("Repo already contains a newer version of %s than the one that was going to be "
                                       "added (existing: %s new: %s)" %
                                       (highlight(package_name), highlight(str(new_base)),
                                        highlight(str(version.version))))
            if self._check_version_exists(package_name, str(after_action.version), args):
                print_debug("The new after-action (%s) version %s, based off %s, derived from %s is already taken, so "
                            "we now recursively search for an unused version string for %s" %
                            (action, highlight(str(after_action.version)), highlight(str(new_base)),
                             highlight(str(version.version)), highlight(package_name)))
                self._find_new_version(package_name, after_action, action, args)
            else:
                print_info("After executing action %s, the selected next version for %s is %s" %
                           (highlight(action), highlight(package_name), highlight(str(after_action.version))))
                return after_action
        else:
            print_info("%s seems to be as yet unused" % highlight(str(version.version)))
            return version

    def generate_future_versions(self, artifact_names: Sequence[str], base_version: VersionContainer[Any], action: str,
                                 args: configargparse.Namespace) -> Union[Dict[str, VersionContainer[DebianVersion]],
                                                                          None]:
        ret = {}  # type: Dict[str, VersionContainer[DebianVersion]]
        base_debv = base_version.convert_to("debian")
        for package_name in artifact_names:
            next_version = self._find_new_version(package_name, base_debv, action, args)
            ret[package_name] = next_version
        return ret

    def store(self, args: configargparse.Namespace) -> None:
        _aptly = aptly_api.Client(args.aptly_server_url)
        _tmpfolder = str(uuid.uuid4())
        # add each package to the repo
        for pkg in the_context.packer_artifacts:
            print_info("Adding %s to repo %s" % (highlight(pkg.artifact_filename), highlight(args.aptly_repo)))
            try:
                _aptly.files.upload(_tmpfolder, pkg.artifact_filename)
            except aptly_api.AptlyAPIException as e:
                raise ErrorMessage("Unable to upload package file %s to Aptly temporary folder %s. Error was: %s" %
                                   (pkg.artifact_filename, _tmpfolder, str(e))) from e

            report = _aptly.repos.add_uploaded_file(args.aptly_repo, _tmpfolder, pkg.artifact_filename,
                                                    remove_processed_files=True,
                                                    force_replace=not args.aptly_dont_remove)

        # publish the repo or update it if it has been previously published
        if args.aptly_publish_endpoint:
            print_info("Publishing repo %s to endpoint %s" %
                       (highlight(args.aptly_repo), highlight(args.aptly_publish_endpoint)))
            # override to use vault_wrapper if specified on the command-line
            _aptly_wrapper_cmd = create_script_path(the_context.gopythongo_path, "vaultwrapper")
            cmdline = [_aptly_wrapper_cmd, "--wrap-program", shutil.which("cat")]

            if args.aptly_passphrase:
                passphrase = args.aptly_passphrase
            elif args.use_aptly_wrapper:
                vault_ret = run_process(*cmdline, allow_nonzero_exitcode=False)
                if vault_ret.output.strip():
                    raise ErrorMessage("vaultwrapper returned an empty passphrase.")
                else:
                    passphrase = vault_ret.output.strip()

            # check whether the publishing endpoint is already in use by executing "aptly publish list" and if so,
            # execute "aptly publish update" instead of "aptly publish repo"
            publish_kwargs = {
                "sources": {"name": args.aptly_repo},
                "architectures": args.aptly_architectures,
            }
            aptly_kwargs = {
                "distribution": args.aptly_distribution,
                "prefix": args.aptly_publish_endpoint,
            }

            if args.aptly_skip_signing:
                aptly_kwargs["sign_skip"] = True
            else:
                aptly_kwargs["sign_gpgkey"] = args.aptly_gpgkey
                aptly_kwargs["sign_passphrase"] = passphrase

            publish_kwargs.update(aptly_kwargs)
            aptly_oper = lambda: _aptly.publish.publish(**publish_kwargs)
            for published in  _aptly.publish.list():
                if "%s:%s" % (published.storage, published.prefix) == args.aptly_publish_endpoint:
                    print_info("Publishing endpoint %s already in use. Executing update..." %
                               highlight(args.aptly_publish_endpoint))
                    aptly_oper = lambda: _aptly.publish.update(**aptly_kwargs)
                    break
            aptly_oper()

    def print_help(self) -> None:
        print("Remove Aptly Store\n"
              "==================\n"
              "\n"
              "Stores .deb packages in a remote package repository managed by aptly\n"
              "(https://aptly.info). The remote repository must run 'aptly api serve', i.e. an\n"
              "aptly API server that this storage plug-in can call. This functionality is\n"
              "especially useful if used inside an isolating build server like concourse.ci\n"
              "where the build result can then be uploaded to the repository through the API.\n")

store_class = RemoteAptlyStore  # type: Type[RemoteAptlyStore]
<|endoftext|>


<commit_before>from __future__ import print_function, absolute_import, unicode_literals, division
import json
from boto.sts.credentials import Credentials
from boto.sts.credentials import AssumedRole
from alppaca import NoCredentialsFoundException

from mock import patch, Mock

from alppaca.compat import OrderedDict, unittest
from alppaca.assume_role import AssumedRoleCredentialsProvider

ROLE = 'my_role'
ROLE_ARN = 'arn:aws:iam::123456789012:role/%s' % ROLE
ANOTHER_EXPIRATION = "NEW_EXPI"
ANOTHER_TOKEN = "NEW_TOKEN"
ANOTHER_SECRET = "NEW_SECRET"
ANOTHER_KEY = "NEW_KEY"

class AssumeRoleCredentialsProviderTest(unittest.TestCase):

    def setUp(self):
        self.credentials_provider_mock = Mock()
        self.provider = AssumedRoleCredentialsProvider(self.credentials_provider_mock, ROLE_ARN)

    def test_should_raise_exception_for_incomplete_given_credentials(self):
        self.credentials_provider_mock.get_credentials_for_all_roles.return_value = None
        with self.assertRaises(NoCredentialsFoundException):
            self.provider.get_credentials_for_all_roles()

    @patch('alppaca.assume_role.connect_to_region')
    def test_should_give_credentials(self, sts_mock):
        self.credentials_provider_mock.get_credentials_for_all_roles.return_value = {
            'ims_role': '{"AccessKeyId": "ACCESS_KEY", "SecretAccessKey": "SECRET", "Token": "MY_TOKEN"}'
        }

        given_credentials = Credentials()
        given_credentials.access_key = ANOTHER_KEY
        given_credentials.secret_key = ANOTHER_SECRET
        given_credentials.session_token = ANOTHER_TOKEN
        given_credentials.expiration = ANOTHER_EXPIRATION
        given_credentials_string = json.dumps({
            "AccessKeyId": ANOTHER_KEY,
            "SecretAccessKey": ANOTHER_SECRET,
            "Token": ANOTHER_TOKEN,
            "Expiration": ANOTHER_EXPIRATION
        })

        sts_mock.return_value.assume_role.return_value = AssumedRole(credentials=given_credentials)

        credentials = self.provider.get_credentials_for_all_roles()
        self.assertEqual(given_credentials_string, credentials[ROLE])

if __name__ == '__main__':
    unittest.main()
<commit_msg>Remove unused import<commit_after>from __future__ import print_function, absolute_import, unicode_literals, division
import json
from boto.sts.credentials import Credentials
from boto.sts.credentials import AssumedRole
from alppaca import NoCredentialsFoundException

from mock import patch, Mock

from alppaca.compat import unittest
from alppaca.assume_role import AssumedRoleCredentialsProvider

ROLE = 'my_role'
ROLE_ARN = 'arn:aws:iam::123456789012:role/%s' % ROLE
ANOTHER_EXPIRATION = "NEW_EXPI"
ANOTHER_TOKEN = "NEW_TOKEN"
ANOTHER_SECRET = "NEW_SECRET"
ANOTHER_KEY = "NEW_KEY"

class AssumeRoleCredentialsProviderTest(unittest.TestCase):

    def setUp(self):
        self.credentials_provider_mock = Mock()
        self.provider = AssumedRoleCredentialsProvider(self.credentials_provider_mock, ROLE_ARN)

    def test_should_raise_exception_for_incomplete_given_credentials(self):
        self.credentials_provider_mock.get_credentials_for_all_roles.return_value = None
        with self.assertRaises(NoCredentialsFoundException):
            self.provider.get_credentials_for_all_roles()

    @patch('alppaca.assume_role.connect_to_region')
    def test_should_give_credentials(self, sts_mock):
        self.credentials_provider_mock.get_credentials_for_all_roles.return_value = {
            'ims_role': '{"AccessKeyId": "ACCESS_KEY", "SecretAccessKey": "SECRET", "Token": "MY_TOKEN"}'
        }

        given_credentials = Credentials()
        given_credentials.access_key = ANOTHER_KEY
        given_credentials.secret_key = ANOTHER_SECRET
        given_credentials.session_token = ANOTHER_TOKEN
        given_credentials.expiration = ANOTHER_EXPIRATION
        given_credentials_string = json.dumps({
            "AccessKeyId": ANOTHER_KEY,
            "SecretAccessKey": ANOTHER_SECRET,
            "Token": ANOTHER_TOKEN,
            "Expiration": ANOTHER_EXPIRATION
        })

        sts_mock.return_value.assume_role.return_value = AssumedRole(credentials=given_credentials)

        credentials = self.provider.get_credentials_for_all_roles()
        self.assertEqual(given_credentials_string, credentials[ROLE])

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>"""
sentry.management.commands.repair
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:copyright: (c) 2012 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import, print_function

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Attempts to repair any invalid data within Sentry'

    def handle(self, **options):
        from django.db.models import Q
        from sentry.constants import RESERVED_ORGANIZATION_SLUGS
        from sentry.models import Organization, Project, Team, ProjectKey
        from sentry.db.models import update
        from sentry.db.models.utils import slugify_instance
        from sentry.utils.query import RangeQuerySetWrapperWithProgressBar

        print("Correcting data on organizations")
        queryset = Organization.objects.filter(
            slug__isnull=True,
        )
        for org in RangeQuerySetWrapperWithProgressBar(queryset):
            slugify_instance(org, org.name, RESERVED_ORGANIZATION_SLUGS)
            org.save()

        # Create teams for any projects that are missing them
        print("Correcting data on projects")
        queryset = Project.objects.filter(
            Q(team__isnull=True) | Q(organization__isnull=True),
        ).select_related('owner')
        for project in RangeQuerySetWrapperWithProgressBar(queryset):
            if not project.team:
                organization = Organization(
                    name=project.name,
                    owner=project.owner,
                )
                slugify_instance(organization, organization.name, RESERVED_ORGANIZATION_SLUGS)
                organization.save()

                team = Team(
                    name=project.name,
                    owner=project.owner,
                    oprganization=organization,
                )
                slugify_instance(team, team.name, RESERVED_ORGANIZATION_SLUGS)
                team.save()

            update(project, organization=team.organization, team=team)

        # Create missing project keys
        print("Creating missing project keys")
        queryset = Team.objects.all()
        for team in RangeQuerySetWrapperWithProgressBar(queryset):
            for project in team.project_set.all():
                try:
                    ProjectKey.objects.get_or_create(
                        project=project,
                    )
                except ProjectKey.MultipleObjectsReturned:
                    pass
<commit_msg>Remove unused behavior from repair<commit_after>"""
sentry.management.commands.repair
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:copyright: (c) 2012 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import, print_function

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Attempts to repair any invalid data within Sentry'

    def handle(self, **options):
        from sentry.models import Project, ProjectKey
        from sentry.utils.query import RangeQuerySetWrapperWithProgressBar

        # Create missing project keys
        print("Creating missing project keys")
        queryset = Project.objects.all()
        for project in RangeQuerySetWrapperWithProgressBar(queryset):
            try:
                ProjectKey.objects.get_or_create(
                    project=project,
                )
            except ProjectKey.MultipleObjectsReturned:
                pass
<|endoftext|>


<commit_before>import os
import subprocess
import json
import sublime
from hashlib import sha1

if int(sublime.version()) >= 3000:
    from .base_command import BaseCommand
else:
    from base_command import BaseCommand

class GulpCommand(BaseCommand):
    package_name = "Gulp"
    cache_file_name = ".sublime-gulp.cache"

    def work(self):
        self.set_instance_variables()
        self.list_gulp_files()

    def set_instance_variables(self):
        self.gulp_files = []
        self.env = Env(self.settings)

    def list_gulp_files(self):
        self.folders = []
        for folder_path in self.window.folders():
            self.folders.append(folder_path)
            self.append_to_gulp_files(folder_path)
        if len(self.gulp_files) > 0:
            self.choose_file()
        else:
            sublime.error_message("gulpfile.js or gulpfile.coffee not found!")

    def append_to_gulp_files(self, path):
        if os.path.exists(os.path.join(path, "gulpfile.js")):
            self.gulp_files.append(os.path.join(path, "gulpfile.js"))
        elif os.path.exists(os.path.join(path, "gulpfile.coffee")):
            self.gulp_files.append(os.path.join(path, "gulpfile.coffee"))

    def choose_file(self):
        if len(self.gulp_files) == 1:
            self.show_tasks_from_gulp_file(0)
        else:
            self.window.show_quick_panel(self.gulp_files, self.show_tasks_from_gulp_file)

    def show_tasks_from_gulp_file(self, file_index):
        if file_index > -1:
            self.working_dir = os.path.dirname(self.gulp_files[file_index])
            self.tasks = self.list_tasks()
            if self.tasks is not None:
                self.show_quick_panel(self.tasks, self.run_gulp_task)

    def list_tasks(self):
        try:
            self.callcount = 0
            json_result = self.fetch_json()
        except TypeError as e:
            sublime.error_message("SublimeGulp: JSON  cache (.sublime-gulp.cache) is malformed.\nCould not read available tasks\n")
        else:
            tasks = [[name, self.dependencies_text(task)] for name, task in json_result.items()]
            return sorted(tasks, key = lambda task: task)

    def dependencies_text(self, task):
        return "Dependencies: " + task['dependencies'] if task['dependencies'] else ""

    # Refactor
    def fetch_json(self):
        jsonfilename = os.path.join(self.working_dir, self.cache_file_name)
        gulpfile = os.path.join(self.working_dir, "gulpfile.js") # .coffee ?
        data = None

        if os.path.exists(jsonfilename):
            filesha1 = Security.hashfile(gulpfile)
            json_data = open(jsonfilename)

            try:
                data = json.load(json_data)
                if data[gulpfile]["sha1"] == filesha1:
                    return data[gulpfile]["tasks"]
            finally:
                json_data.close()

        self.callcount += 1

        if self.callcount == 1:
            return self.write_to_cache()

        if data is None:
            raise TypeError("Could not write to cache gulpfile")

        raise TypeError("Sha1 from gulp cache ({0}) is not equal to calculated ({1})".format(data[gulpfile]["sha1"], filesha1))

    def write_to_cache(self):
        package_path = os.path.join(sublime.packages_path(), self.package_name)

        args = r'node %s/write_tasks_to_cache.js' % package_path # ST2?

        write_to_cache = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env.get_path_with_exec_args(), cwd=self.working_dir, shell=True)
        (stdout, stderr) = write_to_cache.communicate()

        if 127 == write_to_cache.returncode:
            sublime.error_message("\"node\" command not found.\nPlease be sure to have node installed and in your PATH.")
            return

        return self.fetch_json()

    def run_gulp_task(self, task_index):
        if task_index > -1:
            path = self.env.get_path()
            exec_args = {
                'cmd': "gulp " + self.tasks[task_index][0],
                'shell': True,
                'working_dir': self.working_dir,
                'path': path
            }
            self.window.run_command("exec", exec_args)

class GulpKillCommand(BaseCommand):
    def run(self):
        self.window.run_command("exec", { "kill": True })

class Env():
    def __init__(self, settings):
        self.exec_args = settings.get('exec_args', False)

    def get_path(self):
        path = os.environ['PATH']
        if self.exec_args:
            path = exec_args.get('path', os.environ['PATH'])
        return str(path)

    def get_path_with_exec_args(self):
        env = os.environ.copy()
        if self.exec_args:
            path = str(exec_args.get('path', ''))
            if path:
                env['PATH'] = path
        return env

class Security():
    @classmethod
    def hashfile(cls, filename):
        with open(filename, mode='rb') as f:
            filehash = sha1()
            content = f.read();
            filehash.update(str("blob " + str(len(content)) + "\0").encode('UTF-8'))
            filehash.update(content)
            return filehash.hexdigest()
<commit_msg>First implementation<commit_after>import sublime
import os
import signal, subprocess
import json
from hashlib import sha1

if int(sublime.version()) >= 3000:
    from .base_command import BaseCommand
else:
    from base_command import BaseCommand

class GulpCommand(BaseCommand):
    package_name = "Gulp"
    cache_file_name = ".sublime-gulp.cache"

    def work(self):
        self.set_instance_variables()
        self.list_gulp_files()

    def set_instance_variables(self):
        self.gulp_files = []
        self.env = Env(self.settings)

    def list_gulp_files(self):
        self.folders = []
        for folder_path in self.window.folders():
            self.folders.append(folder_path)
            self.append_to_gulp_files(folder_path)
        if len(self.gulp_files) > 0:
            self.choose_file()
        else:
            sublime.error_message("gulpfile.js or gulpfile.coffee not found!")

    def append_to_gulp_files(self, path):
        if os.path.exists(os.path.join(path, "gulpfile.js")):
            self.gulp_files.append(os.path.join(path, "gulpfile.js"))
        elif os.path.exists(os.path.join(path, "gulpfile.coffee")):
            self.gulp_files.append(os.path.join(path, "gulpfile.coffee"))

    def choose_file(self):
        if len(self.gulp_files) == 1:
            self.show_tasks_from_gulp_file(0)
        else:
            self.window.show_quick_panel(self.gulp_files, self.show_tasks_from_gulp_file)

    def show_tasks_from_gulp_file(self, file_index):
        if file_index > -1:
            self.working_dir = os.path.dirname(self.gulp_files[file_index])
            self.tasks = self.list_tasks()
            if self.tasks is not None:
                self.show_quick_panel(self.tasks, self.run_gulp_task)

    def list_tasks(self):
        try:
            self.callcount = 0
            json_result = self.fetch_json()
        except TypeError as e:
            sublime.error_message("SublimeGulp: JSON  cache (.sublime-gulp.cache) is malformed.\nCould not read available tasks\n")
        else:
            tasks = [[name, self.dependencies_text(task)] for name, task in json_result.items()]
            return sorted(tasks, key = lambda task: task)

    def dependencies_text(self, task):
        return "Dependencies: " + task['dependencies'] if task['dependencies'] else ""

    # Refactor
    def fetch_json(self):
        jsonfilename = os.path.join(self.working_dir, self.cache_file_name)
        gulpfile = os.path.join(self.working_dir, "gulpfile.js") # .coffee ?
        data = None

        if os.path.exists(jsonfilename):
            filesha1 = Security.hashfile(gulpfile)
            json_data = open(jsonfilename)

            try:
                data = json.load(json_data)
                if data[gulpfile]["sha1"] == filesha1:
                    return data[gulpfile]["tasks"]
            finally:
                json_data.close()

        self.callcount += 1

        if self.callcount == 1:
            return self.write_to_cache()

        if data is None:
            raise TypeError("Could not write to cache gulpfile")

        raise TypeError("Sha1 from gulp cache ({0}) is not equal to calculated ({1})".format(data[gulpfile]["sha1"], filesha1))

    def write_to_cache(self):
        package_path = os.path.join(sublime.packages_path(), self.package_name)

        args = r'node %s/write_tasks_to_cache.js' % package_path # ST2?

        write_to_cache = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env.get_path_with_exec_args(), cwd=self.working_dir, shell=True)
        (stdout, stderr) = write_to_cache.communicate()

        if 127 == write_to_cache.returncode:
            sublime.error_message("\"node\" command not found.\nPlease be sure to have node installed and in your PATH.")
            return

        return self.fetch_json()

    def run_gulp_task(self, task_index):
        sublime.set_timeout_async(lambda: self.__run__(task_index), 0)

    def __run__(self, task_index):
        if task_index > -1:
            path = self.env.get_path()
            exec_args = {
                'cmd': "gulp " + self.tasks[task_index][0],
                # 'shell': True,
                # 'working_dir': self.working_dir,
                'path': path
            }
            # self.window.run_command("exec", exec_args)
            proc = subprocess.Popen(exec_args['cmd'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env.get_path_with_exec_args(), cwd=self.working_dir, shell=True, preexec_fn=os.setsid)
            ProcessCache.add(proc)
            for line in iter(proc.stdout.readline, ''):
                print(line)
            (stdout, stderr) = proc.communicate()

class GulpKillCommand(BaseCommand):
    def run(self):
        # self.window.run_command("exec", { "kill": True })
        ProcessCache.each(self.kill)
        ProcessCache.clear()

    def kill(self, proc):
        try:
            os.killpg(proc.pid, signal.SIGTERM)
        except ProcessLookupError:
            print("Process not found")

# This implementation still has problems
# 1. It isn't cross-platform
# 2. It queues tasks, so if watch is running and every other task will get executed after watch is killed
# 3. It can frezee sublime!
class ProcessCache():
    _procs = []

    @classmethod
    def add(cls, proc):
       cls._procs.append(proc)

    @classmethod
    def each(cls, fn):
        for proc in cls._procs:
            fn(proc)

    @classmethod
    def clear(cls):
        del cls._procs[:]

class Env():
    def __init__(self, settings):
        self.exec_args = settings.get('exec_args', False)

    def get_path(self):
        path = os.environ['PATH']
        if self.exec_args:
            path = exec_args.get('path', os.environ['PATH'])
        return str(path)

    def get_path_with_exec_args(self):
        env = os.environ.copy()
        if self.exec_args:
            path = str(exec_args.get('path', ''))
            if path:
                env['PATH'] = path
        return env

class Security():
    @classmethod
    def hashfile(cls, filename):
        with open(filename, mode='rb') as f:
            filehash = sha1()
            content = f.read();
            filehash.update(str("blob " + str(len(content)) + "\0").encode('UTF-8'))
            filehash.update(content)
            return filehash.hexdigest()
<|endoftext|>


<commit_before><commit_msg>more arabic...<commit_after><|endoftext|>


<commit_before>"""
python-gumtree

Gumtree scraper written in Python

Copyright 2013 Oli Allen <oli@oliallen.com>

THIS SOFTWARE IS SUPPLIED WITHOUT WARRANTY OF ANY KIND, AND MAY BE
COPIED, MODIFIED OR DISTRIBUTED IN ANY WAY, AS LONG AS THIS NOTICE
AND ACKNOWLEDGEMENT OF AUTHORSHIP REMAIN.
"""

USER_AGENT = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"

import requests
from bs4 import BeautifulSoup

class SearchListing:
    """
    A gumtree search result set containing GTItem objects
    """

    def __init__(self, category, query="", location=""):
        self.category = category
        self.query = query
        self.location = location
        self.listing_results = self.doSearch()

    def __str__(self):
        return "Search listing"

    def doSearch(self):
        """
        Performs the search against gumtree
        """

        request_headers = {'User-agent': USER_AGENT,}

        request = requests.get("http://www.gumtree.com/search?q=%s&search_location=%s&category=%s" % (self.query, self.location, self.category), headers=request_headers)

        if request.status_code == 200:
            # Got a valid response

            listing_results = []

            souped = BeautifulSoup(request.text, "html5lib")
            for listings_wrapper in souped.find_all("ul", class_="ad-listings"):
                for listing in listings_wrapper.find_all("li", class_="offer-sale"):
                    title = listing.find("a", class_="description").get("title")
                    item_instance = GTItem(title=title)
                    item_instance.price = listing.find("span", class_="price").string
                    item_instance.summary = listing.find("div", class_="ad-description").find("span").string
                    item_instance.location =  listing.find("span", class_="location").string
                    item_instance.thumbnail = listing.find("img", class_="thumbnail").get("src")
                    item_instance.adref = listing.find("div", class_="ad-save").get("data-ad-id")
                    listing_results.append(item_instance)
            return listing_results
        else:
            # TODO: Add error handling
            print "Server returned code %s" % request.status_code
            return []

class GTItem:
    """
    An individual gumtree item
    """
    def __init__(self, title, summary="", description="", thumbnail="", price="", location="", adref="", url="", contact_name="", contact_number=""):
        self.title = title
        self.summary = summary
        self.description = description
        self.thumbnail = thumbnail
        self.price = price
        self.location = location
        self.adref = adref
        self.url = url
        self.contact_name = contact_name
        self.contact_number = contact_number

    def __str__(self):
        return self.title
<commit_msg>Moved all licence infromation to LICENSE file<commit_after>"""
python-gumtree

Gumtree scraper written in Python

Copyright 2013 Oli Allen <oli@oliallen.com>
"""

USER_AGENT = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"

import requests
from bs4 import BeautifulSoup

class SearchListing:
    """
    A gumtree search result set containing GTItem objects
    """

    def __init__(self, category, query="", location=""):
        self.category = category
        self.query = query
        self.location = location
        self.listing_results = self.doSearch()

    def __str__(self):
        return "Search listing"

    def doSearch(self):
        """
        Performs the search against gumtree
        """

        request_headers = {'User-agent': USER_AGENT,}

        request = requests.get("http://www.gumtree.com/search?q=%s&search_location=%s&category=%s" % (self.query, self.location, self.category), headers=request_headers)

        if request.status_code == 200:
            # Got a valid response

            listing_results = []

            souped = BeautifulSoup(request.text, "html5lib")
            for listings_wrapper in souped.find_all("ul", class_="ad-listings"):
                for listing in listings_wrapper.find_all("li", class_="offer-sale"):
                    title = listing.find("a", class_="description").get("title")
                    item_instance = GTItem(title=title)
                    item_instance.price = listing.find("span", class_="price").string
                    item_instance.summary = listing.find("div", class_="ad-description").find("span").string
                    item_instance.location =  listing.find("span", class_="location").string
                    item_instance.thumbnail = listing.find("img", class_="thumbnail").get("src")
                    item_instance.adref = listing.find("div", class_="ad-save").get("data-ad-id")
                    listing_results.append(item_instance)
            return listing_results
        else:
            # TODO: Add error handling
            print "Server returned code %s" % request.status_code
            return []

class GTItem:
    """
    An individual gumtree item
    """
    def __init__(self, title, summary="", description="", thumbnail="", price="", location="", adref="", url="", contact_name="", contact_number=""):
        self.title = title
        self.summary = summary
        self.description = description
        self.thumbnail = thumbnail
        self.price = price
        self.location = location
        self.adref = adref
        self.url = url
        self.contact_name = contact_name
        self.contact_number = contact_number

    def __str__(self):
        return self.title
<|endoftext|>


<commit_before>{
  "includes": [
      "common.gypi"
  ],
  "targets": [
    {
      "target_name": "tests",
      "type": "executable",
      "sources": [
        "<!@(find ./test/ -name '*.cpp' ! -name 'writer_tests.cpp' ! -name 'writer_test_cases.cpp' ! -name 'testcase.cpp')"
      ],
      "include_dirs": [
        "./include/",
        "./test/include/"
      ]
    },
    {
      "target_name": "writer_tests",
      "type": "executable",
      "sources": [
        "test/writer_tests.cpp",
        "<!@(find ./test/ -name 'writer_test_cases.cpp')",
        "<!@(find include/protozero/ -name '*.hpp' ! -name 'config.hpp' ! -name 'pbf_builder.hpp' ! -name 'pbf_message.hpp' ! -name 'version.hpp')",
        "<!@(find ./test/ -name '*.pb.cc')",
      ],
      "include_dirs": [
        ".",
        "./include/",
        "./test/include/",
        "./deps/protobuf/include"
      ],
      "libraries" : [
        "./deps/protobuf/$(PlatformTarget)/$(Configuration)/libprotobuf-lite.lib"
      ]
    }
  ]
}
<commit_msg>Fix paths in gyp config<commit_after>{
  "includes": [
      "common.gypi"
  ],
  "targets": [
    {
      "target_name": "tests",
      "type": "executable",
      "sources": [
        "<!@(find ../test/ -name '*.cpp' ! -name 'writer_tests.cpp' ! -name 'writer_test_cases.cpp' ! -name 'testcase.cpp')"
      ],
      "include_dirs": [
        "../include/",
        "../test/include/"
      ]
    },
    {
      "target_name": "writer_tests",
      "type": "executable",
      "sources": [
        "../test/writer_tests.cpp",
        "<!@(find ../test/ -name 'writer_test_cases.cpp')",
        "<!@(find ../include/protozero/ -name '*.hpp' ! -name 'config.hpp' ! -name 'pbf_builder.hpp' ! -name 'pbf_message.hpp' ! -name 'version.hpp')",
        "<!@(find ../test/ -name '*.pb.cc')",
      ],
      "include_dirs": [
        "../",
        "../include/",
        "../test/include/",
        "../deps/protobuf/include"
      ],
      "libraries" : [
        "../deps/protobuf/$(PlatformTarget)/$(Configuration)/libprotobuf-lite.lib"
      ]
    }
  ]
}
<|endoftext|>