<commit_before>from bankbarcode import BankBarcode
from decimal import Decimal

class Recibo(BankBarcode):

    def _check_entity(self, value):
        name = 'entity'
        expected_length = 8
        description = 'entity should be a NIF/CIF, without the letter'
        return self._check_length(name, value, expected_length, description)

    def _check_suffix(self, value):
        name = 'suffix'
        expected_length = 3
        description = 'suffix lenth should be 3'
        return self._check_length(name, value, expected_length, description)

    def _check_ref(self, value):
        name = 'ref'
        expected_length = 11
        description = 'ref lenth should be 11'
        return self._check_length(name, value, expected_length, description)

    def _check_notice(self, value):
        name = 'notice'
        expected_length = 6
        description = 'notice lenth should be 6'
        return self._check_length(name, value, expected_length, description)

    def _check_amount(self, amount):
        name = 'amount'
        decimal = Decimal(amount)
        if decimal.as_tuple().exponent < -2:
            raise ValueError('{} have more than 2 decimals'.format(name))
        if decimal > 99999999.99:
            raise ValueError('{} is too big'.format(name))
        value = unicode(int(decimal * 100)).zfill(10)
        expected_length = 10
        description = 'amount lenth should be 10'
        return self._check_length(name, value, expected_length, description)

class Recibo507(Recibo):

    def __init__(self, entity, suffix, ref, notice, amount):

        if self._check_entity(entity):
            self.entity = entity

        if self._check_suffix(suffix):
            self.suffix = suffix

        if self._check_ref(ref):
            self.ref = ref

        if self._check_notice(notice):
            self.notice = notice

        if self._check_amount(amount):
            self.amount = amount

    def checksum(self):
        amount100 = int(Decimal(self.amount) * 100)
        sum = \
            int(self.entity) \
            + int(self.suffix) \
            + int(self.ref) \
            + int(self.notice) \
            + amount100
        decimals = int(Decimal(sum) / 97 % 1 * 100)
        return unicode(100 - decimals).zfill(2)

    def code(self):
        id_application = u'90'
        format_type = u'507'
        parity = u'0'

        amount100 = Decimal(self.amount) * 100

        code = \
            id_application.zfill(2) + \
            format_type.zfill(3) + \
            self.entity.zfill(8) + \
            self.suffix.zfill(3) + \
            self.ref.zfill(11) + \
            self.checksum() + \
            self.notice.zfill(6) + \
            unicode(int(amount100)).zfill(10) + \
            parity
        return code
<commit_msg>use property and setter decorations<commit_after>from bankbarcode import BankBarcode
from decimal import Decimal

class Recibo(BankBarcode):

    def _check_entity(self, value):
        name = 'entity'
        expected_length = 8
        description = 'entity should be a NIF/CIF, without the letter'
        return self._check_length(name, value, expected_length, description)

    def _check_suffix(self, value):
        name = 'suffix'
        expected_length = 3
        description = 'suffix lenth should be 3'
        return self._check_length(name, value, expected_length, description)

    def _check_ref(self, value):
        name = 'ref'
        expected_length = 11
        description = 'ref lenth should be 11'
        return self._check_length(name, value, expected_length, description)

    def _check_notice(self, value):
        name = 'notice'
        expected_length = 6
        description = 'notice lenth should be 6'
        return self._check_length(name, value, expected_length, description)

    def _check_amount(self, amount):
        name = 'amount'
        decimal = Decimal(amount)
        if decimal.as_tuple().exponent < -2:
            raise ValueError('{} have more than 2 decimals'.format(name))
        if decimal > 99999999.99:
            raise ValueError('{} is too big'.format(name))
        value = unicode(int(decimal * 100)).zfill(10)
        expected_length = 10
        description = 'amount lenth should be 10'
        return self._check_length(name, value, expected_length, description)

class Recibo507(Recibo):

    def __init__(self, entity, suffix, ref, notice, amount):
        self.entity = entity
        self.suffix = suffix
        self.ref = ref
        self.notice = notice
        self.amount = amount

    @property
    def entity(self):
        return self._entity.zfill(8)

    @entity.setter
    def entity(self, value):
        if self._check_entity(value):
            self._entity = value

    @property
    def suffix(self):
        return self._suffix.zfill(3)

    @suffix.setter
    def suffix(self, value):
        if self._check_suffix(value):
            self._suffix = value

    @property
    def ref(self):
        return self._ref.zfill(11)

    @ref.setter
    def ref(self, value):
        if self._check_ref(value):
            self._ref = value

    @property
    def notice(self):
        return self._notice.zfill(6)

    @notice.setter
    def notice(self, value):
        if self._check_notice(value):
            self._notice = value

    @property
    def amount(self):
        return self._amount.zfill(10)

    @amount.setter
    def amount(self, value):
        if self._check_amount(value):
            self._amount = value

    def checksum(self):
        amount100 = int(Decimal(self.amount) * 100)
        sum = \
            int(self.entity) \
            + int(self.suffix) \
            + int(self.ref) \
            + int(self.notice) \
            + amount100
        decimals = int(Decimal(sum) / 97 % 1 * 100)
        return unicode(100 - decimals).zfill(2)

    def code(self):
        id_application = u'90'
        format_type = u'507'
        parity = u'0'

        amount100 = Decimal(self.amount) * 100

        code = \
            id_application.zfill(2) + \
            format_type.zfill(3) + \
            self.entity.zfill(8) + \
            self.suffix.zfill(3) + \
            self.ref.zfill(11) + \
            self.checksum() + \
            self.notice.zfill(6) + \
            unicode(int(amount100)).zfill(10) + \
            parity
        return code
<|endoftext|>


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

"""
This module implements an interface to the Henkelmann et al.'s excellent
Fortran code for calculating a Bader charge analysis.

This module depends on a compiled bader executable available in the path.
Please download the library at http://theory.cm.utexas.edu/vasp/bader/ and
follow the instructions to compile the executable.

If you use this module, please cite the following:

G. Henkelman, A. Arnaldsson, and H. Jonsson, "A fast and robust algorithm for
Bader decomposition of charge density", Comput. Mater. Sci. 36, 254-360 (2006).
"""

from __future__ import division

__author__ = "shyuepingong"
__version__ = "0.1"
__maintainer__ = "Shyue Ping Ong"
__email__ = "shyuep@gmail.com"
__status__ = "Beta"
__date__ = "4/5/13"

import os
import subprocess
import tempfile
import shutil

class BaderAnalysis(object):
    """
    Bader analysis for a CHGCAR.

    .. attribute: data

        Atomic data parsed from bader analysis. Essentially a list of dicts
        of the form::

        [
            {
                "dist": 8.769,
                "min": 0.8753,
                "charge": 7.4168,
                "y": 1.1598,
                "x": 0.0079,
                "z": 0.8348
            },
            ...
        ]

    .. attribute: vacuum_volume

        Vacuum volume of the Bader analysis.

    .. attribute: vacuum_charge

        Vacuum charge of the Bader analysis.

    .. attribute: nelectrons

        Number of electrons of the Bader analysis.
    """

    def __init__(self, filename):
        """
        Args:
            filename:
                The filename of the CHGCAR.
        """
        temp_dir = tempfile.mkdtemp()
        try:
            shutil.copy(filename, os.path.join(temp_dir, "CHGCAR"))
            current_dir = os.getcwd()
            os.chdir(temp_dir)
            rs = subprocess.Popen(["bader", "-p", "atom_index", "-p", "all_atom",
                                   "CHGCAR"],
                                  stdout=subprocess.PIPE,
                                  stdin=subprocess.PIPE, close_fds=True)
            rs.communicate()
            data = []
            with open("ACF.dat") as f:
                raw = f.readlines()
                headers = [s.lower() for s in raw.pop(0).split()]
                raw.pop(0)
                while True:
                    l = raw.pop(0).strip()
                    if l.startswith("-"):
                        break
                    vals = map(float, l.split()[1:])
                    data.append(dict(zip(headers[1:], vals)))
                for l in raw:
                    toks = l.strip().split(":")
                    if toks[0] == "VACUUM CHARGE":
                        self.vacuum_charge = float(toks[1])
                    elif toks[0] == "VACUUM VOLUME":
                        self.vacuum_volume = float(toks[1])
                    elif toks[0] == "NUMBER OF ELECTRONS":
                        self.nelectrons = float(toks[1])
            self.data = data
            os.chdir(current_dir)
        except Exception as ex:
            print str(ex)
        finally:
            shutil.rmtree(temp_dir)

if __name__ == "__main__":
    a = BaderAnalysis("../../test_files/CHGCAR.noncubic")<commit_msg>Simplify bader caller.<commit_after>#!/usr/bin/env python

"""
This module implements an interface to the Henkelmann et al.'s excellent
Fortran code for calculating a Bader charge analysis.

This module depends on a compiled bader executable available in the path.
Please download the library at http://theory.cm.utexas.edu/vasp/bader/ and
follow the instructions to compile the executable.

If you use this module, please cite the following:

G. Henkelman, A. Arnaldsson, and H. Jonsson, "A fast and robust algorithm for
Bader decomposition of charge density", Comput. Mater. Sci. 36, 254-360 (2006).
"""

from __future__ import division

__author__ = "shyuepingong"
__version__ = "0.1"
__maintainer__ = "Shyue Ping Ong"
__email__ = "shyuep@gmail.com"
__status__ = "Beta"
__date__ = "4/5/13"

import os
import subprocess
import tempfile
import shutil

class BaderAnalysis(object):
    """
    Bader analysis for a CHGCAR.

    .. attribute: data

        Atomic data parsed from bader analysis. Essentially a list of dicts
        of the form::

        [
            {
                "dist": 8.769,
                "min": 0.8753,
                "charge": 7.4168,
                "y": 1.1598,
                "x": 0.0079,
                "z": 0.8348
            },
            ...
        ]

    .. attribute: vacuum_volume

        Vacuum volume of the Bader analysis.

    .. attribute: vacuum_charge

        Vacuum charge of the Bader analysis.

    .. attribute: nelectrons

        Number of electrons of the Bader analysis.
    """

    def __init__(self, filename):
        """
        Args:
            filename:
                The filename of the CHGCAR.
        """
        temp_dir = tempfile.mkdtemp()
        try:
            shutil.copy(filename, os.path.join(temp_dir, "CHGCAR"))
            current_dir = os.getcwd()
            os.chdir(temp_dir)
            rs = subprocess.Popen(["bader", "CHGCAR"],
                                  stdout=subprocess.PIPE,
                                  stdin=subprocess.PIPE, close_fds=True)
            rs.communicate()
            data = []
            with open("ACF.dat") as f:
                raw = f.readlines()
                headers = [s.lower() for s in raw.pop(0).split()]
                raw.pop(0)
                while True:
                    l = raw.pop(0).strip()
                    if l.startswith("-"):
                        break
                    vals = map(float, l.split()[1:])
                    data.append(dict(zip(headers[1:], vals)))
                for l in raw:
                    toks = l.strip().split(":")
                    if toks[0] == "VACUUM CHARGE":
                        self.vacuum_charge = float(toks[1])
                    elif toks[0] == "VACUUM VOLUME":
                        self.vacuum_volume = float(toks[1])
                    elif toks[0] == "NUMBER OF ELECTRONS":
                        self.nelectrons = float(toks[1])
            self.data = data
            os.chdir(current_dir)
        except Exception as ex:
            print str(ex)
        finally:
            shutil.rmtree(temp_dir)

if __name__ == "__main__":
    a = BaderAnalysis("../../test_files/CHGCAR.noncubic")<|endoftext|>


<commit_before>import numpy as np
from barak.utilities import between
from barak.convolve import convolve_psf

class PlotWrapBase(object):
    """ A base class that has all the navigation and smoothing
    keypress events. These need to be connected to the wrapped figure
    of the class inheriting from this with something like:

    def connect(self, fig):
        cids = dict(key=[])
        # the top two are methods of PlotWrapBase
        cids['key'].append(fig.canvas.mpl_connect(
            'key_press_event', self.on_keypress_navigate))
        cids['key'].append(fig.canvas.mpl_connect(
            'key_press_event', self.on_keypress_smooth))
        self.cids.update(cids)
    """
    def __init__(self):
        pass

    def on_keypress_navigate(self, event):
        """ Process a keypress event. Requires attributes self.ax,
        self.fl, self.wa, self.fig
        """
        # Navigation
        if event.key == 'i' and event.inaxes:
            x0,x1 = self.ax.get_xlim()
            x = event.xdata
            dx = abs(x1 - x0)
            self.ax.set_xlim(x - 0.275*dx, x + 0.275*dx)
            self.fig.canvas.draw()
        elif event.key == 'o' and event.inaxes:
            x0,x1 = self.ax.get_xlim()
            x = event.xdata
            dx = abs(x1 - x0)
            self.ax.set_xlim(x - 0.95*dx, x + 0.95*dx)
            self.fig.canvas.draw()
        elif event.key == 'Y' and event.inaxes:
            y0,y1 = self.ax.get_ylim()
            y = event.ydata
            dy = abs(y1 - y0)
            self.ax.set_ylim(y0 - 0.05*dy, y1 + 0.4*dy)
            self.fig.canvas.draw()
        elif event.key == 'y' and event.inaxes:
            x0,x1 = self.ax.get_xlim()
            y0,y1 = get_flux_plotrange(self.fl[between(self.wa, x0, x1)])
            self.ax.set_ylim(y0, y1)
            self.fig.canvas.draw()
        elif event.key == ']':
            x0,x1 = self.ax.get_xlim()
            dx = abs(x1 - x0)
            self.ax.set_xlim(x1 - 0.1*dx, x1 + 0.9*dx)
            self.fig.canvas.draw()
        elif event.key == '[':
            x0,x1 = self.ax.get_xlim()
            dx = abs(x1 - x0)
            self.ax.set_xlim(x0 - 0.9*dx, x0 + 0.1*dx)
            self.fig.canvas.draw()
        elif event.key == 'w':
            self.ax.set_xlim(self.wa[0], self.wa[-1])
            y0,y1 = get_flux_plotrange(self.fl)
            self.ax.set_ylim(y0, y1)
            self.fig.canvas.draw()
        elif event.key == 'b' and event.inaxes:
            y0, y1 = self.ax.get_ylim()
            self.ax.set_ylim(event.ydata, y1)
            self.fig.canvas.draw()
        elif event.key == 't' and event.inaxes:
            y0, y1 = self.ax.get_ylim()
            self.ax.set_ylim(y0, event.ydata)
            self.fig.canvas.draw()
        elif event.key == 'l' and event.inaxes:
            x0, x1 = self.ax.get_xlim()
            self.ax.set_xlim(event.xdata, x1)
            self.fig.canvas.draw()
        elif event.key == 'r' and event.inaxes:
            x0, x1 = self.ax.get_xlim()
            self.ax.set_xlim(x0, event.xdata)
            self.fig.canvas.draw()

    def on_keypress_smooth(self, event):
        """ Smooth the flux with a gaussian. Requires attributes
        self.fl and self.nsmooth, self.artists['fl'] and self.fig."""
        if event.key == 'S':
            if self.nsmooth > 0:
                self.nsmooth += 0.5
            else:
                self.nsmooth = 1
            sfl = convolve_psf(self.fl, self.nsmooth)
            self.artists['fl'].set_ydata(sfl)
            self.fig.canvas.draw()
        elif event.key == 'U':
            self.nsmooth = 0
            self.artists['fl'].set_ydata(self.fl)
            self.fig.canvas.draw()
<commit_msg>tweaks to interactive_plot.py<commit_after>""" Classes useful for making interactive plots.
"""
import numpy as np
from barak.utilities import between
from barak.plot import get_flux_plotrange
from barak.convolve import convolve_psf
from barak.interp import AkimaSpline
from barak.io import savejson

class PlotWrapBase(object):
    """ A base class that has all the navigation and smoothing
    keypress events. These need to be connected to the wrapped figure
    of the class inheriting from this with something like:

    ** You need to define the following attributes **

    self.wa, self.fl    Spectrum wavelength and flux
    self.nsmooth        integer > 0 that determines the smoothing
    self.ax             Axes where specturm is plotted
    self.fig            Figure which holds the axes.
    self.artists['fl']  The Matplotlib line artist that represents the flux.

    def connect(self, fig):
        cids = dict(key=[])
        # the top two are methods of PlotWrapBase
        cids['key'].append(fig.canvas.mpl_connect(
            'key_press_event', self.on_keypress_navigate))
        cids['key'].append(fig.canvas.mpl_connect(
            'key_press_event', self.on_keypress_smooth))
        self.cids.update(cids)
    """
    _help_string = """
i,o          Zoom in/out x limits
y            Zoom out y limits
Y            Guess y limits
t,b          Set y top/bottom limit
l,r          Set left/right x limit
[,]          pan left/right
w            Return to original view

S,U          Smooth/unsmooth spectrum
"""

    def __init__(self):
        pass

    def on_keypress_navigate(self, event):
        """ Process a keypress event. Requires attributes self.ax,
        self.fl, self.wa, self.fig
        """
        # Navigation
        if event.key == 'i' and event.inaxes:
            x0,x1 = self.ax.get_xlim()
            x = event.xdata
            dx = abs(x1 - x0)
            self.ax.set_xlim(x - 0.275*dx, x + 0.275*dx)
            self.fig.canvas.draw()
        elif event.key == 'o' and event.inaxes:
            x0,x1 = self.ax.get_xlim()
            x = event.xdata
            dx = abs(x1 - x0)
            self.ax.set_xlim(x - 0.95*dx, x + 0.95*dx)
            self.fig.canvas.draw()
        elif event.key == 'Y' and event.inaxes:
            y0,y1 = self.ax.get_ylim()
            y = event.ydata
            dy = abs(y1 - y0)
            self.ax.set_ylim(y0 - 0.05*dy, y1 + 0.4*dy)
            self.fig.canvas.draw()
        elif event.key == 'y' and event.inaxes:
            x0,x1 = self.ax.get_xlim()
            y0,y1 = get_flux_plotrange(self.fl[between(self.wa, x0, x1)])
            self.ax.set_ylim(y0, y1)
            self.fig.canvas.draw()
        elif event.key == ']':
            x0,x1 = self.ax.get_xlim()
            dx = abs(x1 - x0)
            self.ax.set_xlim(x1 - 0.1*dx, x1 + 0.9*dx)
            self.fig.canvas.draw()
        elif event.key == '[':
            x0,x1 = self.ax.get_xlim()
            dx = abs(x1 - x0)
            self.ax.set_xlim(x0 - 0.9*dx, x0 + 0.1*dx)
            self.fig.canvas.draw()
        elif event.key == 'w':
            self.ax.set_xlim(self.wa[0], self.wa[-1])
            y0,y1 = get_flux_plotrange(self.fl)
            self.ax.set_ylim(y0, y1)
            self.fig.canvas.draw()
        elif event.key == 'b' and event.inaxes:
            y0, y1 = self.ax.get_ylim()
            self.ax.set_ylim(event.ydata, y1)
            self.fig.canvas.draw()
        elif event.key == 't' and event.inaxes:
            y0, y1 = self.ax.get_ylim()
            self.ax.set_ylim(y0, event.ydata)
            self.fig.canvas.draw()
        elif event.key == 'l' and event.inaxes:
            x0, x1 = self.ax.get_xlim()
            self.ax.set_xlim(event.xdata, x1)
            self.fig.canvas.draw()
        elif event.key == 'r' and event.inaxes:
            x0, x1 = self.ax.get_xlim()
            self.ax.set_xlim(x0, event.xdata)
            self.fig.canvas.draw()

    def on_keypress_smooth(self, event):
        """ Smooth the flux with a gaussian. Requires attributes
        self.fl and self.nsmooth, self.artists['fl'] and self.fig."""
        if event.key == 'S':
            if self.nsmooth > 0:
                self.nsmooth += 0.5
            else:
                self.nsmooth = 1
            sfl = convolve_psf(self.fl, self.nsmooth)
            self.artists['fl'].set_ydata(sfl)
            self.fig.canvas.draw()
        elif event.key == 'U':
            self.nsmooth = 0
            self.artists['fl'].set_ydata(self.fl)
            self.fig.canvas.draw()

class PlotWrapBase_Continuum(PlotWrapBase):
    """
    This needs the following attributes defined:

    self.contpoints: List of x,y pairs giving the spline knots
    self.co:         Continuum array
    self.wa:         Wavelength array (sorted low to high)
    self.fl:         Flux array
    self.artists['contpoints']: Matplotlib artist showing the spline knots.
    self.artists['co']:  Matplotlib artist showing the continuum.

    It will also update a self.artists['model'] line using the new
    continuum and the array in self.model, if they exist.

    The knots are saved in the current directory in a file call
    '_knots.json'. This save location and name can be changed using
    the attributes self.outdir and self.name.
    """

    _help_string = PlotWrapBase._help_string + """
3,4          Add (3) or delete (4) a continuum point
"""
    def __init__(self):
        pass

    def update_cont(self):
        """ Sort the continuum points and update continuum artists.
        """
        if not self.contpoints:
            self.artists['contpoints'].set_data([0], [0])
        else:
            self.contpoints = sorted(self.contpoints, key=lambda pt: pt[0])
            cpts = self.contpoints
            self.artists['contpoints'].set_data(list(zip(*cpts)))

            name = '_knots.json'
            if hasattr(self, 'outdir') and hasattr(self, 'name'):
                name = self.outdir + self.name + '_knots.json'
            savejson(name, cpts, overwrite=True)
            if self.co is None:
                self.co = np.empty_like(self.fl)
            if len(cpts) > 2:
                i,j = self.wa.searchsorted([cpts[0][0], cpts[-1][0]])
                spline = AkimaSpline(*list(zip(*cpts)))
                self.co[i:j] = spline(self.wa[i:j])
                self.co[:i] = self.co[i]
                self.co[j:] = self.co[j-1]
            elif len(cpts) > 1:
                wa_pts, pts = zip(*cpts)
                self.co = np.interp(self.wa, wa_pts, pts)
            elif len(cpts) == 1:
                self.co[:] = cpts[0][1]

        if hasattr(self, 'model') and len(self.co) == len(self.model):
            self.artists['model'].set_data(self.wa, self.co * self.model)
        self.artists['co'].set_data(self.wa, self.co)

    def on_keypress_continuum(self, event):
        """ Add and remove continuum points.

        needs

        self.contpoints
        self.fig
        self.ax
        """
        if event.key == '3' and event.inaxes:
            # add a point to contpoints
            x,y = event.xdata, event.ydata
            if not self.contpoints or x not in zip(*self.contpoints)[0]:
                self.contpoints.append((x, y))
                self.update_cont()
            self.fig.canvas.draw()
        elif event.key == '4' and event.inaxes:
            # remove a point from contpoints
            if not self.contpoints:
                'Define a continuum point first!'
            elif len(self.contpoints) == 1:
                self.contpoints = []
            else:
                contx,conty = zip(*self.ax.transData.transform(self.contpoints))
                sep = np.hypot(event.x - np.array(contx),
                               event.y - np.array(conty))
                self.contpoints.remove(self.contpoints[sep.argmin()])
            self.update_cont()
            self.fig.canvas.draw()

<|endoftext|>


<commit_before>import re
from providers.moviedata.provider import MoviedataProvider
from application import ACCESS_KEYS, APPLICATION as APP

IDENTIFIER = "MyAPIfilms"

class Provider(MoviedataProvider):
    def get_url(self, movie):
        parameters = {
            "title": movie["name"].encode("utf-8"),
            "limit": 1,
            "filter": "3",
            "format": "json",
        }
        if "year" in movie and movie["year"]:
            parameters["year"] = movie["year"]
            # Note limits are set before filtering, so with limit 1 we get no hits
            parameters["limit"] = 5

        if IDENTIFIER in ACCESS_KEYS:
            parameters["token"] = ACCESS_KEYS[IDENTIFIER]["TOKEN"]

        return "http://www.myapifilms.com/imdb/title?" + self.urlencode(parameters)

    def fetch_movie_data(self, movie):
        url = self.get_url(movie)
        APP.debug("Fetching url: %s" % url)
        data = self.parse_json(url, path="data.movies")
        for hit in data:
            if hit and "releaseDate" in hit and hit["releaseDate"]:
                return self.transform_data(hit)

        return {}

    def _get_clean_rating(self, data):
        if "rating" not in data:
            return ""

        return re.sub(r"[^\d\.]", "", data["rating"])

    def get_data_mapping(self):
        return {
            "id": "idIMDB",
            "title": lambda data: data["title"].replace(u"\u00a0", ""),
            "plot": "simplePlot",
            "genre": "genres",
            "director": "directors.0.name",
            "country": "countries",
            "language": "languages",
            "runtime": "runtime",
            "released": "releaseDate",
            "age_rating": "rated",
            "year": "year",
            "metacritic_rating": "metascore",
            "imdb_url": "urlIMDB",
            "imdb_poster": "urlPoster",
            "imdb_rating": "rating",
            "imdb_rating_votes": self._get_clean_rating,
        }
<commit_msg>IMDB ratings sometimes has a comma instead of period for decimal numbers.<commit_after>import re
from providers.moviedata.provider import MoviedataProvider
from application import ACCESS_KEYS, APPLICATION as APP

IDENTIFIER = "MyAPIfilms"

class Provider(MoviedataProvider):
    def get_url(self, movie):
        parameters = {
            "title": movie["name"].encode("utf-8"),
            "limit": 1,
            "filter": "3",
            "format": "json",
        }
        if "year" in movie and movie["year"]:
            parameters["year"] = movie["year"]
            # Note limits are set before filtering, so with limit 1 we get no hits
            parameters["limit"] = 5

        if IDENTIFIER in ACCESS_KEYS:
            parameters["token"] = ACCESS_KEYS[IDENTIFIER]["TOKEN"]

        return "http://www.myapifilms.com/imdb/title?" + self.urlencode(parameters)

    def fetch_movie_data(self, movie):
        url = self.get_url(movie)
        APP.debug("Fetching url: %s" % url)
        data = self.parse_json(url, path="data.movies")
        for hit in data:
            if hit and "releaseDate" in hit and hit["releaseDate"]:
                return self.transform_data(hit)

        return {}

    def _get_clean_rating(self, data):
        if "rating" not in data:
            return ""

        rating = data["rating"]
        rating = rating.replace(",", ".")
        return re.sub(r"[^\d\.]", "", data["rating"])

    def get_data_mapping(self):
        return {
            "id": "idIMDB",
            "title": lambda data: data["title"].replace(u"\u00a0", ""),
            "plot": "simplePlot",
            "genre": "genres",
            "director": "directors.0.name",
            "country": "countries",
            "language": "languages",
            "runtime": "runtime",
            "released": "releaseDate",
            "age_rating": "rated",
            "year": "year",
            "metacritic_rating": "metascore",
            "imdb_url": "urlIMDB",
            "imdb_poster": "urlPoster",
            "imdb_rating": self._get_clean_rating,
        }
<|endoftext|>


<commit_before>import datetime
import unittest

from utils import get_lookback

class LookbackTimeTest(unittest.TestCase):
    def test_one_week(self):
        self.assertEqual(get_lookback('1w'), datetime.timedelta(7))

    def test_four_weeks(self):
        self.assertEqual(get_lookback('4w'), datetime.timedelta(28))

    def test_one_month(self):
        with self.assertRaises(TypeError):
            lookback_time = get_lookback('1m')

    def test_no_units(self):
        with self.assertRaises(TypeError):
            lookback_time = get_lookback('666')
<commit_msg>test_utils expects get_lookback's sys.exit()<commit_after>import datetime
import unittest

from utils import get_lookback

class LookbackTimeTest(unittest.TestCase):
    def test_one_week(self):
        self.assertEqual(get_lookback('1w'), datetime.timedelta(7))

    def test_four_weeks(self):
        self.assertEqual(get_lookback('4w'), datetime.timedelta(28))

    def test_one_month(self):
        with self.assertRaises(SystemExit):
            lookback_time = get_lookback('1m')

    def test_no_units(self):
        with self.assertRaises(SystemExit):
            lookback_time = get_lookback('666')
<|endoftext|>


<commit_before># Copyright (c) 2013-2014 Rackspace, 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.

"""
Configuration setup for Barbican.
"""

import logging
import os

from oslo_config import cfg
from oslo_log import log
from oslo_middleware import cors
from oslo_service import _options

from barbican import i18n as u
import barbican.version

MAX_BYTES_REQUEST_INPUT_ACCEPTED = 15000
DEFAULT_MAX_SECRET_BYTES = 10000
KS_NOTIFICATIONS_GRP_NAME = 'keystone_notifications'

context_opts = [
    cfg.StrOpt('admin_role', default='admin',
               help=u._('Role used to identify an authenticated user as '
                        'administrator.')),
    cfg.BoolOpt('allow_anonymous_access', default=False,
                help=u._('Allow unauthenticated users to access the API with '
                         'read-only privileges. This only applies when using '
                         'ContextMiddleware.')),
]

common_opts = [
    cfg.IntOpt('max_allowed_request_size_in_bytes',
               default=MAX_BYTES_REQUEST_INPUT_ACCEPTED),
    cfg.IntOpt('max_allowed_secret_in_bytes',
               default=DEFAULT_MAX_SECRET_BYTES),
]

host_opts = [
    cfg.StrOpt('host_href', default='http://localhost:9311'),
]

db_opts = [
    cfg.StrOpt('sql_connection', secret=True),
    cfg.IntOpt('sql_idle_timeout', default=3600),
    cfg.IntOpt('sql_max_retries', default=60),
    cfg.IntOpt('sql_retry_interval', default=1),
    cfg.BoolOpt('db_auto_create', default=True),
    cfg.IntOpt('max_limit_paging', default=100),
    cfg.IntOpt('default_limit_paging', default=10),
    cfg.StrOpt('sql_pool_class'),
    cfg.BoolOpt('sql_pool_logging', default=False),
    cfg.IntOpt('sql_pool_size'),
    cfg.IntOpt('sql_pool_max_overflow'),
]

retry_opt_group = cfg.OptGroup(name='retry_scheduler',
                               title='Retry/Scheduler Options')

retry_opts = [
    cfg.FloatOpt(
        'initial_delay_seconds', default=10.0,
        help=u._('Seconds (float) to wait before starting retry scheduler')),
    cfg.FloatOpt(
        'periodic_interval_max_seconds', default=10.0,
        help=u._('Seconds (float) to wait between periodic schedule events')),
]

queue_opt_group = cfg.OptGroup(name='queue',
                               title='Queue Application Options')

queue_opts = [
    cfg.BoolOpt('enable', default=False,
                help=u._('True enables queuing, False invokes '
                         'workers synchronously')),
    cfg.StrOpt('namespace', default='barbican',
               help=u._('Queue namespace')),
    cfg.StrOpt('topic', default='barbican.workers',
               help=u._('Queue topic name')),
    cfg.StrOpt('version', default='1.1',
               help=u._('Version of tasks invoked via queue')),
    cfg.StrOpt('server_name', default='barbican.queue',
               help=u._('Server name for RPC task processing server')),
    cfg.IntOpt('asynchronous_workers', default=1,
               help=u._('Number of asynchronous worker processes')),
]

ks_queue_opt_group = cfg.OptGroup(name=KS_NOTIFICATIONS_GRP_NAME,
                                  title='Keystone Notification Options')

ks_queue_opts = [
    cfg.BoolOpt('enable', default=False,
                help=u._('True enables keystone notification listener '
                         ' functionality.')),
    cfg.StrOpt('control_exchange', default='openstack',
               help=u._('The default exchange under which topics are scoped. '
                        'May be overridden by an exchange name specified in '
                        'the transport_url option.')),
    cfg.StrOpt('topic', default='notifications',
               help=u._("Keystone notification queue topic name. This name "
                        "needs to match one of values mentioned in Keystone "
                        "deployment's 'notification_topics' configuration "
                        "e.g."
                        "    notification_topics=notifications, "
                        "    barbican_notifications"
                        "Multiple servers may listen on a topic and messages "
                        "will be dispatched to one of the servers in a "
                        "round-robin fashion. That's why Barbican service "
                        "should have its own dedicated notification queue so "
                        "that it receives all of Keystone notifications.")),
    cfg.BoolOpt('allow_requeue', default=False,
                help=u._('True enables requeue feature in case of notification'
                         ' processing error. Enable this only when underlying '
                         'transport supports this feature.')),
    cfg.StrOpt('version', default='1.0',
               help=u._('Version of tasks invoked via notifications')),
    cfg.IntOpt('thread_pool_size', default=10,
               help=u._('Define the number of max threads to be used for '
                        'notification server processing functionality.')),
]

quota_opt_group = cfg.OptGroup(name='quotas',
                               title='Quota Options')

quota_opts = [
    cfg.IntOpt('quota_secrets',
               default=-1,
               help='Number of secrets allowed per project'),
    cfg.IntOpt('quota_orders',
               default=-1,
               help='Number of orders allowed per project'),
    cfg.IntOpt('quota_containers',
               default=-1,
               help='Number of containers allowed per project'),
    cfg.IntOpt('quota_consumers',
               default=-1,
               help='Number of consumers allowed per project'),
    cfg.IntOpt('quota_cas',
               default=-1,
               help='Number of CAs allowed per project')
]

# Flag to indicate barbican configuration is already parsed once or not
_CONFIG_PARSED_ONCE = False

def parse_args(conf, args=None, usage=None, default_config_files=None):
    global _CONFIG_PARSED_ONCE
    conf(args=args if args else [],
         project='barbican',
         prog='barbican',
         version=barbican.version.__version__,
         usage=usage,
         default_config_files=default_config_files)

    conf.pydev_debug_host = os.environ.get('PYDEV_DEBUG_HOST')
    conf.pydev_debug_port = os.environ.get('PYDEV_DEBUG_PORT')

    # Assign cfg.CONF handle to parsed barbican configuration once at startup
    # only. No need to keep re-assigning it with separate plugin conf usage
    if not _CONFIG_PARSED_ONCE:
        cfg.CONF = conf
        _CONFIG_PARSED_ONCE = True

def new_config():
    conf = cfg.ConfigOpts()
    log.register_options(conf)
    conf.register_opts(context_opts)
    conf.register_opts(common_opts)
    conf.register_opts(host_opts)
    conf.register_opts(db_opts)
    conf.register_opts(_options.eventlet_backdoor_opts)
    conf.register_opts(_options.periodic_opts)

    conf.register_opts(_options.ssl_opts, "ssl")

    conf.register_group(retry_opt_group)
    conf.register_opts(retry_opts, group=retry_opt_group)

    conf.register_group(queue_opt_group)
    conf.register_opts(queue_opts, group=queue_opt_group)

    conf.register_group(ks_queue_opt_group)
    conf.register_opts(ks_queue_opts, group=ks_queue_opt_group)

    conf.register_group(quota_opt_group)
    conf.register_opts(quota_opts, group=quota_opt_group)

    # Update default values from libraries that carry their own oslo.config
    # initialization and configuration.
    set_middleware_defaults()

    return conf

def setup_remote_pydev_debug():
    """Required setup for remote debugging."""

    if CONF.pydev_debug_host and CONF.pydev_debug_port:
        try:
            try:
                from pydev import pydevd
            except ImportError:
                import pydevd

            pydevd.settrace(CONF.pydev_debug_host,
                            port=int(CONF.pydev_debug_port),
                            stdoutToServer=True,
                            stderrToServer=True)
        except Exception:
            LOG.exception('Unable to join debugger, please '
                          'make sure that the debugger processes is '
                          'listening on debug-host \'%s\' debug-port \'%s\'.',
                          CONF.pydev_debug_host, CONF.pydev_debug_port)
            raise

def set_middleware_defaults():
    """Update default configuration options for oslo.middleware."""
    # CORS Defaults
    # TODO(krotscheck): Update with https://review.openstack.org/#/c/285368/
    cfg.set_defaults(cors.CORS_OPTS,
                     allow_headers=['X-Auth-Token',
                                    'X-Openstack-Request-Id',
                                    'X-Project-Id',
                                    'X-Identity-Status',
                                    'X-User-Id',
                                    'X-Storage-Token',
                                    'X-Domain-Id',
                                    'X-User-Domain-Id',
                                    'X-Project-Domain-Id',
                                    'X-Roles'],
                     expose_headers=['X-Auth-Token',
                                     'X-Openstack-Request-Id',
                                     'X-Project-Id',
                                     'X-Identity-Status',
                                     'X-User-Id',
                                     'X-Storage-Token',
                                     'X-Domain-Id',
                                     'X-User-Domain-Id',
                                     'X-Project-Domain-Id',
                                     'X-Roles'],
                     allow_methods=['GET',
                                    'PUT',
                                    'POST',
                                    'DELETE',
                                    'PATCH']
                     )

CONF = new_config()
LOG = logging.getLogger(__name__)
parse_args(CONF)

# Adding global scope dict for all different configs created in various
# modules. In barbican, each plugin module creates its own *new* config
# instance so its error prone to share/access config values across modules
# as these module imports introduce a cyclic dependency. To avoid this, each
# plugin can set this dict after its own config instance is created and parsed.
_CONFIGS = {}

def set_module_config(name, module_conf):
    """Each plugin can set its own conf instance with its group name."""
    _CONFIGS[name] = module_conf

def get_module_config(name):
    """Get handle to plugin specific config instance by its group name."""
    return _CONFIGS[name]
<commit_msg>Enable translations<commit_after># Copyright (c) 2013-2014 Rackspace, 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.

"""
Configuration setup for Barbican.
"""

import logging
import os

from oslo_config import cfg
from oslo_log import log
from oslo_middleware import cors
from oslo_service import _options

from barbican import i18n as u
import barbican.version

MAX_BYTES_REQUEST_INPUT_ACCEPTED = 15000
DEFAULT_MAX_SECRET_BYTES = 10000
KS_NOTIFICATIONS_GRP_NAME = 'keystone_notifications'

context_opts = [
    cfg.StrOpt('admin_role', default='admin',
               help=u._('Role used to identify an authenticated user as '
                        'administrator.')),
    cfg.BoolOpt('allow_anonymous_access', default=False,
                help=u._('Allow unauthenticated users to access the API with '
                         'read-only privileges. This only applies when using '
                         'ContextMiddleware.')),
]

common_opts = [
    cfg.IntOpt('max_allowed_request_size_in_bytes',
               default=MAX_BYTES_REQUEST_INPUT_ACCEPTED),
    cfg.IntOpt('max_allowed_secret_in_bytes',
               default=DEFAULT_MAX_SECRET_BYTES),
]

host_opts = [
    cfg.StrOpt('host_href', default='http://localhost:9311'),
]

db_opts = [
    cfg.StrOpt('sql_connection', secret=True),
    cfg.IntOpt('sql_idle_timeout', default=3600),
    cfg.IntOpt('sql_max_retries', default=60),
    cfg.IntOpt('sql_retry_interval', default=1),
    cfg.BoolOpt('db_auto_create', default=True),
    cfg.IntOpt('max_limit_paging', default=100),
    cfg.IntOpt('default_limit_paging', default=10),
    cfg.StrOpt('sql_pool_class'),
    cfg.BoolOpt('sql_pool_logging', default=False),
    cfg.IntOpt('sql_pool_size'),
    cfg.IntOpt('sql_pool_max_overflow'),
]

retry_opt_group = cfg.OptGroup(name='retry_scheduler',
                               title='Retry/Scheduler Options')

retry_opts = [
    cfg.FloatOpt(
        'initial_delay_seconds', default=10.0,
        help=u._('Seconds (float) to wait before starting retry scheduler')),
    cfg.FloatOpt(
        'periodic_interval_max_seconds', default=10.0,
        help=u._('Seconds (float) to wait between periodic schedule events')),
]

queue_opt_group = cfg.OptGroup(name='queue',
                               title='Queue Application Options')

queue_opts = [
    cfg.BoolOpt('enable', default=False,
                help=u._('True enables queuing, False invokes '
                         'workers synchronously')),
    cfg.StrOpt('namespace', default='barbican',
               help=u._('Queue namespace')),
    cfg.StrOpt('topic', default='barbican.workers',
               help=u._('Queue topic name')),
    cfg.StrOpt('version', default='1.1',
               help=u._('Version of tasks invoked via queue')),
    cfg.StrOpt('server_name', default='barbican.queue',
               help=u._('Server name for RPC task processing server')),
    cfg.IntOpt('asynchronous_workers', default=1,
               help=u._('Number of asynchronous worker processes')),
]

ks_queue_opt_group = cfg.OptGroup(name=KS_NOTIFICATIONS_GRP_NAME,
                                  title='Keystone Notification Options')

ks_queue_opts = [
    cfg.BoolOpt('enable', default=False,
                help=u._('True enables keystone notification listener '
                         ' functionality.')),
    cfg.StrOpt('control_exchange', default='openstack',
               help=u._('The default exchange under which topics are scoped. '
                        'May be overridden by an exchange name specified in '
                        'the transport_url option.')),
    cfg.StrOpt('topic', default='notifications',
               help=u._("Keystone notification queue topic name. This name "
                        "needs to match one of values mentioned in Keystone "
                        "deployment's 'notification_topics' configuration "
                        "e.g."
                        "    notification_topics=notifications, "
                        "    barbican_notifications"
                        "Multiple servers may listen on a topic and messages "
                        "will be dispatched to one of the servers in a "
                        "round-robin fashion. That's why Barbican service "
                        "should have its own dedicated notification queue so "
                        "that it receives all of Keystone notifications.")),
    cfg.BoolOpt('allow_requeue', default=False,
                help=u._('True enables requeue feature in case of notification'
                         ' processing error. Enable this only when underlying '
                         'transport supports this feature.')),
    cfg.StrOpt('version', default='1.0',
               help=u._('Version of tasks invoked via notifications')),
    cfg.IntOpt('thread_pool_size', default=10,
               help=u._('Define the number of max threads to be used for '
                        'notification server processing functionality.')),
]

quota_opt_group = cfg.OptGroup(name='quotas',
                               title='Quota Options')

quota_opts = [
    cfg.IntOpt('quota_secrets',
               default=-1,
               help=u._('Number of secrets allowed per project')),
    cfg.IntOpt('quota_orders',
               default=-1,
               help=u._('Number of orders allowed per project')),
    cfg.IntOpt('quota_containers',
               default=-1,
               help=u._('Number of containers allowed per project')),
    cfg.IntOpt('quota_consumers',
               default=-1,
               help=u._('Number of consumers allowed per project')),
    cfg.IntOpt('quota_cas',
               default=-1,
               help=u._('Number of CAs allowed per project'))
]

# Flag to indicate barbican configuration is already parsed once or not
_CONFIG_PARSED_ONCE = False

def parse_args(conf, args=None, usage=None, default_config_files=None):
    global _CONFIG_PARSED_ONCE
    conf(args=args if args else [],
         project='barbican',
         prog='barbican',
         version=barbican.version.__version__,
         usage=usage,
         default_config_files=default_config_files)

    conf.pydev_debug_host = os.environ.get('PYDEV_DEBUG_HOST')
    conf.pydev_debug_port = os.environ.get('PYDEV_DEBUG_PORT')

    # Assign cfg.CONF handle to parsed barbican configuration once at startup
    # only. No need to keep re-assigning it with separate plugin conf usage
    if not _CONFIG_PARSED_ONCE:
        cfg.CONF = conf
        _CONFIG_PARSED_ONCE = True

def new_config():
    conf = cfg.ConfigOpts()
    log.register_options(conf)
    conf.register_opts(context_opts)
    conf.register_opts(common_opts)
    conf.register_opts(host_opts)
    conf.register_opts(db_opts)
    conf.register_opts(_options.eventlet_backdoor_opts)
    conf.register_opts(_options.periodic_opts)

    conf.register_opts(_options.ssl_opts, "ssl")

    conf.register_group(retry_opt_group)
    conf.register_opts(retry_opts, group=retry_opt_group)

    conf.register_group(queue_opt_group)
    conf.register_opts(queue_opts, group=queue_opt_group)

    conf.register_group(ks_queue_opt_group)
    conf.register_opts(ks_queue_opts, group=ks_queue_opt_group)

    conf.register_group(quota_opt_group)
    conf.register_opts(quota_opts, group=quota_opt_group)

    # Update default values from libraries that carry their own oslo.config
    # initialization and configuration.
    set_middleware_defaults()

    return conf

def setup_remote_pydev_debug():
    """Required setup for remote debugging."""

    if CONF.pydev_debug_host and CONF.pydev_debug_port:
        try:
            try:
                from pydev import pydevd
            except ImportError:
                import pydevd

            pydevd.settrace(CONF.pydev_debug_host,
                            port=int(CONF.pydev_debug_port),
                            stdoutToServer=True,
                            stderrToServer=True)
        except Exception:
            LOG.exception(u._LE('Unable to join debugger, please '
                                'make sure that the debugger processes is '
                                'listening on debug-host \'%(debug-host)s\' '
                                'debug-port \'%(debug-port)s\'.'),
                          {'debug-host': CONF.pydev_debug_host,
                           'debug-port': CONF.pydev_debug_port})
            raise

def set_middleware_defaults():
    """Update default configuration options for oslo.middleware."""
    # CORS Defaults
    # TODO(krotscheck): Update with https://review.openstack.org/#/c/285368/
    cfg.set_defaults(cors.CORS_OPTS,
                     allow_headers=['X-Auth-Token',
                                    'X-Openstack-Request-Id',
                                    'X-Project-Id',
                                    'X-Identity-Status',
                                    'X-User-Id',
                                    'X-Storage-Token',
                                    'X-Domain-Id',
                                    'X-User-Domain-Id',
                                    'X-Project-Domain-Id',
                                    'X-Roles'],
                     expose_headers=['X-Auth-Token',
                                     'X-Openstack-Request-Id',
                                     'X-Project-Id',
                                     'X-Identity-Status',
                                     'X-User-Id',
                                     'X-Storage-Token',
                                     'X-Domain-Id',
                                     'X-User-Domain-Id',
                                     'X-Project-Domain-Id',
                                     'X-Roles'],
                     allow_methods=['GET',
                                    'PUT',
                                    'POST',
                                    'DELETE',
                                    'PATCH']
                     )

CONF = new_config()
LOG = logging.getLogger(__name__)
parse_args(CONF)

# Adding global scope dict for all different configs created in various
# modules. In barbican, each plugin module creates its own *new* config
# instance so its error prone to share/access config values across modules
# as these module imports introduce a cyclic dependency. To avoid this, each
# plugin can set this dict after its own config instance is created and parsed.
_CONFIGS = {}

def set_module_config(name, module_conf):
    """Each plugin can set its own conf instance with its group name."""
    _CONFIGS[name] = module_conf

def get_module_config(name):
    """Get handle to plugin specific config instance by its group name."""
    return _CONFIGS[name]
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
This module contains the checker mode, a base class for code checker modes.
"""
from pyqode.qt import QtCore, QtGui
from pyqode.core import frontend
from pyqode.core.frontend.utils import DelayJobRunner
from pyqode.core.frontend.panels.marker import Marker, MarkerPanel
# pylint: disable=too-many-arguments, maybe-no-member

class CheckerMessages:
    """
    Enumerates the possible checker message types.
    """
    # pylint: disable=no-init, too-few-public-methods
    #: Status value for an information message.
    INFO = 0
    #: Status value for a warning message.
    WARNING = 1
    #: Status value for an error message.
    ERROR = 2

class CheckerMessage(object):
    """
    Holds data for a message displayed by the
    :class:`pyqode.core.frontend.modes.CheckerMode`.
    """
    # pylint: disable= too-many-instance-attributes
    #: Default set of icons foreach message status
    ICONS = {CheckerMessages.INFO: ("marker-info",
                                    ":/pyqode-icons/rc/dialog-info.png"),
             CheckerMessages.WARNING: ("marker-warning",
                                       ":/pyqode-icons/rc/dialog-warning.png"),
             CheckerMessages.ERROR: ("marker-error",
                                     ":/pyqode-icons/rc/dialog-error.png")}

    #: Default colors foreach message status
    COLORS = {CheckerMessages.INFO: "#4040DD",
              CheckerMessages.WARNING: "#DDDD40",
              CheckerMessages.ERROR: "#DD4040"}

    @classmethod
    def status_to_string(cls, status):
        """
        Converts a message status to a string.
        :param status: Status to convert (
            pyqode.core.frontend.modes.CheckerMessages)

        :return: The status string.
        :rtype: str
        """
        strings = {CheckerMessages.INFO: "Info",
                   CheckerMessages.WARNING: "Warning",
                   CheckerMessages.ERROR: "Error"}
        return strings[status]

    @property
    def status_string(self):
        """
        Returns the message status as a string.

        :return: The status string.
        """
        return self.status_to_string(self.status)

    def __init__(self, description, status, line, col=None, icon=None,
                 color=None, path=None):
        """
        :param description: The message description (used as a tooltip)
        :param status: The status associated with the message.
        :param line: The message line number
        :param col: The message start column (at the moment the message ends at
                    the end of the line).
        :param icon: Icon used for the marker panel
        :param color: Text decoration color
        :param path: file path. Optional
        """
        assert 0 <= status <= 2
        #: The description of the message, used as a tooltip.
        self.description = description
        #: The status associated with the message. One of:
        #:    * :const:`pyqode.core.MSG_STATUS_INFO`
        #:    * :const:`pyqode.core.MSG_STATUS_WARNING`
        #:    * :const:`pyqode.core.MSG_STATUS_ERROR`
        self.status = status
        #: The line of the message
        self.line = line
        #: The start column (used for the text decoration). If the col is None,
        #: the whole line is highlighted.
        self.col = col
        #: The color used for the text decoration. If None, the default color
        #: is used (:const:`pyqode.core.CheckerMessage.COLORS`)
        self.color = color
        if self.color is None:
            self.color = self.COLORS[status]
        #: The icon used for the marker panel. If None, the default icon is
        #: used (:const:`pyqode.core.CheckerMessage.ICONS`)
        self.icon = icon
        if self.icon is None:
            self.icon = self.ICONS[status]
        self.marker = None
        self.decoration = None
        self.path = path

    def __repr__(self):
        return "{0} {1}".format(self.description, self.line)

class CheckerMode(frontend.Mode, QtCore.QObject):
    """
    Performs a user defined code analysis job in a background process and
    display the results on the editor instance.

    The user defined code analysis job is a simple **function** with the
    following signature:

    .. code-block:: python

        def analysisProcess(queue: multiprocessing.Queue, code: str, path:
        str, encoding: str):

    You use the queue to put the list of
    :class:`pyqode.core.frontend.modes.CheckerMessage` that you want to be
    displayed.

    The background process is ran when the text changed and the user is idle
    for a specific delay or when the text is saved depending on the trigger
    (see :const:`pyqode.core.frontend.modes.CheckMessages`).

    You can also request an analysis manually using
    :meth:`pyqode.core.frontend.modes.CheckerMode.request_analysis`

    The messages are displayed as text decorations on the editor and optional
    markers can be added to a :class:`pyqode.core.frontend.panels.MarkerPanel`
    """
    def __init__(self, worker,
                 delay=500,
                 marker_panel_id="markerPanel",
                 clear_on_request=True, show_tooltip=False):
        """
        :param worker: The process function or class to call remotely.
        :param delay: The delay used before running the analysis process when
                      trigger is set to
                      :class:pyqode.core.frontend.modes.CheckerTriggers`
        :param marker_panel_id: Identifier of the marker panel to use to add
                              checker messages markers.
        :param clear_on_request: Clear all markers on request. If set to False,
                            the marker will be cleared only when the analysis
                            jobs finished. Default is True
        :param trigger: The kind of trigger. (see
                        :class:pyqode.core.frontend.modes.CheckerTriggers)
        :param show_tooltip: Specify if a tooltip must be displayed when the
                             mouse is over a checker message decoration.
        """
        frontend.Mode.__init__(self)
        QtCore.QObject.__init__(self)
        self._job_runner = DelayJobRunner(delay=delay)
        self._messages = []
        self._worker = worker
        self._mutex = QtCore.QMutex()
        self._clear_on_request = clear_on_request
        self._show_tooltip = show_tooltip
        self._marker_panel_id = marker_panel_id

    def add_messages(self, messages, clear=True):
        """
        Adds one message or a list of message.

        :param messages: A list of messages or a single message
        :param clear: Clear messages before displaying the new ones.
                      Default is True.

        .. warning:: This function will be renamed to **addMessages** for the
                     next release (this is planned for 1.1).
        """
        if clear:
            self.clear_messages()
        marker_panel = None
        nb_msg = len(messages)
        if nb_msg > 20:
            nb_msg = 20
        for message in messages[0:nb_msg]:
            if message.line:
                self._messages.append(message)
                try:
                    marker_panel = frontend.get_panel(self.editor,
                                                      MarkerPanel)
                except KeyError:
                    pass
                else:
                    message.marker = Marker(message.line, message.icon,
                                            message.description)
                    marker_panel.add_marker(message.marker)
                tooltip = None
                if self._show_tooltip:
                    tooltip = message.description
                message.decoration = frontend.TextDecoration(
                    self.editor.textCursor(), start_line=message.line,
                    tooltip=tooltip, draw_order=3)
                message.decoration.set_full_width(True)
                message.decoration.set_as_error(color=QtGui.QColor(
                    message.color))
                frontend.add_decoration(self.editor, message.decoration)
        if marker_panel:
            marker_panel.repaint()

    def remove_message(self, message):
        """
        Removes a message.

        :param message: Message to remove
        """
        self._messages.remove(message)
        if message.marker:
            try:
                pnl = frontend.get_panel(self.editor, MarkerPanel)
            except KeyError:
                pass
            else:
                pnl.remove_marker(message.marker)
        if message.decoration:
            frontend.remove_decoration(self.editor, message.decoration)

    def clear_messages(self):
        """
        Clears all messages.
        """
        while len(self._messages):
            self.remove_message(self._messages[0])
        try:
            mode = frontend.get_panel(self.editor, MarkerPanel)
        except KeyError:
            pass
        else:
            mode.repaint()

    def _on_state_changed(self, state):
        if state:
            self.editor.textChanged.connect(self.request_analysis)
        else:
            self.editor.textChanged.disconnect(self.request_analysis)

    def _on_work_finished(self, status, messages):
        """
        Display results.

        :param status: Response status
        :param messages: Response data, messages.
        """
        # pylint: disable=star-args
        if status:
            messages = [CheckerMessage(*msg) for msg in messages]
            self.add_messages(messages)
        else:
            self.clear_messages()

    def request_analysis(self):
        """
        Requests an analysis.
        """
        self._job_runner.request_job(self._request)

    def _request(self):
        """ Requests a checking of the editor content. """
        if self._clear_on_request:
            self.clear_messages()
        request_data = {
            'code': self.editor.toPlainText(),
            'path': self.editor.file_path,
            'encoding': self.editor.file_encoding
        }
        try:
            frontend.request_work(self.editor, self._worker, request_data,
                                  on_receive=self._on_work_finished)
        except frontend.NotConnectedError:
            QtCore.QTimer.singleShot(100, self._request)
<commit_msg>Improve checker doc<commit_after># -*- coding: utf-8 -*-
"""
This module contains the checker mode, a base class for code checker modes.
"""
from pyqode.qt import QtCore, QtGui
from pyqode.core import frontend
from pyqode.core.frontend.utils import DelayJobRunner
from pyqode.core.frontend.panels.marker import Marker, MarkerPanel
# pylint: disable=too-many-arguments, maybe-no-member

class CheckerMessages:
    """
    Enumerates the possible checker message types.
    """
    # pylint: disable=no-init, too-few-public-methods
    #: Status value for an information message.
    INFO = 0
    #: Status value for a warning message.
    WARNING = 1
    #: Status value for an error message.
    ERROR = 2

class CheckerMessage(object):
    """
    Holds data for a message displayed by the
    :class:`pyqode.core.frontend.modes.CheckerMode`.
    """
    # pylint: disable= too-many-instance-attributes
    #: Default set of icons foreach message status
    ICONS = {CheckerMessages.INFO: ("marker-info",
                                    ":/pyqode-icons/rc/dialog-info.png"),
             CheckerMessages.WARNING: ("marker-warning",
                                       ":/pyqode-icons/rc/dialog-warning.png"),
             CheckerMessages.ERROR: ("marker-error",
                                     ":/pyqode-icons/rc/dialog-error.png")}

    #: Default colors foreach message status
    COLORS = {CheckerMessages.INFO: "#4040DD",
              CheckerMessages.WARNING: "#DDDD40",
              CheckerMessages.ERROR: "#DD4040"}

    @classmethod
    def status_to_string(cls, status):
        """
        Converts a message status to a string.
        :param status: Status to convert (
            pyqode.core.frontend.modes.CheckerMessages)

        :return: The status string.
        :rtype: str
        """
        strings = {CheckerMessages.INFO: "Info",
                   CheckerMessages.WARNING: "Warning",
                   CheckerMessages.ERROR: "Error"}
        return strings[status]

    @property
    def status_string(self):
        """
        Returns the message status as a string.

        :return: The status string.
        """
        return self.status_to_string(self.status)

    def __init__(self, description, status, line, col=None, icon=None,
                 color=None, path=None):
        """
        :param description: The message description (used as a tooltip)
        :param status: The status associated with the message.
        :param line: The message line number
        :param col: The message start column (at the moment the message ends at
                    the end of the line).
        :param icon: Icon used for the marker panel
        :param color: Text decoration color
        :param path: file path. Optional
        """
        assert 0 <= status <= 2
        #: The description of the message, used as a tooltip.
        self.description = description
        #: The status associated with the message. One of:
        #:    * :const:`pyqode.core.MSG_STATUS_INFO`
        #:    * :const:`pyqode.core.MSG_STATUS_WARNING`
        #:    * :const:`pyqode.core.MSG_STATUS_ERROR`
        self.status = status
        #: The line of the message
        self.line = line
        #: The start column (used for the text decoration). If the col is None,
        #: the whole line is highlighted.
        self.col = col
        #: The color used for the text decoration. If None, the default color
        #: is used (:const:`pyqode.core.CheckerMessage.COLORS`)
        self.color = color
        if self.color is None:
            self.color = self.COLORS[status]
        #: The icon used for the marker panel. If None, the default icon is
        #: used (:const:`pyqode.core.CheckerMessage.ICONS`)
        self.icon = icon
        if self.icon is None:
            self.icon = self.ICONS[status]
        self.marker = None
        self.decoration = None
        self.path = path

    def __repr__(self):
        return "{0} {1}".format(self.description, self.line)

class CheckerMode(frontend.Mode, QtCore.QObject):
    """
    Performs a user defined code analysis job using the backend and
    display the results on the editor instance.

    The user defined code analysis job is a simple **function** with the
    following signature:

    .. code-block:: python

        def analysisProcess(data)

    where data is the request data:

    .. code-block:: python

        request_data = {
                'code': self.editor.toPlainText(),
                'path': self.editor.file_path,
                'encoding': self.editor.file_encoding
            }

    and the return value is a tuple made up of the following elements:

        (description, status, line, [col], [icon], [color], [path])

    The background process is ran when the text changed and the ide is an idle
    state for a few seconds.

    You can also request an analysis manually using
    :meth:`pyqode.core.frontend.modes.CheckerMode.request_analysis`

    Messages are displayed as text decorations on the editor and optional
    markers can be added to a :class:`pyqode.core.frontend.panels.MarkerPanel`
    """
    def __init__(self, worker,
                 delay=500,
                 marker_panel_id="markerPanel",
                 clear_on_request=True, show_tooltip=False):
        """
        :param worker: The process function or class to call remotely.
        :param delay: The delay used before running the analysis process when
                      trigger is set to
                      :class:pyqode.core.frontend.modes.CheckerTriggers`
        :param marker_panel_id: Identifier of the marker panel to use to add
                              checker messages markers.
        :param clear_on_request: Clear all markers on request. If set to False,
                            the marker will be cleared only when the analysis
                            jobs finished. Default is True
        :param trigger: The kind of trigger. (see
                        :class:pyqode.core.frontend.modes.CheckerTriggers)
        :param show_tooltip: Specify if a tooltip must be displayed when the
                             mouse is over a checker message decoration.
        """
        frontend.Mode.__init__(self)
        QtCore.QObject.__init__(self)
        self._job_runner = DelayJobRunner(delay=delay)
        self._messages = []
        self._worker = worker
        self._mutex = QtCore.QMutex()
        self._clear_on_request = clear_on_request
        self._show_tooltip = show_tooltip
        self._marker_panel_id = marker_panel_id

    def add_messages(self, messages, clear=True):
        """
        Adds one message or a list of message.

        :param messages: A list of messages or a single message
        :param clear: Clear messages before displaying the new ones.
                      Default is True.

        .. warning:: This function will be renamed to **addMessages** for the
                     next release (this is planned for 1.1).
        """
        if clear:
            self.clear_messages()
        marker_panel = None
        nb_msg = len(messages)
        if nb_msg > 20:
            nb_msg = 20
        for message in messages[0:nb_msg]:
            if message.line:
                self._messages.append(message)
                try:
                    marker_panel = frontend.get_panel(self.editor,
                                                      MarkerPanel)
                except KeyError:
                    pass
                else:
                    message.marker = Marker(message.line, message.icon,
                                            message.description)
                    marker_panel.add_marker(message.marker)
                tooltip = None
                if self._show_tooltip:
                    tooltip = message.description
                message.decoration = frontend.TextDecoration(
                    self.editor.textCursor(), start_line=message.line,
                    tooltip=tooltip, draw_order=3)
                message.decoration.set_full_width(True)
                message.decoration.set_as_error(color=QtGui.QColor(
                    message.color))
                frontend.add_decoration(self.editor, message.decoration)
        if marker_panel:
            marker_panel.repaint()

    def remove_message(self, message):
        """
        Removes a message.

        :param message: Message to remove
        """
        self._messages.remove(message)
        if message.marker:
            try:
                pnl = frontend.get_panel(self.editor, MarkerPanel)
            except KeyError:
                pass
            else:
                pnl.remove_marker(message.marker)
        if message.decoration:
            frontend.remove_decoration(self.editor, message.decoration)

    def clear_messages(self):
        """
        Clears all messages.
        """
        while len(self._messages):
            self.remove_message(self._messages[0])
        try:
            mode = frontend.get_panel(self.editor, MarkerPanel)
        except KeyError:
            pass
        else:
            mode.repaint()

    def _on_state_changed(self, state):
        if state:
            self.editor.textChanged.connect(self.request_analysis)
        else:
            self.editor.textChanged.disconnect(self.request_analysis)

    def _on_work_finished(self, status, messages):
        """
        Display results.

        :param status: Response status
        :param messages: Response data, messages.
        """
        # pylint: disable=star-args
        if status:
            messages = [CheckerMessage(*msg) for msg in messages]
            self.add_messages(messages)
        else:
            self.clear_messages()

    def request_analysis(self):
        """
        Requests an analysis.
        """
        self._job_runner.request_job(self._request)

    def _request(self):
        """ Requests a checking of the editor content. """
        if self._clear_on_request:
            self.clear_messages()
        request_data = {
            'code': self.editor.toPlainText(),
            'path': self.editor.file_path,
            'encoding': self.editor.file_encoding
        }
        try:
            frontend.request_work(self.editor, self._worker, request_data,
                                  on_receive=self._on_work_finished)
        except frontend.NotConnectedError:
            QtCore.QTimer.singleShot(100, self._request)
<|endoftext|>


<commit_before>from django.contrib.auth.models import User, Group
from rest_framework.decorators import detail_route
from rest_framework import viewsets
from rest_framework import permissions
from .serializers import *
from .models import *

from allauth.account.adapter import get_adapter
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from rest_auth.registration.views import SocialLoginView

from django.http import HttpResponse

from janitor import OAuthDance

from requests_oauthlib import OAuth2Session
from requests_oauthlib.compliance_fixes import facebook_compliance_fix

class FacebookLogin(SocialLoginView):
    """
    Facebook login
    """
    adapter_class = FacebookOAuth2Adapter
    client_class = OAuth2Client
    callback_url = "localhost:9080"
    serializer_class = SocialLoginSerializer

    def process_login(self):
        get_adapter(self.request).login(self.request, self.user)

class UserViewSet(viewsets.ModelViewSet):
    """
    Allows system users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    lookup_field = 'username'
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class PostViewSet(viewsets.ModelViewSet):
    """
    Scheduled posts
    """
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    queryset = Post.objects.all()
    serializer_class = PostSerializer

class PhaseViewSet(viewsets.ModelViewSet):
    """
    Topics, these belong to one or many projects
    """
    queryset = Phase.objects.all()
    serializer_class = PhaseSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class CampaignViewSet(viewsets.ModelViewSet):
    """
    Marketing projects or campaignsi, these hold many topics
    """
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class SocialAccountViewSet(viewsets.ModelViewSet):
    """
    Managed social accounts
    """
    queryset = SocialAccount.objects.all()
    serializer_class = SocialAccountSerializer
    permission_classes = (permissions.AllowAny,)

class SocialGroupViewSet(viewsets.ModelViewSet):
    """
    Managed social accounts
    """
    queryset = SocialGroup.objects.all()
    serializer_class = SocialGroupSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class SocialAccountGroupViewSet(viewsets.ModelViewSet):
    """
    Groups of social accounts
    """
    queryset = SocialAccountGroup.objects.all()
    serializer_class = SocialAccountGroupSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    @detail_route()
    def search(self, request, *args, **kwargs):
        ag = self.filter(name="algo")

class BucketViewSet(viewsets.ModelViewSet):
    """
    Marketing channels registry
    """
    queryset = Bucket.objects.all()
    serializer_class = BucketSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class StaticPageViewSet(viewsets.ModelViewSet):
    """
    Customizable system static pages
    """
    queryset = StaticPage.objects.all()
    serializer_class = StaticPageSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

def callback(request):
    if request.GET.get("code"):
        return HttpResponse(request.GET.get("code"))

    return HttpResponse(request.GET.get("access_token"))
#     client_id = settings.SOCIAL_AUTH_FACEBOOK_KEY
    # client_secret = settings.SOCIAL_AUTH_FACEBOOK_SECRET
    # authorization_base_url = 'https://www.facebook.com/dialog/oauth'
    # token_url = 'https://graph.facebook.com/v2.9/oauth/access_token'
    # redirect_uri = 'http://localhost:8000/callback/'

    # facebook = OAuth2Session(client_id)
    # token = facebook.fetch_token(token_url, client_secret=client_secret,
            # code=request.GET.get("code"))

    # return HttpResponse(token)
<commit_msg>PoC fetch oauth token with backend app<commit_after>import os
from django.contrib.auth.models import User, Group
from rest_framework.decorators import detail_route
from rest_framework import viewsets
from rest_framework import permissions
from .serializers import *
from .models import *

from allauth.account.adapter import get_adapter
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from rest_auth.registration.views import SocialLoginView

from django.http import HttpResponse

from janitor import OAuthDance

from requests_oauthlib import OAuth2Session
from requests_oauthlib.compliance_fixes import facebook_compliance_fix
from oauthlib.oauth2 import BackendApplicationClient

class FacebookLogin(SocialLoginView):
    """
    Facebook login
    """
    adapter_class = FacebookOAuth2Adapter
    client_class = OAuth2Client
    callback_url = "localhost:9080"
    serializer_class = SocialLoginSerializer

    def process_login(self):
        get_adapter(self.request).login(self.request, self.user)

class UserViewSet(viewsets.ModelViewSet):
    """
    Allows system users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    lookup_field = 'username'
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class PostViewSet(viewsets.ModelViewSet):
    """
    Scheduled posts
    """
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    queryset = Post.objects.all()
    serializer_class = PostSerializer

class PhaseViewSet(viewsets.ModelViewSet):
    """
    Topics, these belong to one or many projects
    """
    queryset = Phase.objects.all()
    serializer_class = PhaseSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class CampaignViewSet(viewsets.ModelViewSet):
    """
    Marketing projects or campaignsi, these hold many topics
    """
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class SocialAccountViewSet(viewsets.ModelViewSet):
    """
    Managed social accounts
    """
    queryset = SocialAccount.objects.all()
    serializer_class = SocialAccountSerializer
    permission_classes = (permissions.AllowAny,)

class SocialGroupViewSet(viewsets.ModelViewSet):
    """
    Managed social accounts
    """
    queryset = SocialGroup.objects.all()
    serializer_class = SocialGroupSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class SocialAccountGroupViewSet(viewsets.ModelViewSet):
    """
    Groups of social accounts
    """
    queryset = SocialAccountGroup.objects.all()
    serializer_class = SocialAccountGroupSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    @detail_route()
    def search(self, request, *args, **kwargs):
        ag = self.filter(name="algo")

class BucketViewSet(viewsets.ModelViewSet):
    """
    Marketing channels registry
    """
    queryset = Bucket.objects.all()
    serializer_class = BucketSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class StaticPageViewSet(viewsets.ModelViewSet):
    """
    Customizable system static pages
    """
    queryset = StaticPage.objects.all()
    serializer_class = StaticPageSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

def callback(request):
    # Set to 0 for production, 1 is for development only
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    client_id = settings.SOCIAL_AUTH_FACEBOOK_KEY
    client_secret=settings.SOCIAL_AUTH_FACEBOOK_SECRET
    token_url ='https://graph.facebook.com/v2.9/oauth/access_token'
    client = BackendApplicationClient(client_id = client_id)
    oauth = OAuth2Session(client = client)
    token = oauth.fetch_token(token_url = token_url,
            client_id = client_id, client_secret = client_secret)

    return HttpResponse(token['access_token'])
<|endoftext|>


<commit_before>import plugins
import packetFactory
import data.clients
import data.players

from config import YAMLConfig
import config
from commands import Command

ircSettings = YAMLConfig("cfg/gchat-irc.config.yml",
                         {'enabled': False, 'nick': "PSO2IRCBot", 'server': '', 'port': 6667, 'channel': "", 'autoexec': []}, True)

ircMode = ircSettings.get_key('enabled')
ircNick = ircSettings.get_key('nick')
ircServer = (ircSettings.get_key('server'), ircSettings.get_key('port'))
ircChannel = ircSettings.get_key('channel')

chatPreferences = YAMLConfig("cfg/gchat.prefs.json")

if ircMode:
    from twisted.words.protocols import irc
    from twisted.internet import reactor, protocol

    ircBot = None

    # noinspection PyUnresolvedReferences
    class GChatIRC(irc.IRCClient):
        currentPid = 0
        userIds = {}

        def __init__(self):
            global ircNick
            self.nickname = ircNick

        def get_user_id(self, user):
            if user not in self.userIds:
                self.userIds[user] = self.currentPid
                self.currentPid += 1
            return self.userIds[user]

        def connectionMade(self):
            irc.IRCClient.connectionMade(self)
            print("[GlobalChat] IRC Connected!")
            for command in ircSettings.get_key('autoexec'):
                self.sendLine(command)

        def connectionLost(self, reason):
            irc.IRCClient.connectionLost(self, reason)
            print("[GlobalChat] IRC Connection lost!")

        def signedOn(self):
            global ircBot
            self.join(self.factory.channel)
            print("[GlobalChat] Joined %s" % self.factory.channel)
            ircBot = self

        def privmsg(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] <%s> %s" % (user.split("!")[0], msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC] %s" % user.split("!")[0], msg.decode('utf-8')).build())

        def action(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] * %s %s" % (user, msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC] %s" % user.split("!")[0],
                                                         "* %s" % msg.decode('utf-8')).build())

        def send_global_message(self, ship, user, message):
            self.msg(self.factory.channel, "[G-%02i] <%s> %s" % (ship, user, message))

    class GIRCFactory(protocol.ClientFactory):
        """docstring for ClassName"""

        def __init__(self, channel):
            self.channel = channel

        def buildProtocol(self, addr):
            p = GChatIRC()
            p.factory = self
            return p

        def clientConnectionLost(self, connector, reason):
            connector.connect()

@plugins.on_start_hook
def create_preferences():
    global chatPreferences
    global ircMode
    if ircMode:
        global ircChannel
        global ircServer
        bot = GIRCFactory(ircChannel)
        reactor.connectTCP(ircServer[0], ircServer[1], bot)

# noinspection PyUnresolvedReferences
@plugins.on_connection_hook
def check_config(user):
    global chatPreferences
    if user.playerId in data.clients.connectedClients:
        client_preferences = data.clients.connectedClients[user.playerId].get_preferences()
        if 'globalChat' not in client_preferences:
            if chatPreferences.key_exists(user.playerId):
                client_preferences['globalChat'] = chatPreferences.get_key(user.playerId)['toggle']
            else:
                client_preferences['globalChat'] = True
                chatPreferences.set_key(user.playerId, {'toggle': True})
            if client_preferences['globalChat']:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is enabled, use %sg <Message> to chat and %sgoff to disable it." % (config.globalConfig.get_key('commandPrefix'), config.globalConfig.get_key('commandPrefix')),
                    0x3).build())
            else:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is disabled, use %sgon to enable it and use %sg <Message> to chat." % (config.globalConfig.get_key('commandPrefix'), config.globalConfig.get_key('commandPrefix')),
                    0x3).build())
        data.clients.connectedClients[user.playerId].set_preferences(client_preferences)

@plugins.CommandHook("gon", "Enable global chat.")
class EnableGChat(Command):
    def call_from_client(self, client):
        global chatPreferences
        preferences = data.clients.connectedClients[client.playerId].get_preferences()
        preferences['globalChat'] = True
        client.send_crypto_packet(
            packetFactory.SystemMessagePacket("[GlobalChat] Global chat enabled for you.", 0x3).build())
        data.clients.connectedClients[client.playerId].set_preferences(preferences)
        new_preferences = chatPreferences.get_key(client.playerId)
        new_preferences['toggle'] = True
        chatPreferences.set_key(client.playerId, new_preferences)

@plugins.CommandHook("goff", "Disable global chat.")
class DisableGChat(Command):
    def call_from_client(self, client):
        preferences = data.clients.connectedClients[client.playerId].get_preferences()
        preferences['globalChat'] = False
        client.send_crypto_packet(
            packetFactory.SystemMessagePacket("[GlobalChat] Global chat disabled for you.", 0x3).build())
        data.clients.connectedClients[client.playerId].set_preferences(preferences)
        new_preferences = chatPreferences.get_key(client.playerId)
        new_preferences['toggle'] = False
        chatPreferences.set_key(client.playerId, new_preferences)

@plugins.CommandHook("g", "Chat in global chat.")
class GChat(Command):
    def call_from_client(self, client):
        global ircMode
        if not data.clients.connectedClients[client.playerId].get_preferences()['globalChat']:
            client.send_crypto_packet(packetFactory.SystemMessagePacket(
                "[GlobalChat] You do not have global chat enabled, and can not send a global message.", 0x3).build())
            return
        print("[GlobalChat] <%s> %s" % (data.players.playerList[client.playerId][0], self.args[3:]))
        if ircMode:
            global ircBot
            if ircBot is not None:
                ircBot.send_global_message(data.clients.connectedClients[client.playerId].ship,
                    data.players.playerList[client.playerId][0].encode('utf-8'), self.args[3:].encode('utf-8'))
        for client_data in data.clients.connectedClients.values():
            if client_data.get_preferences()['globalChat'] and client_data.get_handle() is not None:
                client_data.get_handle().send_crypto_packet(
                    packetFactory.TeamChatPacket(client.playerId,
                                                 "[G-%02i] %s" % (data.clients.connectedClients[client.playerId].ship, data.players.playerList[client.playerId][0]),
                                                 self.args[3:]).build())

    def call_from_console(self):
        global ircMode
        if ircMode:
            global ircBot
            if ircBot is not None:
                ircBot.send_global_message(0, "Console", self.args[:2].encode('utf-8'))
        for client in data.clients.connectedClients.values():
            if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                client.get_handle().send_crypto_packet(
                    packetFactory.TeamChatPacket(0x999, "[GCONSOLE]",
                                                 self.args[2:]).build())
        return "[GlobalChat] <Console> %s" % self.args[2:]

<commit_msg>IRC changes<commit_after>import plugins
import packetFactory
import data.clients
import data.players

from config import YAMLConfig
import config
from commands import Command

ircSettings = YAMLConfig("cfg/gchat-irc.config.yml",
                         {'enabled': False, 'nick': "PSO2IRCBot", 'server': '', 'port': 6667, 'channel': "", 'autoexec': []}, True)

ircMode = ircSettings.get_key('enabled')
ircNick = ircSettings.get_key('nick')
ircServer = (ircSettings.get_key('server'), ircSettings.get_key('port'))
ircChannel = ircSettings.get_key('channel')

chatPreferences = YAMLConfig("cfg/gchat.prefs.json")

if ircMode:
    from twisted.words.protocols import irc
    from twisted.internet import reactor, protocol

    ircBot = None

    # noinspection PyUnresolvedReferences
    class GChatIRC(irc.IRCClient):
        currentPid = 0
        userIds = {}

        def __init__(self):
            global ircNick
            self.nickname = ircNick

        def get_user_id(self, user):
            if user not in self.userIds:
                self.userIds[user] = self.currentPid
                self.currentPid += 1
            return self.userIds[user]

        def connectionMade(self):
            irc.IRCClient.connectionMade(self)
            print("[GlobalChat] IRC Connected!")
            for command in ircSettings.get_key('autoexec'):
                self.sendLine(command)

        def connectionLost(self, reason):
            irc.IRCClient.connectionLost(self, reason)
            print("[GlobalChat] IRC Connection lost!")

        def signedOn(self):
            global ircBot
            self.join(self.factory.channel)
            print("[GlobalChat] Joined %s" % self.factory.channel)
            ircBot = self

        def privmsg(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] <%s> %s" % (user.split("!")[0], msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC] %s" % user.split("!")[0], msg.decode('utf-8')).build())
            else:
                print("[IRC] <%s> %s" % (user, msg))

        def action(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] * %s %s" % (user, msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC] %s" % user.split("!")[0],
                                                         "* %s" % msg.decode('utf-8')).build())

        def send_global_message(self, ship, user, message):
            self.msg(self.factory.channel, "[G-%02i] <%s> %s" % (ship, user, message))

    class GIRCFactory(protocol.ClientFactory):
        """docstring for ClassName"""

        def __init__(self, channel):
            self.channel = channel

        def buildProtocol(self, addr):
            p = GChatIRC()
            p.factory = self
            return p

        def clientConnectionLost(self, connector, reason):
            connector.connect()

@plugins.on_start_hook
def create_preferences():
    global chatPreferences
    global ircMode
    if ircMode:
        global ircChannel
        global ircServer
        bot = GIRCFactory(ircChannel)
        reactor.connectTCP(ircServer[0], ircServer[1], bot)

# noinspection PyUnresolvedReferences
@plugins.on_connection_hook
def check_config(user):
    global chatPreferences
    if user.playerId in data.clients.connectedClients:
        client_preferences = data.clients.connectedClients[user.playerId].get_preferences()
        if 'globalChat' not in client_preferences:
            if chatPreferences.key_exists(user.playerId):
                client_preferences['globalChat'] = chatPreferences.get_key(user.playerId)['toggle']
            else:
                client_preferences['globalChat'] = True
                chatPreferences.set_key(user.playerId, {'toggle': True})
            if client_preferences['globalChat']:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is enabled, use %sg <Message> to chat and %sgoff to disable it." % (config.globalConfig.get_key('commandPrefix'), config.globalConfig.get_key('commandPrefix')),
                    0x3).build())
            else:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is disabled, use %sgon to enable it and use %sg <Message> to chat." % (config.globalConfig.get_key('commandPrefix'), config.globalConfig.get_key('commandPrefix')),
                    0x3).build())
        data.clients.connectedClients[user.playerId].set_preferences(client_preferences)

@plugins.CommandHook("irccmd")
class IRCCommand(Command):
    def call_from_console(self):
        global ircMode
        global ircBot
        if ircMode and ircBot is not None:
            ircBot.sendLine(self.args.split(" ", 1)[1])

@plugins.CommandHook("gon", "Enable global chat.")
class EnableGChat(Command):
    def call_from_client(self, client):
        global chatPreferences
        preferences = data.clients.connectedClients[client.playerId].get_preferences()
        preferences['globalChat'] = True
        client.send_crypto_packet(
            packetFactory.SystemMessagePacket("[GlobalChat] Global chat enabled for you.", 0x3).build())
        data.clients.connectedClients[client.playerId].set_preferences(preferences)
        new_preferences = chatPreferences.get_key(client.playerId)
        new_preferences['toggle'] = True
        chatPreferences.set_key(client.playerId, new_preferences)

@plugins.CommandHook("goff", "Disable global chat.")
class DisableGChat(Command):
    def call_from_client(self, client):
        preferences = data.clients.connectedClients[client.playerId].get_preferences()
        preferences['globalChat'] = False
        client.send_crypto_packet(
            packetFactory.SystemMessagePacket("[GlobalChat] Global chat disabled for you.", 0x3).build())
        data.clients.connectedClients[client.playerId].set_preferences(preferences)
        new_preferences = chatPreferences.get_key(client.playerId)
        new_preferences['toggle'] = False
        chatPreferences.set_key(client.playerId, new_preferences)

@plugins.CommandHook("g", "Chat in global chat.")
class GChat(Command):
    def call_from_client(self, client):
        global ircMode
        if not data.clients.connectedClients[client.playerId].get_preferences()['globalChat']:
            client.send_crypto_packet(packetFactory.SystemMessagePacket(
                "[GlobalChat] You do not have global chat enabled, and can not send a global message.", 0x3).build())
            return
        print("[GlobalChat] <%s> %s" % (data.players.playerList[client.playerId][0], self.args[3:]))
        if ircMode:
            global ircBot
            if ircBot is not None:
                ircBot.send_global_message(data.clients.connectedClients[client.playerId].ship,
                    data.players.playerList[client.playerId][0].encode('utf-8'), self.args[3:].encode('utf-8'))
        for client_data in data.clients.connectedClients.values():
            if client_data.get_preferences()['globalChat'] and client_data.get_handle() is not None:
                client_data.get_handle().send_crypto_packet(
                    packetFactory.TeamChatPacket(client.playerId,
                                                 "[G-%02i] %s" % (data.clients.connectedClients[client.playerId].ship, data.players.playerList[client.playerId][0]),
                                                 self.args[3:]).build())

    def call_from_console(self):
        global ircMode
        if ircMode:
            global ircBot
            if ircBot is not None:
                ircBot.send_global_message(0, "Console", self.args[:2].encode('utf-8'))
        for client in data.clients.connectedClients.values():
            if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                client.get_handle().send_crypto_packet(
                    packetFactory.TeamChatPacket(0x999, "[GCONSOLE]",
                                                 self.args[2:]).build())
        return "[GlobalChat] <Console> %s" % self.args[2:]

<|endoftext|>