<commit_before>from sympy.core import S, Dummy, pi
from sympy.functions.combinatorial.factorials import factorial
from sympy.functions.special.gamma_functions import gamma
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.polys.orthopolys import legendre_poly, laguerre_poly, hermite_poly
from sympy.polys.rootoftools import RootOf

def gauss_legendre(n, n_digits):
    r"""
    Computes the Gauss-Legendre quadrature [1]_ points and weights.

    The Gauss-Legendre quadrature approximates the integral:

    .. math::
        \int_{-1}^1 f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    Parameters
    ==========

    n : the order of quadrature

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy.integrals.quadrature import gauss_legendre
    >>> x, w = gauss_legendre(3, 5)
    >>> x
    [-0.7746, 0, 0.7746]
    >>> w
    [0.55556, 0.88889, 0.55556]
    >>> x, w = gauss_legendre(4, 5)
    >>> x
    [-0.86114, -0.33998, 0.33998, 0.86114]
    >>> w
    [0.34786, 0.65215, 0.65215, 0.34786]

    See Also
    ========

    gauss_laguerre, gauss_gen_laguerre, gauss_hermite

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gaussian_quadrature
    """
    x = Dummy("x")
    p = legendre_poly(n, x, polys=True)
    pd = p.diff(x)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((2/((1-r**2) * pd.subs(x, r)**2)).n(n_digits))
    return xi, w

def gauss_laguerre(n, n_digits):
    r"""
    Computes the Gauss-Laguerre quadrature [1]_ points and weights.

    The Gauss-Laguerre quadrature approximates the integral:

    .. math::
        \int_0^{\infty} e^{-x} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    Parameters
    ==========

    n : the order of quadrature

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy.integrals.quadrature import gauss_laguerre
    >>> x, w = gauss_laguerre(3, 5)
    >>> x
    [0.41577, 2.2943, 6.2899]
    >>> w
    [0.71109, 0.27852, 0.010389]
    >>> x, w = gauss_laguerre(6, 5)
    >>> x
    [0.22285, 1.1889, 2.9927, 5.7751, 9.8375, 15.983]
    >>> w
    [0.45896, 0.417, 0.11337, 0.010399, 0.00026102, 8.9855e-7]

    See Also
    ========

    gauss_legendre, gauss_gen_laguerre, gauss_hermite

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature
    """
    x = Dummy("x")
    p  = laguerre_poly(n, x, polys=True)
    p1 = laguerre_poly(n+1, x, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((r/((n+1)**2 * p1.subs(x, r)**2)).n(n_digits))
    return xi, w

def gauss_hermite(n, n_digits):
    r"""
    Computes the Gauss-Hermite quadrature [1]_ points and weights.

    The Gauss-Hermite quadrature approximates the integral:

    .. math::
        \int_{-\infty}^{\infty} e^{-x^2} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    Parameters
    ==========

    n : the order of quadrature

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy.integrals.quadrature import gauss_hermite
    >>> x, w = gauss_hermite(3, 5)
    >>> x
    [-1.2247, 0, 1.2247]
    >>> w
    [0.29541, 1.1816, 0.29541]

    >>> x, w = gauss_hermite(6, 5)
    >>> x
    [-2.3506, -1.3358, -0.43608, 0.43608, 1.3358, 2.3506]
    >>> w
    [0.00453, 0.15707, 0.72463, 0.72463, 0.15707, 0.00453]

    See Also
    ========

    gauss_legendre, gauss_laguerre, gauss_gen_laguerre

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss-Hermite_Quadrature
    """
    x = Dummy("x")
    p  = hermite_poly(n, x, polys=True)
    p1 = hermite_poly(n-1, x, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append(((2**(n-1) * factorial(n) * sqrt(pi))/(n**2 * p1.subs(x, r)**2)).n(n_digits))
    return xi, w

def gauss_gen_laguerre(n, alpha, n_digits):
    r"""
    Computes the generalized Gauss-Laguerre quadrature [1]_ points and weights.

    The generalized Gauss-Laguerre quadrature approximates the integral:

    .. math::
        \int_{0}^\infty x^{\alpha} e^{-x} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of `L^{\alpha}_n`
    and the weights `w_i` are given by:

    .. math::
        w_i = \frac{\Gamma(\alpha+n)}{n \Gamma(n) L^{\alpha}_{n-1}(x_i) L^{\alpha+1}_{n-1}(x_i)}

    Parameters
    ==========

    n : the order of quadrature

    alpha : the exponent of the singularity, `\alpha > -1`

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.integrals.quadrature import gauss_gen_laguerre
    >>> x, w = gauss_gen_laguerre(3, -S.Half, 5)
    >>> x
    [0.19016, 1.7845, 5.5253]
    >>> w
    [0.19016, 1.7845, 5.5253]

    >>> x, w = gauss_gen_laguerre(4, 3*S.Half, 5)
    >>> x
    [0.97851, 2.9904, 6.3193, 11.712]
    >>> w
    [0.53087, 0.67721, 0.11895, 0.0023152]

    See Also
    ========

    gauss_legendre, gauss_laguerre, gauss_hermite

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature
    """
    x = Dummy("x")
    p = laguerre_poly(n, x, alpha=alpha, polys=True)
    p1 = laguerre_poly(n-1, x, alpha=alpha, polys=True)
    p2 = laguerre_poly(n-1, x, alpha=alpha+1, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((gamma(alpha+n)/(n*gamma(n)*p1.subs(x, r)*p2.subs(x, r))).n(n_digits))
    return xi, w
<commit_msg>Add weight formulae to doc<commit_after>from sympy.core import S, Dummy, pi
from sympy.functions.combinatorial.factorials import factorial
from sympy.functions.special.gamma_functions import gamma
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.polys.orthopolys import legendre_poly, laguerre_poly, hermite_poly
from sympy.polys.rootoftools import RootOf

def gauss_legendre(n, n_digits):
    r"""
    Computes the Gauss-Legendre quadrature [1]_ points and weights.

    The Gauss-Legendre quadrature approximates the integral:

    .. math::
        \int_{-1}^1 f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of `P_n`
    and the weights `w_i` are given by:

    .. math::
        w_i = \frac{2}{\left(1-x_i^2\right) \left(P'_n(x_i)\right)^2}

    Parameters
    ==========

    n : the order of quadrature

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy.integrals.quadrature import gauss_legendre
    >>> x, w = gauss_legendre(3, 5)
    >>> x
    [-0.7746, 0, 0.7746]
    >>> w
    [0.55556, 0.88889, 0.55556]
    >>> x, w = gauss_legendre(4, 5)
    >>> x
    [-0.86114, -0.33998, 0.33998, 0.86114]
    >>> w
    [0.34786, 0.65215, 0.65215, 0.34786]

    See Also
    ========

    gauss_laguerre, gauss_gen_laguerre, gauss_hermite

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gaussian_quadrature
    """
    x = Dummy("x")
    p = legendre_poly(n, x, polys=True)
    pd = p.diff(x)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((2/((1-r**2) * pd.subs(x, r)**2)).n(n_digits))
    return xi, w

def gauss_laguerre(n, n_digits):
    r"""
    Computes the Gauss-Laguerre quadrature [1]_ points and weights.

    The Gauss-Laguerre quadrature approximates the integral:

    .. math::
        \int_0^{\infty} e^{-x} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of `L_n`
    and the weights `w_i` are given by:

    .. math::
        w_i = \frac{x_i}{(n+1)^2 \left(L_{n+1}(x_i)\right)^2}

    Parameters
    ==========

    n : the order of quadrature

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy.integrals.quadrature import gauss_laguerre
    >>> x, w = gauss_laguerre(3, 5)
    >>> x
    [0.41577, 2.2943, 6.2899]
    >>> w
    [0.71109, 0.27852, 0.010389]
    >>> x, w = gauss_laguerre(6, 5)
    >>> x
    [0.22285, 1.1889, 2.9927, 5.7751, 9.8375, 15.983]
    >>> w
    [0.45896, 0.417, 0.11337, 0.010399, 0.00026102, 8.9855e-7]

    See Also
    ========

    gauss_legendre, gauss_gen_laguerre, gauss_hermite

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature
    """
    x = Dummy("x")
    p  = laguerre_poly(n, x, polys=True)
    p1 = laguerre_poly(n+1, x, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((r/((n+1)**2 * p1.subs(x, r)**2)).n(n_digits))
    return xi, w

def gauss_hermite(n, n_digits):
    r"""
    Computes the Gauss-Hermite quadrature [1]_ points and weights.

    The Gauss-Hermite quadrature approximates the integral:

    .. math::
        \int_{-\infty}^{\infty} e^{-x^2} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of `H_n`
    and the weights `w_i` are given by:

    .. math::
        w_i = \frac{2^{n-1} n! \sqrt{\pi}}{n^2 \left(H_{n-1}(x_i)\right)^2}

    Parameters
    ==========

    n : the order of quadrature

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy.integrals.quadrature import gauss_hermite
    >>> x, w = gauss_hermite(3, 5)
    >>> x
    [-1.2247, 0, 1.2247]
    >>> w
    [0.29541, 1.1816, 0.29541]

    >>> x, w = gauss_hermite(6, 5)
    >>> x
    [-2.3506, -1.3358, -0.43608, 0.43608, 1.3358, 2.3506]
    >>> w
    [0.00453, 0.15707, 0.72463, 0.72463, 0.15707, 0.00453]

    See Also
    ========

    gauss_legendre, gauss_laguerre, gauss_gen_laguerre

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss-Hermite_Quadrature
    """
    x = Dummy("x")
    p  = hermite_poly(n, x, polys=True)
    p1 = hermite_poly(n-1, x, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append(((2**(n-1) * factorial(n) * sqrt(pi))/(n**2 * p1.subs(x, r)**2)).n(n_digits))
    return xi, w

def gauss_gen_laguerre(n, alpha, n_digits):
    r"""
    Computes the generalized Gauss-Laguerre quadrature [1]_ points and weights.

    The generalized Gauss-Laguerre quadrature approximates the integral:

    .. math::
        \int_{0}^\infty x^{\alpha} e^{-x} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of `L^{\alpha}_n`
    and the weights `w_i` are given by:

    .. math::
        w_i = \frac{\Gamma(\alpha+n)}{n \Gamma(n) L^{\alpha}_{n-1}(x_i) L^{\alpha+1}_{n-1}(x_i)}

    Parameters
    ==========

    n : the order of quadrature

    alpha : the exponent of the singularity, `\alpha > -1`

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.integrals.quadrature import gauss_gen_laguerre
    >>> x, w = gauss_gen_laguerre(3, -S.Half, 5)
    >>> x
    [0.19016, 1.7845, 5.5253]
    >>> w
    [0.19016, 1.7845, 5.5253]

    >>> x, w = gauss_gen_laguerre(4, 3*S.Half, 5)
    >>> x
    [0.97851, 2.9904, 6.3193, 11.712]
    >>> w
    [0.53087, 0.67721, 0.11895, 0.0023152]

    See Also
    ========

    gauss_legendre, gauss_laguerre, gauss_hermite

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature
    """
    x = Dummy("x")
    p = laguerre_poly(n, x, alpha=alpha, polys=True)
    p1 = laguerre_poly(n-1, x, alpha=alpha, polys=True)
    p2 = laguerre_poly(n-1, x, alpha=alpha+1, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((gamma(alpha+n)/(n*gamma(n)*p1.subs(x, r)*p2.subs(x, r))).n(n_digits))
    return xi, w
<|endoftext|>


<commit_before>"""

qasm.py - Functions to parse a set of qasm commands into a Sympy Circuit.

Examples taken from Chuang's page: http://www.media.mit.edu/quanta/qasm2circ/

Todo:
* Put in subscripts??
* Figure out the def boxes

The code returns a circuit and an associated list of labels.
>>> from sympy.physics.quantum.qasm import Qasm
>>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*H(1)

>>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
"""
import re

from sympy.physics.quantum.gate import H, CNOT, X, Z, CGate, CGateS,SWAP,S,T
from sympy.physics.quantum.circuitplot import Mz

def prod(c):
    def mul(a,b): return a*b # Can't import operator.mul b/c operator module in directory
    return reduce(mul,c,1)

def flip_index(i,n):
    """Reorder qubit indices from largest to smallest.
    >>> from sympy.physics.quantum.qasm import flip_index
    >>> flip_index(0,2)
    1
    >>> flip_index(1,2)
    0
    """
    return n-i-1

def isblank(line):
    """Returns True if the line is empty/blank/all whitespace.
    >>> from sympy.physics.quantum.qasm import isblank
    >>> isblank('   ')
    True
    >>> isblank(' _ ')
    False
    """
    return len(line.split()) == 0

def trim(line):
    """Remove everything following comment # characters in line.
    >>> from sympy.physics.quantum.qasm import trim
    >>> trim('nothing happens here')
    'nothing happens here'
    >>> trim('something #happens here')
    'something '
    """
    if not '#' in line: return line
    return line.split('#')[0]

def get_index(target,labels):
    """Get qubit labels from the rest of the line,
    and return their indices, properly flipped.
    >>> from sympy.physics.quantum.qasm import get_index
    >>> get_index('q0',['q0','q1'])
    1
    >>> get_index('q1',['q0','q1'])
    0
    """
    nq = len(labels)
    return flip_index(labels.index(target),nq)

def get_indices(targets,labels):
    return [get_index(t,labels) for t in targets]

def nonblank(args):
    for line in args:
        line = trim(line)
        if isblank(line): continue
        yield line
    return

def fullsplit(line):
    words = line.split()
    rest = ' '.join(words[1:])
    return fixcommand(words[0]),rest.split(',')

def fixcommand(c):
    """Fix Qasm command names.
    Remove all of forbidden characters from command c, and
    replace 'def' with 'qdef'.
    """
    forbidden_characters = ['-']
    c = c.lower()
    for char in forbidden_characters:
        c = c.replace(char,'')
    if c == 'def':
        return 'qdef'
    return c

def stripquotes(s):
    """Replace explicit quotes in a string.
    >>> from sympy.physics.quantum.qasm import stripquotes
    >>> stripquotes("'S'") == 'S'
    True
    >>> stripquotes('"S"') == 'S'
    True
    >>> stripquotes('S') == 'S'
    True
    """
    s = s.replace('"','') # Remove second set of quotes?
    s = s.replace("'",'')
    return s

class Qasm(object):
    """
    >>> from sympy.physics.quantum.qasm import Qasm
    >>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*H(1)
    >>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
    """
    def __init__(self,*args,**kwargs):
        self.defs = {}
        self.circuit = []
        self.labels = []
        self.add(*args)
        self.kwargs = kwargs

    def add(self,*lines):
        for line in nonblank(lines):
            command,rest = fullsplit(line)
            if self.defs.get(command): #defs come first, since you can override built-in
                function = self.defs.get(command)
                indices = self.indices(rest)
                if len(indices) == 1:
                    self.circuit.append(function(indices[0]))
                else:
                    self.circuit.append(function(indices[:-1],indices[-1]))
            elif hasattr(self,command):
                function = getattr(self,command)
                function(*rest)
            else:
                print "Function %s not defined. Skipping" % command

    def get_circuit(self): return prod(reversed(self.circuit))
    def get_labels(self): return list(reversed(self.labels))

    def plot(self):
        from sympy.physics.quantum.circuitplot import CircuitPlot
        circuit,labels = self.get_circuit(), self.get_labels()
        CircuitPlot(circuit,len(labels),labels=labels)

    def qubit(self,arg,*rest): self.labels.append(arg)
    def indices(self,args): return get_indices(args,self.labels)
    def index(self,arg): return get_index(arg,self.labels)
    def nop(self,*args): pass
    def x(self,arg): self.circuit.append(X(self.index(arg)))
    def z(self,arg): self.circuit.append(Z(self.index(arg)))
    def h(self,arg): self.circuit.append(H(self.index(arg)))
    def s(self,arg): self.circuit.append(S(self.index(arg)))
    def t(self,arg): self.circuit.append(T(self.index(arg)))
    def measure(self,arg): self.circuit.append(Mz(self.index(arg)))

    def cnot(self,a1,a2):self.circuit.append(CNOT(*self.indices([a1,a2])))
    def swap(self,a1,a2):self.circuit.append(SWAP(*self.indices([a1,a2])))
    def cphase(self,a1,a2):self.circuit.append(CPhase(*self.indices([a1,a2])))

    def toffoli(self,a1,a2,a3):
        i1,i2,i3 = self.indices([a1,a2,a3])
        self.circuit.append(CGateS((i1,i2),X(i3)))

    def cx(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,X(fj)))
    def cz(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,Z(fj)))

    def defbox(self,*args):
        print "defbox not supported yet. Skipping: ",args

    def qdef(self,name,ncontrols,symbol):
        from sympy.physics.quantum.circuitplot import CreateOneQubitGate,CreateCGate
        ncontrols = int(ncontrols)
        command = fixcommand(name)
        symbol = stripquotes(symbol)
        if ncontrols > 0:
            self.defs[command] = CreateCGate(symbol)
        else:
            self.defs[command] = CreateOneQubitGate(symbol)

if __name__ == '__main__':
    import doctest; doctest.testmod()
<commit_msg>Rebasing and adding changes from intermediate patch<commit_after>"""

qasm.py - Functions to parse a set of qasm commands into a Sympy Circuit.

Examples taken from Chuang's page: http://www.media.mit.edu/quanta/qasm2circ/

Todo:
* Put in subscripts??
* Figure out the def boxes

The code returns a circuit and an associated list of labels.
>>> from sympy.physics.quantum.qasm import Qasm
>>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*H(1)

>>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
"""
import re

from sympy.physics.quantum.gate import H, CNOT, X, Z, CGate, CGateS,SWAP,S,T
from sympy.physics.quantum.circuitplot import Mz

def prod(c):
    def mul(a,b): return a*b # Can't import operator.mul b/c operator module in directory
    return reduce(mul,c,1)

def flip_index(i,n):
    """Reorder qubit indices from largest to smallest.
    >>> from sympy.physics.quantum.qasm import flip_index
    >>> flip_index(0,2)
    1
    >>> flip_index(1,2)
    0
    """
    return n-i-1

def isblank(line):
    """Returns True if the line is empty/blank/all whitespace.
    >>> from sympy.physics.quantum.qasm import isblank
    >>> isblank('   ')
    True
    >>> isblank(' _ ')
    False
    """
    return len(line.split()) == 0

def trim(line):
    """Remove everything following comment # characters in line.
    >>> from sympy.physics.quantum.qasm import trim
    >>> trim('nothing happens here')
    'nothing happens here'
    >>> trim('something #happens here')
    'something '
    """
    if not '#' in line: return line
    return line.split('#')[0]

def get_index(target,labels):
    """Get qubit labels from the rest of the line,
    and return their indices, properly flipped.
    >>> from sympy.physics.quantum.qasm import get_index
    >>> get_index('q0',['q0','q1'])
    1
    >>> get_index('q1',['q0','q1'])
    0
    """
    nq = len(labels)
    return flip_index(labels.index(target),nq)

def get_indices(targets,labels):
    return [get_index(t,labels) for t in targets]

def nonblank(args):
    for line in args:
        line = trim(line)
        if isblank(line): continue
        yield line
    return

def fullsplit(line):
    words = line.split()
    rest = ' '.join(words[1:])
    return fixcommand(words[0]),rest.split(',')

def fixcommand(c):
    """Fix Qasm command names.
    Remove all of forbidden characters from command c, and
    replace 'def' with 'qdef'.
    """
    forbidden_characters = ['-']
    c = c.lower()
    for char in forbidden_characters:
        c = c.replace(char,'')
    if c == 'def':
        return 'qdef'
    return c

def stripquotes(s):
    """Replace explicit quotes in a string.
    >>> from sympy.physics.quantum.qasm import stripquotes
    >>> stripquotes("'S'") == 'S'
    True
    >>> stripquotes('"S"') == 'S'
    True
    >>> stripquotes('S') == 'S'
    True
    """
    s = s.replace('"','') # Remove second set of quotes?
    s = s.replace("'",'')
    return s

class Qasm(object):
    """
    >>> from sympy.physics.quantum.qasm import Qasm
    >>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*H(1)
    >>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
    """
    def __init__(self,*args,**kwargs):
        self.defs = {}
        self.circuit = []
        self.labels = []
        self.add(*args)
        self.kwargs = kwargs
        self.defs = {}

    def add(self,*lines):
        for line in nonblank(lines):
            command,rest = fullsplit(line)
            if self.defs.get(command): #defs come first, since you can override built-in
                function = self.defs.get(command)
                indices = self.indices(rest)
                if len(indices) == 1:
                    self.circuit.append(function(indices[0]))
                else:
                    self.circuit.append(function(indices[:-1],indices[-1]))
            elif hasattr(self,command):
                function = getattr(self,command)
                function(*rest)
            else:
                print "Function %s not defined. Skipping" % command

    def get_circuit(self): return prod(reversed(self.circuit))
    def get_labels(self): return list(reversed(self.labels))

    def plot(self):
        from sympy.physics.quantum.circuitplot import CircuitPlot
        circuit,labels = self.get_circuit(), self.get_labels()
        CircuitPlot(circuit,len(labels),labels=labels)

    def qubit(self,arg,*rest): self.labels.append(arg)
    def indices(self,args): return get_indices(args,self.labels)
    def index(self,arg): return get_index(arg,self.labels)
    def nop(self,*args): pass
    def x(self,arg): self.circuit.append(X(self.index(arg)))
    def z(self,arg): self.circuit.append(Z(self.index(arg)))
    def h(self,arg): self.circuit.append(H(self.index(arg)))
    def s(self,arg): self.circuit.append(S(self.index(arg)))
    def t(self,arg): self.circuit.append(T(self.index(arg)))
    def measure(self,arg): self.circuit.append(Mz(self.index(arg)))

    def cnot(self,a1,a2):self.circuit.append(CNOT(*self.indices([a1,a2])))
    def swap(self,a1,a2):self.circuit.append(SWAP(*self.indices([a1,a2])))
    def cphase(self,a1,a2):self.circuit.append(CPhase(*self.indices([a1,a2])))

    def toffoli(self,a1,a2,a3):
        i1,i2,i3 = self.indices([a1,a2,a3])
        self.circuit.append(CGateS((i1,i2),X(i3)))

    def cx(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,X(fj)))
    def cz(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,Z(fj)))

    def defbox(self,*args):
        print "defbox not supported yet. Skipping: ",args

    def qdef(self,name,ncontrols,symbol):
        from sympy.physics.quantum.circuitplot import CreateOneQubitGate,CreateCGate
        ncontrols = int(ncontrols)
        command = fixcommand(name)
        symbol = stripquotes(symbol)
        if ncontrols > 0:
            self.defs[command] = CreateCGate(symbol)
        else:
            self.defs[command] = CreateOneQubitGate(symbol)

if __name__ == '__main__':
    import doctest; doctest.testmod()
<|endoftext|>


<commit_before>"""

qasm.py - Functions to parse a set of qasm commands into a Sympy Circuit.

Examples taken from Chuang's page: http://www.media.mit.edu/quanta/qasm2circ/

Todo:
* Put in subscripts??
* Figure out the def boxes

The code returns a circuit and an associated list of labels.
>>> from sympy.physics.quantum.qasm import Qasm
>>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*H(1)

>>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
"""
from sympy.physics.quantum.gate import H, CNOT, X, Z, CGate, SWAP,S,T
from sympy.physics.quantum.circuitplot import Mz

def prod(c):
    def mul(a,b): return a*b # Can't import operator.mul b/c operator module in directory
    return reduce(mul,c,1)

def flip_index(i,n):
    """Reorder qubit indices from largest to smallest.
    >>> from sympy.physics.quantum.qasm import flip_index
    >>> flip_index(0,2)
    1
    >>> flip_index(1,2)
    0
    """
    return n-i-1

def isblank(line):
    """Returns True if the line is empty/blank/all whitespace.
    >>> from sympy.physics.quantum.qasm import isblank
    >>> isblank('   ')
    True
    >>> isblank(' _ ')
    False
    """
    return len(line.split()) == 0

def trim(line):
    """Remove everything following comment # characters in line.
    >>> from sympy.physics.quantum.qasm import trim
    >>> trim('nothing happens here')
    'nothing happens here'
    >>> trim('something #happens here')
    'something '
    """
    if not '#' in line: return line
    return line.split('#')[0]

def get_index(target,labels):
    """Get qubit labels from the rest of the line,
    and return their indices, properly flipped.
    >>> from sympy.physics.quantum.qasm import get_index
    >>> get_index('q0',['q0','q1'])
    1
    >>> get_index('q1',['q0','q1'])
    0
    """
    nq = len(labels)
    return flip_index(labels.index(target),nq)

def get_indices(targets,labels):
    return [get_index(t,labels) for t in targets]

def nonblank(args):
    for line in args:
        line = trim(line)
        if isblank(line): continue
        yield line
    return

def fullsplit(line):
    words = line.split()
    rest = ' '.join(words[1:])
    return fixcommand(words[0]),rest.split(',')

def fixcommand(c):
    """Fix Qasm command names.
    Remove all of forbidden characters from command c, and
    replace 'def' with 'qdef'.
    """
    forbidden_characters = ['-']
    for char in forbidden_characters:
        c = c.replace(char,'')
    if c == 'def':
        return 'qdef'
    return c

class Qasm(object):
    """
    >>> from sympy.physics.quantum.qasm import Qasm
    >>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*H(1)
    >>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
    """
    def __init__(self,*args,**kwargs):
        self.circuit = []
        self.labels = []
        self.add(*args)
        self.kwargs = kwargs

    def add(self,*lines):
        for line in nonblank(lines):
            command,rest = fullsplit(line)
            function = getattr(self,command)
            if not function:
                print "%s not defined: skipping" % command
            else:
                function(*rest)

    def get_circuit(self): return prod(reversed(self.circuit))
    def get_labels(self): return list(reversed(self.labels))

    def plot(self):
        from sympy.physics.quantum.circuitplot import CircuitPlot
        circuit,labels = self.get_circuit(), self.get_labels()
        CircuitPlot(circuit,len(labels),labels=labels)

    def qubit(self,arg): self.labels.append(arg)
    def indices(self,args): return get_indices(args,self.labels)
    def index(self,arg): return get_index(arg,self.labels)
    def nop(self,*args): pass
    def x(self,arg): self.circuit.append(X(self.index(arg)))
    def z(self,arg): self.circuit.append(Z(self.index(arg)))
    def h(self,arg): self.circuit.append(H(self.index(arg)))
    def s(self,arg): self.circuit.append(S(self.index(arg)))
    def t(self,arg): self.circuit.append(T(self.index(arg)))
    def measure(self,arg): self.circuit.append(Mz(self.index(arg)))

    def cnot(self,a1,a2):self.circuit.append(CNOT(*self.indices([a1,a2])))
    def swap(self,a1,a2):self.circuit.append(SWAP(*self.indices([a1,a2])))
    def cphase(self,a1,a2):self.circuit.append(CPhase(*self.indices([a1,a2])))

    def cx(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,X(fj)))
    def cz(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,Z(fj)))

    def qdef(self,name,nq,symbol):
        print "Testing def",name,nq,symbol

if __name__ == '__main__':
    import doctest; doctest.testmod()
<commit_msg>Added preliminary version of def statement handling to qasm parser<commit_after>"""

qasm.py - Functions to parse a set of qasm commands into a Sympy Circuit.

Examples taken from Chuang's page: http://www.media.mit.edu/quanta/qasm2circ/

Todo:
* Put in subscripts??
* Figure out the def boxes

The code returns a circuit and an associated list of labels.
>>> from sympy.physics.quantum.qasm import Qasm
>>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*H(1)

>>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
"""
from sympy.physics.quantum.gate import H, CNOT, X, Z, CGate, SWAP,S,T
from sympy.physics.quantum.circuitplot import Mz

def prod(c):
    def mul(a,b): return a*b # Can't import operator.mul b/c operator module in directory
    return reduce(mul,c,1)

def flip_index(i,n):
    """Reorder qubit indices from largest to smallest.
    >>> from sympy.physics.quantum.qasm import flip_index
    >>> flip_index(0,2)
    1
    >>> flip_index(1,2)
    0
    """
    return n-i-1

def isblank(line):
    """Returns True if the line is empty/blank/all whitespace.
    >>> from sympy.physics.quantum.qasm import isblank
    >>> isblank('   ')
    True
    >>> isblank(' _ ')
    False
    """
    return len(line.split()) == 0

def trim(line):
    """Remove everything following comment # characters in line.
    >>> from sympy.physics.quantum.qasm import trim
    >>> trim('nothing happens here')
    'nothing happens here'
    >>> trim('something #happens here')
    'something '
    """
    if not '#' in line: return line
    return line.split('#')[0]

def get_index(target,labels):
    """Get qubit labels from the rest of the line,
    and return their indices, properly flipped.
    >>> from sympy.physics.quantum.qasm import get_index
    >>> get_index('q0',['q0','q1'])
    1
    >>> get_index('q1',['q0','q1'])
    0
    """
    nq = len(labels)
    return flip_index(labels.index(target),nq)

def get_indices(targets,labels):
    return [get_index(t,labels) for t in targets]

def nonblank(args):
    for line in args:
        line = trim(line)
        if isblank(line): continue
        yield line
    return

def fullsplit(line):
    words = line.split()
    rest = ' '.join(words[1:])
    return fixcommand(words[0]),rest.split(',')

def fixcommand(c):
    """Fix Qasm command names.
    Remove all of forbidden characters from command c, and
    replace 'def' with 'qdef'.
    """
    forbidden_characters = ['-']
    for char in forbidden_characters:
        c = c.replace(char,'')
    if c == 'def':
        return 'qdef'
    return c

class Qasm(object):
    """
    >>> from sympy.physics.quantum.qasm import Qasm
    >>> q = Qasm('qubit q0','qubit q1','h q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*H(1)
    >>> q = Qasm('qubit q0','qubit q1','cnot q0,q1','cnot q1,q0','cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
    """
    def __init__(self,*args,**kwargs):
        self.circuit = []
        self.labels = []
        self.add(*args)
        self.kwargs = kwargs
        self.defs = {}

    def add(self,*lines):
        for line in nonblank(lines):
            command,rest = fullsplit(line)
            if hasattr(self,command):
                function = getattr(self,command)
                function(*rest)
            elif self.defs.get(command):
                function = self.defs.get(command)
                fi = self.index(rest[0])
                self.circuit.append(function(fi))
            else:
                print "Function %s not defined. Skipping"

    def get_circuit(self): return prod(reversed(self.circuit))
    def get_labels(self): return list(reversed(self.labels))

    def plot(self):
        from sympy.physics.quantum.circuitplot import CircuitPlot
        circuit,labels = self.get_circuit(), self.get_labels()
        CircuitPlot(circuit,len(labels),labels=labels)

    def qubit(self,arg): self.labels.append(arg)
    def indices(self,args): return get_indices(args,self.labels)
    def index(self,arg): return get_index(arg,self.labels)
    def nop(self,*args): pass
    def x(self,arg): self.circuit.append(X(self.index(arg)))
    def z(self,arg): self.circuit.append(Z(self.index(arg)))
    def h(self,arg): self.circuit.append(H(self.index(arg)))
    def s(self,arg): self.circuit.append(S(self.index(arg)))
    def t(self,arg): self.circuit.append(T(self.index(arg)))
    def measure(self,arg): self.circuit.append(Mz(self.index(arg)))

    def cnot(self,a1,a2):self.circuit.append(CNOT(*self.indices([a1,a2])))
    def swap(self,a1,a2):self.circuit.append(SWAP(*self.indices([a1,a2])))
    def cphase(self,a1,a2):self.circuit.append(CPhase(*self.indices([a1,a2])))

    def cx(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,X(fj)))
    def cz(self,a1,a2):
        fi,fj = self.indices([a1,a2])
        self.circuit.append(CGate(fi,Z(fj)))

    def qdef(self,name,nq,symbol):
        from sympy.physics.quantum.circuitplot import CreateOneQubitGate
        nq = int(nq)
        command = fixcommand(name)
        if nq > 1:
            print "Def for nq>1 not defined ",nq
        else:
            self.defs[command] = CreateOneQubitGate(symbol)

if __name__ == '__main__':
    import doctest; doctest.testmod()
<|endoftext|>


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

from twisted.internet import defer

from collections import namedtuple

from ._base import SQLBaseStore
from synapse.util.caches.descriptors import cached, cachedInlineCallbacks

from synapse.api.constants import Membership
from synapse.types import UserID

import logging

logger = logging.getLogger(__name__)

RoomsForUser = namedtuple(
    "RoomsForUser",
    ("room_id", "sender", "membership", "event_id", "stream_ordering")
)

class RoomMemberStore(SQLBaseStore):

    def _store_room_members_txn(self, txn, events):
        """Store a room member in the database.
        """
        self._simple_insert_many_txn(
            txn,
            table="room_memberships",
            values=[
                {
                    "event_id": event.event_id,
                    "user_id": event.state_key,
                    "sender": event.user_id,
                    "room_id": event.room_id,
                    "membership": event.membership,
                }
                for event in events
            ]
        )

        for event in events:
            txn.call_after(self.get_rooms_for_user.invalidate, (event.state_key,))
            txn.call_after(self.get_joined_hosts_for_room.invalidate, (event.room_id,))
            txn.call_after(self.get_users_in_room.invalidate, (event.room_id,))

    def get_room_member(self, user_id, room_id):
        """Retrieve the current state of a room member.

        Args:
            user_id (str): The member's user ID.
            room_id (str): The room the member is in.
        Returns:
            Deferred: Results in a MembershipEvent or None.
        """
        return self.runInteraction(
            "get_room_member",
            self._get_members_events_txn,
            room_id,
            user_id=user_id,
        ).addCallback(
            self._get_events
        ).addCallback(
            lambda events: events[0] if events else None
        )

    @cached(max_entries=5000)
    def get_users_in_room(self, room_id):
        def f(txn):

            rows = self._get_members_rows_txn(
                txn,
                room_id=room_id,
                membership=Membership.JOIN,
            )

            return [r["user_id"] for r in rows]
        return self.runInteraction("get_users_in_room", f)

    def get_room_members(self, room_id, membership=None):
        """Retrieve the current room member list for a room.

        Args:
            room_id (str): The room to get the list of members.
            membership (synapse.api.constants.Membership): The filter to apply
            to this list, or None to return all members with some state
            associated with this room.
        Returns:
            list of namedtuples representing the members in this room.
        """
        return self.runInteraction(
            "get_room_members",
            self._get_members_events_txn,
            room_id,
            membership=membership,
        ).addCallback(self._get_events)

    def get_invites_for_user(self, user_id):
        """ Get all the invite events for a user
        Args:
            user_id (str): The user ID.
        Returns:
            A deferred list of event objects.
        """

        return self.get_rooms_for_user_where_membership_is(
            user_id, [Membership.INVITE]
        ).addCallback(lambda invites: self._get_events([
            invites.event_id for invite in invites
        ]))

    def get_leave_and_ban_events_for_user(self, user_id):
        """ Get all the leave events for a user
        Args:
            user_id (str): The user ID.
        Returns:
            A deferred list of event objects.
        """
        return self.get_rooms_for_user_where_membership_is(
            user_id, (Membership.LEAVE, Membership.BAN)
        ).addCallback(lambda leaves: self._get_events([
            leave.event_id for leave in leaves
        ]))

    def get_rooms_for_user_where_membership_is(self, user_id, membership_list):
        """ Get all the rooms for this user where the membership for this user
        matches one in the membership list.

        Args:
            user_id (str): The user ID.
            membership_list (list): A list of synapse.api.constants.Membership
            values which the user must be in.
        Returns:
            A list of dictionary objects, with room_id, membership and sender
            defined.
        """
        if not membership_list:
            return defer.succeed(None)

        return self.runInteraction(
            "get_rooms_for_user_where_membership_is",
            self._get_rooms_for_user_where_membership_is_txn,
            user_id, membership_list
        )

    def _get_rooms_for_user_where_membership_is_txn(self, txn, user_id,
                                                    membership_list):
        where_clause = "user_id = ? AND (%s) AND forgotten = 0" % (
            " OR ".join(["membership = ?" for _ in membership_list]),
        )

        args = [user_id]
        args.extend(membership_list)

        sql = (
            "SELECT m.room_id, m.sender, m.membership, m.event_id, e.stream_ordering"
            " FROM current_state_events as c"
            " INNER JOIN room_memberships as m"
            " ON m.event_id = c.event_id"
            " INNER JOIN events as e"
            " ON e.event_id = c.event_id"
            " AND m.room_id = c.room_id"
            " AND m.user_id = c.state_key"
            " WHERE %s"
        ) % (where_clause,)

        txn.execute(sql, args)
        return [
            RoomsForUser(**r) for r in self.cursor_to_dict(txn)
        ]

    @cached(max_entries=5000)
    def get_joined_hosts_for_room(self, room_id):
        return self.runInteraction(
            "get_joined_hosts_for_room",
            self._get_joined_hosts_for_room_txn,
            room_id,
        )

    def _get_joined_hosts_for_room_txn(self, txn, room_id):
        rows = self._get_members_rows_txn(
            txn,
            room_id, membership=Membership.JOIN
        )

        joined_domains = set(
            UserID.from_string(r["user_id"]).domain
            for r in rows
        )

        return joined_domains

    def _get_members_events_txn(self, txn, room_id, membership=None, user_id=None):
        rows = self._get_members_rows_txn(
            txn,
            room_id, membership, user_id,
        )
        return [r["event_id"] for r in rows]

    def _get_members_rows_txn(self, txn, room_id, membership=None, user_id=None):
        where_clause = "c.room_id = ?"
        where_values = [room_id]

        if membership:
            where_clause += " AND m.membership = ?"
            where_values.append(membership)

        if user_id:
            where_clause += " AND m.user_id = ?"
            where_values.append(user_id)

        sql = (
            "SELECT m.* FROM room_memberships as m"
            " INNER JOIN current_state_events as c"
            " ON m.event_id = c.event_id "
            " AND m.room_id = c.room_id "
            " AND m.user_id = c.state_key"
            " WHERE %(where)s"
        ) % {
            "where": where_clause,
        }

        txn.execute(sql, where_values)
        rows = self.cursor_to_dict(txn)

        return rows

    @cached()
    def get_rooms_for_user(self, user_id):
        return self.get_rooms_for_user_where_membership_is(
            user_id, membership_list=[Membership.JOIN],
        )

    @defer.inlineCallbacks
    def user_rooms_intersect(self, user_id_list):
        """ Checks whether all the users whose IDs are given in a list share a
        room.

        This is a "hot path" function that's called a lot, e.g. by presence for
        generating the event stream. As such, it is implemented locally by
        wrapping logic around heavily-cached database queries.
        """
        if len(user_id_list) < 2:
            defer.returnValue(True)

        deferreds = [self.get_rooms_for_user(u) for u in user_id_list]

        results = yield defer.DeferredList(deferreds, consumeErrors=True)

        # A list of sets of strings giving room IDs for each user
        room_id_lists = [set([r.room_id for r in result[1]]) for result in results]

        # There isn't a setintersection(*list_of_sets)
        ret = len(room_id_lists.pop(0).intersection(*room_id_lists)) > 0

        defer.returnValue(ret)

    @defer.inlineCallbacks
    def forget(self, user_id, room_id):
        """Indicate that user_id wishes to discard history for room_id."""
        def f(txn):
            sql = (
                "UPDATE"
                "  room_memberships"
                " SET"
                "  forgotten = 1"
                " WHERE"
                "  user_id = ?"
                " AND"
                "  room_id = ?"
            )
            txn.execute(sql, (user_id, room_id))
        yield self.runInteraction("forget_membership", f)
        self.was_forgotten_at.invalidate_all()
        self.did_forget.invalidate((user_id, room_id))

    @cachedInlineCallbacks(num_args=2)
    def did_forget(self, user_id, room_id):
        """Returns whether user_id has elected to discard history for room_id.

        Returns False if they have since re-joined."""
        def f(txn):
            sql = (
                "SELECT"
                "  COUNT(*)"
                " FROM"
                "  room_memberships"
                " WHERE"
                "  user_id = ?"
                " AND"
                "  room_id = ?"
                " AND"
                "  forgotten = 0"
            )
            txn.execute(sql, (user_id, room_id))
            rows = txn.fetchall()
            return rows[0][0]
        count = yield self.runInteraction("did_forget_membership", f)
        defer.returnValue(count == 0)

    @cachedInlineCallbacks(num_args=3)
    def was_forgotten_at(self, user_id, room_id, event_id):
        """Returns whether user_id has elected to discard history for room_id at event_id.

        event_id must be a membership event."""
        def f(txn):
            sql = (
                "SELECT"
                "  forgotten"
                " FROM"
                "  room_memberships"
                " WHERE"
                "  user_id = ?"
                " AND"
                "  room_id = ?"
                " AND"
                "  event_id = ?"
            )
            txn.execute(sql, (user_id, room_id, event_id))
            rows = txn.fetchall()
            return rows[0][0]
        forgot = yield self.runInteraction("did_forget_membership_at", f)
        defer.returnValue(forgot == 1)
<commit_msg>Fix typo<commit_after># -*- coding: utf-8 -*-
# Copyright 2014, 2015 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from twisted.internet import defer

from collections import namedtuple

from ._base import SQLBaseStore
from synapse.util.caches.descriptors import cached, cachedInlineCallbacks

from synapse.api.constants import Membership
from synapse.types import UserID

import logging

logger = logging.getLogger(__name__)

RoomsForUser = namedtuple(
    "RoomsForUser",
    ("room_id", "sender", "membership", "event_id", "stream_ordering")
)

class RoomMemberStore(SQLBaseStore):

    def _store_room_members_txn(self, txn, events):
        """Store a room member in the database.
        """
        self._simple_insert_many_txn(
            txn,
            table="room_memberships",
            values=[
                {
                    "event_id": event.event_id,
                    "user_id": event.state_key,
                    "sender": event.user_id,
                    "room_id": event.room_id,
                    "membership": event.membership,
                }
                for event in events
            ]
        )

        for event in events:
            txn.call_after(self.get_rooms_for_user.invalidate, (event.state_key,))
            txn.call_after(self.get_joined_hosts_for_room.invalidate, (event.room_id,))
            txn.call_after(self.get_users_in_room.invalidate, (event.room_id,))

    def get_room_member(self, user_id, room_id):
        """Retrieve the current state of a room member.

        Args:
            user_id (str): The member's user ID.
            room_id (str): The room the member is in.
        Returns:
            Deferred: Results in a MembershipEvent or None.
        """
        return self.runInteraction(
            "get_room_member",
            self._get_members_events_txn,
            room_id,
            user_id=user_id,
        ).addCallback(
            self._get_events
        ).addCallback(
            lambda events: events[0] if events else None
        )

    @cached(max_entries=5000)
    def get_users_in_room(self, room_id):
        def f(txn):

            rows = self._get_members_rows_txn(
                txn,
                room_id=room_id,
                membership=Membership.JOIN,
            )

            return [r["user_id"] for r in rows]
        return self.runInteraction("get_users_in_room", f)

    def get_room_members(self, room_id, membership=None):
        """Retrieve the current room member list for a room.

        Args:
            room_id (str): The room to get the list of members.
            membership (synapse.api.constants.Membership): The filter to apply
            to this list, or None to return all members with some state
            associated with this room.
        Returns:
            list of namedtuples representing the members in this room.
        """
        return self.runInteraction(
            "get_room_members",
            self._get_members_events_txn,
            room_id,
            membership=membership,
        ).addCallback(self._get_events)

    def get_invites_for_user(self, user_id):
        """ Get all the invite events for a user
        Args:
            user_id (str): The user ID.
        Returns:
            A deferred list of event objects.
        """

        return self.get_rooms_for_user_where_membership_is(
            user_id, [Membership.INVITE]
        ).addCallback(lambda invites: self._get_events([
            invite.event_id for invite in invites
        ]))

    def get_leave_and_ban_events_for_user(self, user_id):
        """ Get all the leave events for a user
        Args:
            user_id (str): The user ID.
        Returns:
            A deferred list of event objects.
        """
        return self.get_rooms_for_user_where_membership_is(
            user_id, (Membership.LEAVE, Membership.BAN)
        ).addCallback(lambda leaves: self._get_events([
            leave.event_id for leave in leaves
        ]))

    def get_rooms_for_user_where_membership_is(self, user_id, membership_list):
        """ Get all the rooms for this user where the membership for this user
        matches one in the membership list.

        Args:
            user_id (str): The user ID.
            membership_list (list): A list of synapse.api.constants.Membership
            values which the user must be in.
        Returns:
            A list of dictionary objects, with room_id, membership and sender
            defined.
        """
        if not membership_list:
            return defer.succeed(None)

        return self.runInteraction(
            "get_rooms_for_user_where_membership_is",
            self._get_rooms_for_user_where_membership_is_txn,
            user_id, membership_list
        )

    def _get_rooms_for_user_where_membership_is_txn(self, txn, user_id,
                                                    membership_list):
        where_clause = "user_id = ? AND (%s) AND forgotten = 0" % (
            " OR ".join(["membership = ?" for _ in membership_list]),
        )

        args = [user_id]
        args.extend(membership_list)

        sql = (
            "SELECT m.room_id, m.sender, m.membership, m.event_id, e.stream_ordering"
            " FROM current_state_events as c"
            " INNER JOIN room_memberships as m"
            " ON m.event_id = c.event_id"
            " INNER JOIN events as e"
            " ON e.event_id = c.event_id"
            " AND m.room_id = c.room_id"
            " AND m.user_id = c.state_key"
            " WHERE %s"
        ) % (where_clause,)

        txn.execute(sql, args)
        return [
            RoomsForUser(**r) for r in self.cursor_to_dict(txn)
        ]

    @cached(max_entries=5000)
    def get_joined_hosts_for_room(self, room_id):
        return self.runInteraction(
            "get_joined_hosts_for_room",
            self._get_joined_hosts_for_room_txn,
            room_id,
        )

    def _get_joined_hosts_for_room_txn(self, txn, room_id):
        rows = self._get_members_rows_txn(
            txn,
            room_id, membership=Membership.JOIN
        )

        joined_domains = set(
            UserID.from_string(r["user_id"]).domain
            for r in rows
        )

        return joined_domains

    def _get_members_events_txn(self, txn, room_id, membership=None, user_id=None):
        rows = self._get_members_rows_txn(
            txn,
            room_id, membership, user_id,
        )
        return [r["event_id"] for r in rows]

    def _get_members_rows_txn(self, txn, room_id, membership=None, user_id=None):
        where_clause = "c.room_id = ?"
        where_values = [room_id]

        if membership:
            where_clause += " AND m.membership = ?"
            where_values.append(membership)

        if user_id:
            where_clause += " AND m.user_id = ?"
            where_values.append(user_id)

        sql = (
            "SELECT m.* FROM room_memberships as m"
            " INNER JOIN current_state_events as c"
            " ON m.event_id = c.event_id "
            " AND m.room_id = c.room_id "
            " AND m.user_id = c.state_key"
            " WHERE %(where)s"
        ) % {
            "where": where_clause,
        }

        txn.execute(sql, where_values)
        rows = self.cursor_to_dict(txn)

        return rows

    @cached()
    def get_rooms_for_user(self, user_id):
        return self.get_rooms_for_user_where_membership_is(
            user_id, membership_list=[Membership.JOIN],
        )

    @defer.inlineCallbacks
    def user_rooms_intersect(self, user_id_list):
        """ Checks whether all the users whose IDs are given in a list share a
        room.

        This is a "hot path" function that's called a lot, e.g. by presence for
        generating the event stream. As such, it is implemented locally by
        wrapping logic around heavily-cached database queries.
        """
        if len(user_id_list) < 2:
            defer.returnValue(True)

        deferreds = [self.get_rooms_for_user(u) for u in user_id_list]

        results = yield defer.DeferredList(deferreds, consumeErrors=True)

        # A list of sets of strings giving room IDs for each user
        room_id_lists = [set([r.room_id for r in result[1]]) for result in results]

        # There isn't a setintersection(*list_of_sets)
        ret = len(room_id_lists.pop(0).intersection(*room_id_lists)) > 0

        defer.returnValue(ret)

    @defer.inlineCallbacks
    def forget(self, user_id, room_id):
        """Indicate that user_id wishes to discard history for room_id."""
        def f(txn):
            sql = (
                "UPDATE"
                "  room_memberships"
                " SET"
                "  forgotten = 1"
                " WHERE"
                "  user_id = ?"
                " AND"
                "  room_id = ?"
            )
            txn.execute(sql, (user_id, room_id))
        yield self.runInteraction("forget_membership", f)
        self.was_forgotten_at.invalidate_all()
        self.did_forget.invalidate((user_id, room_id))

    @cachedInlineCallbacks(num_args=2)
    def did_forget(self, user_id, room_id):
        """Returns whether user_id has elected to discard history for room_id.

        Returns False if they have since re-joined."""
        def f(txn):
            sql = (
                "SELECT"
                "  COUNT(*)"
                " FROM"
                "  room_memberships"
                " WHERE"
                "  user_id = ?"
                " AND"
                "  room_id = ?"
                " AND"
                "  forgotten = 0"
            )
            txn.execute(sql, (user_id, room_id))
            rows = txn.fetchall()
            return rows[0][0]
        count = yield self.runInteraction("did_forget_membership", f)
        defer.returnValue(count == 0)

    @cachedInlineCallbacks(num_args=3)
    def was_forgotten_at(self, user_id, room_id, event_id):
        """Returns whether user_id has elected to discard history for room_id at event_id.

        event_id must be a membership event."""
        def f(txn):
            sql = (
                "SELECT"
                "  forgotten"
                " FROM"
                "  room_memberships"
                " WHERE"
                "  user_id = ?"
                " AND"
                "  room_id = ?"
                " AND"
                "  event_id = ?"
            )
            txn.execute(sql, (user_id, room_id, event_id))
            rows = txn.fetchall()
            return rows[0][0]
        forgot = yield self.runInteraction("did_forget_membership_at", f)
        defer.returnValue(forgot == 1)
<|endoftext|>


<commit_before>#!/usr/bin/python3

import os
import logging
import sys
from socrate import conf
import subprocess
import hmac

env = os.environ

logging.basicConfig(stream=sys.stderr, level=env.get("LOG_LEVEL", "WARNING"))

# jinja context
context = {}
context.update(env)

context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576))

db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite")
if db_flavor == "sqlite":
    context["DB_DSNW"] = "sqlite:////data/roundcube.db"
elif db_flavor == "mysql":
    context["DB_DSNW"] = "mysql://%s:%s@%s/%s" % (
        env.get("ROUNDCUBE_DB_USER", "roundcube"),
        env.get("ROUNDCUBE_DB_PW"),
        env.get("ROUNDCUBE_DB_HOST", "database"),
        env.get("ROUNDCUBE_DB_NAME", "roundcube")
    )
elif db_flavor == "postgresql":
    context["DB_DSNW"] = "pgsql://%s:%s@%s/%s" % (
        env.get("ROUNDCUBE_DB_USER", "roundcube"),
        env.get("ROUNDCUBE_DB_PW"),
        env.get("ROUNDCUBE_DB_HOST", "database"),
        env.get("ROUNDCUBE_DB_NAME", "roundcube")
    )
else:
    print(f"Unknown ROUNDCUBE_DB_FLAVOR: {db_flavor}", file=sys.stderr)
    exit(1)

# derive roundcube secret key
secret_key = env.get("SECRET_KEY")
if not secret_key:
    try:
        secret_key = open(env.get("SECRET_KEY_FILE"), "r").read().strip()
    except Exception as exc:
        print(f"Can't read SECRET_KEY from file: {exc}", file=sys.stderr)
        exit(2)

context['SECRET_KEY'] = hmac.new(bytearray(secret_key, 'utf-8'), bytearray('ROUNDCUBE_KEY', 'utf-8'), 'sha256').hexdigest()

# roundcube plugins
# (using "dict" because it is ordered and "set" is not)
plugins = dict((p, None) for p in env.get("ROUNDCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/plugins", p)))
if plugins:
    plugins["mailu"] = None
else:
    plugins = dict((k, None) for k in ["archive", "zipdownload", "markasjunk", "managesieve", "enigma", "carddav", "mailu"])

context["PLUGINS"] = ",".join(f"'{p}'" for p in plugins)

# add overrides
context["INCLUDES"] = sorted(inc for inc in os.listdir("/overrides") if inc.endswith(".inc")) if os.path.isdir("/overrides") else []

# calculate variables for config file
env["SESSION_TIMEOUT_MINUTES"] = str(int(env.get("SESSION_TIMEOUT", "3600")) // 60 ) if int(env.get("SESSION_TIMEOUT", "3600")) >= 60 else "1"
context.update(env)

# create config files
conf.jinja("/php.ini", context, "/usr/local/etc/php/conf.d/roundcube.ini")
conf.jinja("/config.inc.php", context, "/var/www/html/config/config.inc.php")

# create dirs
os.system("mkdir -p /data/gpg")

print("Initializing database")
try:
    result = subprocess.check_output(["/var/www/html/bin/initdb.sh", "--dir", "/var/www/html/SQL"],
                                     stderr=subprocess.STDOUT)
    print(result.decode())
except subprocess.CalledProcessError as exc:
    err = exc.stdout.decode()
    if "already exists" in err:
        print("Already initialzed")
    else:
        print(err)
        exit(3)

print("Upgrading database")
try:
    subprocess.check_call(["/var/www/html/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
    exit(4)
else:
    print("Cleaning database")
    try:
        subprocess.check_call(["/var/www/html/bin/cleandb.sh"], stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as exc:
        exit(5)

# setup permissions
os.system("chown -R www-data:www-data /data")

# clean env
[env.pop(key, None) for key in env.keys() if key == "SECRET_KEY" or key.startswith("ROUNDCUBE_")]

# run apache
os.execve("/usr/local/bin/apache2-foreground", ["apache2-foreground"], env)

<commit_msg>prettify<commit_after>#!/usr/bin/python3

import os
import logging
import sys
from socrate import conf
import subprocess
import hmac

env = os.environ

logging.basicConfig(stream=sys.stderr, level=env.get("LOG_LEVEL", "WARNING"))

# jinja context
context = {}
context.update(env)

context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576))

db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite")
if db_flavor == "sqlite":
    context["DB_DSNW"] = "sqlite:////data/roundcube.db"
elif db_flavor == "mysql":
    context["DB_DSNW"] = "mysql://%s:%s@%s/%s" % (
        env.get("ROUNDCUBE_DB_USER", "roundcube"),
        env.get("ROUNDCUBE_DB_PW"),
        env.get("ROUNDCUBE_DB_HOST", "database"),
        env.get("ROUNDCUBE_DB_NAME", "roundcube")
    )
elif db_flavor == "postgresql":
    context["DB_DSNW"] = "pgsql://%s:%s@%s/%s" % (
        env.get("ROUNDCUBE_DB_USER", "roundcube"),
        env.get("ROUNDCUBE_DB_PW"),
        env.get("ROUNDCUBE_DB_HOST", "database"),
        env.get("ROUNDCUBE_DB_NAME", "roundcube")
    )
else:
    print(f"Unknown ROUNDCUBE_DB_FLAVOR: {db_flavor}", file=sys.stderr)
    exit(1)

# derive roundcube secret key
secret_key = env.get("SECRET_KEY")
if not secret_key:
    try:
        secret_key = open(env.get("SECRET_KEY_FILE"), "r").read().strip()
    except Exception as exc:
        print(f"Can't read SECRET_KEY from file: {exc}", file=sys.stderr)
        exit(2)

context['SECRET_KEY'] = hmac.new(bytearray(secret_key, 'utf-8'), bytearray('ROUNDCUBE_KEY', 'utf-8'), 'sha256').hexdigest()

# roundcube plugins
# (using "dict" because it is ordered and "set" is not)
plugins = dict((p, None) for p in env.get("ROUNDCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/plugins", p)))
if plugins:
    plugins["mailu"] = None
else:
    plugins = dict((k, None) for k in ["archive", "zipdownload", "markasjunk", "managesieve", "enigma", "carddav", "mailu"])

context["PLUGINS"] = ",".join(f"'{p}'" for p in plugins)

# add overrides
context["INCLUDES"] = sorted(inc for inc in os.listdir("/overrides") if inc.endswith(".inc")) if os.path.isdir("/overrides") else []

# calculate variables for config file
context["SESSION_TIMEOUT_MINUTES"] = max(int(env.get("SESSION_TIMEOUT", "3600")) // 60, 1)

# create config files
conf.jinja("/php.ini", context, "/usr/local/etc/php/conf.d/roundcube.ini")
conf.jinja("/config.inc.php", context, "/var/www/html/config/config.inc.php")

# create dirs
os.system("mkdir -p /data/gpg")

print("Initializing database")
try:
    result = subprocess.check_output(["/var/www/html/bin/initdb.sh", "--dir", "/var/www/html/SQL"],
                                     stderr=subprocess.STDOUT)
    print(result.decode())
except subprocess.CalledProcessError as exc:
    err = exc.stdout.decode()
    if "already exists" in err:
        print("Already initialzed")
    else:
        print(err)
        exit(3)

print("Upgrading database")
try:
    subprocess.check_call(["/var/www/html/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
    exit(4)
else:
    print("Cleaning database")
    try:
        subprocess.check_call(["/var/www/html/bin/cleandb.sh"], stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as exc:
        exit(5)

# setup permissions
os.system("chown -R www-data:www-data /data")

# clean env
[env.pop(key, None) for key in env.keys() if key == "SECRET_KEY" or key.startswith("ROUNDCUBE_")]

# run apache
os.execve("/usr/local/bin/apache2-foreground", ["apache2-foreground"], env)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Utillity class with things
"""

import os, io, logging
import asyncio, aiohttp

from discord import Message
from discord.ext import commands

logger = logging.getLogger("disco")

def get_destination(msg: Message):
    dest = None
    if msg.channel.is_private:
        dest  = 'Private Message'
    else:
        dest = '#{0.channel.name} ({0.server.name})'.format(msg)
    return dest

def get_channel_permissions(ctx):
    return ctx.message.channel.permissions_for(ctx.message.author)

def can_attach_links(ctx):
    """Check if the user can upload files in the given context"""
    permissions = get_channel_permissions(ctx)
    return permissions.attach_files

async def try_embed_image(bot: commands.Bot, ctx, url: str, content=None):
    """
    Embeds an image in a message. If it can't embed
    you the url file, it will just do the normal bot.say
    """
    try:
        logger.debug("[embed image] {}".format(url))
        can_send_file = can_attach_links(ctx)
        logger.debug("can_send_file: {}".format(str(can_send_file)))
        if can_send_file:
            with aiohttp.ClientSession() as session:
                async with session.request(url=url, method="GET") as resp:
                    with io.BytesIO(await resp.read()) as f:
                        await bot.send_file(ctx.message.channel, f, filename=url, content=content)
        else:
            logger.debug("[embed image] warning: cannot attach files in this channel")
            if content is None:
                await bot.say(url)
            else:
                await bot.say("{0} {1}".format(str(content), url))
    except Exception as e:
        logger.warning("Could not embed image, error: {}".format(e))

def configure_logger(name=__name__, stream=True, level=logging.INFO):
    """
    Function to quickly help you configure several loggers.

        ex.: `configure_logger("awesome-logger", False, logging.DEBUG)`
    """
    loginst = logging.getLogger(name)
    loginst.setLevel(logging.INFO if level is None else level)

    path = os.path.abspath(name + ".log")
    #fhnd = logging.FileHandler(path, "w", "utf-8")
    shnd = logging.StreamHandler()
    rhnd = logging.RotatingFileHandler(path, mode="a", maxBytes=10000000,
        backupCount=10, encoding="utf-8")

    log_fmt = "%(asctime)s::%(name)s [%(levelname)s]: %(message)s"
    fmt = logging.Formatter(log_fmt) # if log_format is None else log_format)
    #fhnd.setFormatter(fmt)
    shnd.setFormatter(fmt)
    rhnd.setFormatter(fmt)

    #loginst.addHandler(fhnd)
    loginst.addHandler(rhnd)
    if stream: loginst.addHandler(shnd)

    return loginst
<commit_msg>fixed RotatingFileHandler import error<commit_after># -*- coding: utf-8 -*-
"""
Utillity class with things
"""

import os, io, logging
import asyncio, aiohttp
import logging.handlers

from discord import Message
from discord.ext import commands

logger = logging.getLogger("disco")

def get_destination(msg: Message):
    dest = None
    if msg.channel.is_private:
        dest  = 'Private Message'
    else:
        dest = '#{0.channel.name} ({0.server.name})'.format(msg)
    return dest

def get_channel_permissions(ctx):
    return ctx.message.channel.permissions_for(ctx.message.author)

def can_attach_links(ctx):
    """Check if the user can upload files in the given context"""
    permissions = get_channel_permissions(ctx)
    return permissions.attach_files

async def try_embed_image(bot: commands.Bot, ctx, url: str, content=None):
    """
    Embeds an image in a message. If it can't embed
    you the url file, it will just do the normal bot.say
    """
    try:
        logger.debug("[embed image] {}".format(url))
        can_send_file = can_attach_links(ctx)
        logger.debug("can_send_file: {}".format(str(can_send_file)))
        if can_send_file:
            with aiohttp.ClientSession() as session:
                async with session.request(url=url, method="GET") as resp:
                    with io.BytesIO(await resp.read()) as f:
                        await bot.send_file(ctx.message.channel, f, filename=url, content=content)
        else:
            logger.debug("[embed image] warning: cannot attach files in this channel")
            if content is None:
                await bot.say(url)
            else:
                await bot.say("{0} {1}".format(str(content), url))
    except Exception as e:
        logger.warning("Could not embed image, error: {}".format(e))

def configure_logger(name=__name__, stream=True, level=logging.INFO):
    """
    Function to quickly help you configure several loggers.

        ex.: `configure_logger("awesome-logger", False, logging.DEBUG)`
    """
    loginst = logging.getLogger(name)
    loginst.setLevel(logging.INFO if level is None else level)

    path = os.path.abspath(name + ".log")
    #fhnd = logging.FileHandler(path, "w", "utf-8")
    shnd = logging.StreamHandler()
    rhnd = logging.handlers.RotatingFileHandler(path, mode="a", maxBytes=10000000,
        backupCount=10, encoding="utf-8")

    log_fmt = "%(asctime)s::%(name)s [%(levelname)s]: %(message)s"
    fmt = logging.Formatter(log_fmt) # if log_format is None else log_format)
    #fhnd.setFormatter(fmt)
    shnd.setFormatter(fmt)
    rhnd.setFormatter(fmt)

    #loginst.addHandler(fhnd)
    loginst.addHandler(rhnd)
    if stream: loginst.addHandler(shnd)

    return loginst
<|endoftext|>


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

"""
An upload script for Google Music using https://github.com/simon-weber/Unofficial-Google-Music-API.
You may contact the author (thebigmunch) in #gmusicapi on irc.freenode.net.
"""

import os
import sys
from gmusicapi import Musicmanager, CallFailure

input = sys.argv[1:] if len(sys.argv) > 1 else '.'
formats = ('.mp3', '.flac', '.ogg', '.m4a', '.m4b', '.wma')

MM = Musicmanager(debug_logging=False)

def do_auth():
	"""
	Authenticates the MM client.
	"""

	attempts = 0

	# Attempt to login. Perform oauth only when necessary.
	while attempts < 3:
		if MM.login():
			break
		MM.perform_oauth()
		attempts += 1

	if not MM.is_authenticated():
		print "Sorry, login failed."
		return

	print "Successfully logged in.\n"

def do_upload(files):
	"""
	Uploads the files and outputs the upload response with a counter.
	"""

	# Sort the list for sensible output before uploading.
	files.sort()

	filenum = 0
	total = len(files)
	errors = {}

	print "Uploading %s songs to Google Music\n" % total

	for file in files:
		filenum += 1

		try:
			uploaded, matched, not_uploaded = MM.upload(file, transcode_quality="320k", enable_matching=False)
		except CallFailure as e:
			print "(%s/%s) Failed to upload  %s | %s" % (filenum, total, file, e)
			errors[file] = e
		else:
			if uploaded:
				print "(%s/%s) Successfully uploaded  %s" % (filenum, total, file)
			elif matched:
				print "(%s/%s) Successfully scanned and matched  %s" % (filenum, total, file)
			else:
				if "ALREADY_EXISTS" or "this song is already uploaded" in not_uploaded[file]:
					response = "ALREADY EXISTS"
				else:
					response = not_uploaded[file]
				print "(%s/%s) Failed to upload  %s | %s" % (filenum, total, file, response)

	if errors:
		print "\n\nThe following errors occurred:\n"
		for k, v in errors.iteritems():
			print "%s | %s" % (k, v)
		print "\nThese files may need to be synced again.\n"

def get_file_list():
	"""
	Creates a list of supported files from user input(s).
	"""

	files = []

	for i in input:
		if os.path.isfile(i) and i.endswith(formats):
			files.append(i)

		if os.path.isdir(i):
			for dirpath, dirnames, filenames in os.walk(i):
				for filename in filenames:
					if filename.endswith(formats):
						file = os.path.join(dirpath, filename)
						files.append(file)

	return files

def main():
	do_auth()

	files = get_file_list()

	do_upload(files)

	# Log out MM session when finished.
	MM.logout()
	print "All done!"

if __name__ == '__main__':
	main()
<commit_msg>Add argparse option handling to gmupload -h,--help to show the usage help -l,--log will enable gmusicapi's logging -m,--match will enable scan and match<commit_after>#!/usr/bin/env python

"""
An upload script for Google Music using https://github.com/simon-weber/Unofficial-Google-Music-API.
You may contact the author (thebigmunch) in #gmusicapi on irc.freenode.net.
"""

import argparse
import os
import sys
from gmusicapi import Musicmanager, CallFailure

formats = ('.mp3', '.flac', '.ogg', '.m4a', '.m4b', '.wma')

# Parse command line for arguments.
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--log', action='store_true', default=False, help='Enable gmusicapi logging')
parser.add_argument('-m', '--match', action='store_true', default=False, help='Enable scan and match')
parser.add_argument('input', nargs='*', default='.', help='Files, directories, or glob patterns to upload. Defaults to current directory if none given.')
opts = parser.parse_args()

MM = Musicmanager(debug_logging=opts.log)

def do_auth():
	"""
	Authenticates the MM client.
	"""

	attempts = 0

	# Attempt to login. Perform oauth only when necessary.
	while attempts < 3:
		if MM.login():
			break
		MM.perform_oauth()
		attempts += 1

	if not MM.is_authenticated():
		print "Sorry, login failed."
		return

	print "Successfully logged in.\n"

def do_upload(files):
	"""
	Uploads the files and outputs the upload response with a counter.
	"""

	# Sort the list for sensible output before uploading.
	files.sort()

	filenum = 0
	total = len(files)
	errors = {}

	print "Uploading %s songs to Google Music\n" % total

	for file in files:
		filenum += 1

		try:
			uploaded, matched, not_uploaded = MM.upload(file, transcode_quality="320k", enable_matching=opts.match)
		except CallFailure as e:
			print "(%s/%s) Failed to upload  %s | %s" % (filenum, total, file, e)
			errors[file] = e
		else:
			if uploaded:
				print "(%s/%s) Successfully uploaded  %s" % (filenum, total, file)
			elif matched:
				print "(%s/%s) Successfully scanned and matched  %s" % (filenum, total, file)
			else:
				if "ALREADY_EXISTS" or "this song is already uploaded" in not_uploaded[file]:
					response = "ALREADY EXISTS"
				else:
					response = not_uploaded[file]
				print "(%s/%s) Failed to upload  %s | %s" % (filenum, total, file, response)

	if errors:
		print "\n\nThe following errors occurred:\n"
		for k, v in errors.iteritems():
			print "%s | %s" % (k, v)
		print "\nThese files may need to be synced again.\n"

def get_file_list():
	"""
	Creates a list of supported files from user input(s).
	"""

	files = []

	for i in opts.input:
		if os.path.isfile(i) and i.endswith(formats):
			files.append(i)

		if os.path.isdir(i):
			for dirpath, dirnames, filenames in os.walk(i):
				for filename in filenames:
					if filename.endswith(formats):
						file = os.path.join(dirpath, filename)
						files.append(file)

	return files

def main():
	do_auth()

	files = get_file_list()

	do_upload(files)

	# Log out MM session when finished.
	MM.logout()
	print "All done!"

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


<commit_before>"""
Live OAuth2 backend, docs at:
    http://psa.matiasaguirre.net/docs/backends/live.html
"""
from social.backends.oauth import BaseOAuth2

class LiveOAuth2(BaseOAuth2):
    name = 'live'
    AUTHORIZATION_URL = 'https://login.live.com/oauth20_authorize.srf'
    ACCESS_TOKEN_URL = 'https://login.live.com/oauth20_token.srf'
    ACCESS_TOKEN_METHOD = 'POST'
    SCOPE_SEPARATOR = ','
    DEFAULT_SCOPE = ['wl.basic', 'wl.emails']
    EXTRA_DATA = [
        ('id', 'id'),
        ('access_token', 'access_token'),
        ('authentication_token', 'authentication_token'),
        ('refresh_token', 'refresh_token'),
        ('expires_in', 'expires'),
        ('email', 'email'),
        ('first_name', 'first_name'),
        ('last_name', 'last_name'),
        ('token_type', 'token_type'),
    ]

    def get_user_details(self, response):
        """Return user details from Live Connect account"""
        fullname, first_name, last_name = self.get_user_names(
            first_name=response.get('first_name'),
            last_name=response.get('last_name')
        )
        return {'username': response.get('name'),
                'email': response.get('emails', {}).get('account', ''),
                'fullname': fullname,
                'first_name': first_name,
                'last_name': last_name}

    def user_data(self, access_token, *args, **kwargs):
        """Loads user data from service"""
        return self.get_json('https://apis.live.net/v5.0/me', params={
            'access_token': access_token
        })
<commit_msg>set redirect_state to false for live oauth2<commit_after>"""
Live OAuth2 backend, docs at:
    http://psa.matiasaguirre.net/docs/backends/live.html
"""
from social.backends.oauth import BaseOAuth2

class LiveOAuth2(BaseOAuth2):
    name = 'live'
    AUTHORIZATION_URL = 'https://login.live.com/oauth20_authorize.srf'
    ACCESS_TOKEN_URL = 'https://login.live.com/oauth20_token.srf'
    ACCESS_TOKEN_METHOD = 'POST'
    SCOPE_SEPARATOR = ','
    DEFAULT_SCOPE = ['wl.basic', 'wl.emails']
    EXTRA_DATA = [
        ('id', 'id'),
        ('access_token', 'access_token'),
        ('authentication_token', 'authentication_token'),
        ('refresh_token', 'refresh_token'),
        ('expires_in', 'expires'),
        ('email', 'email'),
        ('first_name', 'first_name'),
        ('last_name', 'last_name'),
        ('token_type', 'token_type'),
    ]
    REDIRECT_STATE = False

    def get_user_details(self, response):
        """Return user details from Live Connect account"""
        fullname, first_name, last_name = self.get_user_names(
            first_name=response.get('first_name'),
            last_name=response.get('last_name')
        )
        return {'username': response.get('name'),
                'email': response.get('emails', {}).get('account', ''),
                'fullname': fullname,
                'first_name': first_name,
                'last_name': last_name}

    def user_data(self, access_token, *args, **kwargs):
        """Loads user data from service"""
        return self.get_json('https://apis.live.net/v5.0/me', params={
            'access_token': access_token
        })
<|endoftext|>


<commit_before>#!/usr/bin/python
#Prerequisites:
#pip install requests
#pip install pyqrcode

import requests
import json
import pyqrcode

#Author: Justin Smith
#Date: April 27, 2016
#Description: Simple interface for working with GoatD after it has been configured

#Modified: April 28, 2016
#Reason: Added the ability to see fees for a unit

balance="balance"
units="units"
transfers="transfers/"
fees_unitID="fees?unitID="
fees_amount="&amount="
url=('http://127.0.0.1:2360/v3.0/')

while True:
    menu=raw_input("Press 'a' to see your wallet address and generate a QR code.\nPress 'b' to see your balance.\nPress 'u' to see units available on the Notary.\nPress 's' to see the status of a pending transfer.\nPress 'n' to create a new transfer.'\nPress 'f' to see the fees for a particular unit.\nTo quit, press 'q'.\n\n")

    if menu=="b":
        r = requests.get(url + balance)
        print(r.text)
    elif menu=="a":
        r = requests.get(url + "nym-id")
        url = pyqrcode.create(r.text)
	url.svg(r.text, scale=4)
	print(url.terminal(quiet_zone=1))
	print(r.text)
    elif menu=="u":
        r = requests.get(url+units)
        print(r.text)
    elif menu=="q":
        exit(0)
    elif menu=="s":
        how_many_to_see=raw_input("Which transfer would you like to see? Enter your transfer's history number.\n")
        r = requests.get(url+transfers+how_many_to_see)
        print(r.text)
        raw_input("\n\nPress enter to continue.")
    elif menu=="n":
        unit_type=raw_input("What type of units do you want to send?\nFor Bitcoin use 432jiLUkzDwG8PqyFxiWfxMq1ijL69R3VyUUHq6o6tnv\n\n")
        unit_quantity=raw_input("How many units do you want to send?\n")
        receiver=raw_input("Who do you want to send funds to? Enter their Nym ID\n")
        payload = {receiver:{unit_type:unit_quantity}}
        r = requests.post(url + transfers, json=payload)
        print(r.text)
    elif menu=="f":
        unit_type=raw_input("Which unit would you like to see the fees for?\n\n")
        unit_quantity=raw_input("How much money are you planning to transfer?\n\n")
        r = requests.get(url + fees_unitID + unit_type + fees_amount + unit_quantity)
        #"fees?unitID=ffeoiafoieoeifiafoie&amount=10"
        print(r.text)
    else:
        print("Invalid response.")

raw_input("\n\nPress the enter key to exit.")
<commit_msg>added faucet and transfer capabilities<commit_after>#!/usr/bin/python
#Prerequisites:
#pip install requests
#pip install pyqrcode

import requests
import json
import pyqrcode
import random

#Author: Justin Smith
#Date: April 27, 2016
#Description: Simple interface for working with GoatD after it has been configured

#Modified: April 28, 2016
#Reason: Added the ability to see fees for a unit

my_nym= "Hrv9T8sQajt9oGQfE9MudSkndbaPDusGXLmessNYBAbK"
port = "23765"
version = "/v3.0/"

balance="balance"
units="units"
transfers="transfers/"
fees_unitID="fees?unitID="
fees_amount="&amount="
url= "http://127.0.0.1:" + port + version

CHF_address = "8r6xxNXoAFAbUHXhDJLFsicHkPQF8oitxHdRwg1gzoGh"
Diamonds_address = "6qYPELToPoAwc71AovjPhC5r9t2f9E4ZUd5JcwY5Tnjy"

while True:
    menu=raw_input("Press 'a' for your wallet address QR code.\nPress 'b' to see your balance.\nPress 'l' to get funds.\nPress 'u' to see units available on the Notary.\nPress 'n' to create a new transfer.'\nPress 'f' to see the fees for a unit type.\nTo quit, press 'q'.\n\n")

    if menu=="b":
        wallet_response = requests.get(url + balance)
        print(wallet_response.text)
    elif menu=="a":
        r = requests.get(url + "nym-id")
        url = pyqrcode.create(r.text)
	url.svg(r.text, scale=4)
	print(url.terminal(quiet_zone=1))
	print(r.text)
    elif menu=="u":
        r = requests.get(url+units)
        print(r.text)
        #
        #
    elif menu=="n":
        #amount=raw_input("How many Diamonds do you want to send?\n")
        #Send my phone some funds.
        unit_type=raw_input("Enter the number of the unit type you would like to send, or enter any other character to return to the main menu.\nPlease note: the only fully interoperable units right now are the playing card currencies.\n\n(1) CHF ISO4217\n(2) EUR ISO4217\n(3) JPY ISO4217\n(4) TND ISO4217\n(5) Hearts\n(6) Diamonds\n(7) Spades\n(8) Clubs\n(9) Slice Of Goat Cheese With Fees\n(10) Liter Of Goat Milk With Fees\n\n")
        amount = raw_input("Enter the amount of funds to send. Make sure you have enough, there's no error handling available!\n")
        receiver_nym=raw_input("Who do you want to send funds to? Enter their Nym ID\n")
        #
        #this code works. Leave it for testing.
        #data = '{"'BiqwM9USRHeqtXc3obukNfiTyvwF4NozrVRWL5yUzAGy'":{"6qYPELToPoAwc71AovjPhC5r9t2f9E4ZUd5JcwY5Tnjy":100}}' #receiver nym:unit to send:amount
        #requests.post('http://127.0.0.1:23765/v3.0/transfers', data=data)

        if unit_type == "5":
            data = '{ "'+ receiver_nym +'": {"AZQQJwE6ET4xCDKc3g72AnvoqBcTTyF1PtWzoYJD6Miq": '+ str(amount) +'}}' #Hearts
            requests.post(url + 'transfers', data=data)
            print("Transfer sent!\n\n")
        elif unit_type == "6":
            data = '{ "'+ receiver_nym +'": {"6qYPELToPoAwc71AovjPhC5r9t2f9E4ZUd5JcwY5Tnjy": '+ str(amount) +'}}' #Diamonds
            requests.post(url + 'transfers', data=data)
            print("Transfer sent!\n\n")
        elif unit_type == "7":
            data = '{ "'+ receiver_nym +'": {"GQtgyCzJJWuz3NJuggdYsLDuf1BfTHmEHZ4Fm7uU8RRf": '+ str(amount) +'}}' #Spades
            requests.post(url + 'transfers', data=data)
            print("Transfer sent!\n\n")
        elif unit_type == "8":
            data = '{ "'+ receiver_nym +'": {"EodNsm5J1mxgk8Sjq8QrhRwKdJnSN2N58XJiuhxCoJc9": '+ str(amount) +'}}' #Clubs
            requests.post(url + 'transfers', data=data)
            print("Transfer sent!\n\n")
        else:
            print("Let's go back to the main menu.\n")
        #r = requests.post(url+'/transfers?feesType=$fixedOutput', data=data)
        #print("Please check your balance and confirm the transfer with the recipient.")
        #
        #
    elif menu=="f":
        unit_type=raw_input("Which unit would you like to see the fees for?\n\n")
        unit_quantity=raw_input("How much money are you planning to transfer?\n\n")
        r = requests.get(url + fees_unitID + unit_type + fees_amount + unit_quantity)
        #"fees?unitID=ffeoiafoieoeifiafoie&amount=10"
        print(r.text)
    elif menu=="l":
        amount = random.randint(100,1000)
        unit_type=raw_input("Enter the number of the unit type you would like to receive, or enter any other character to return to the main menu.\n\n(1) CHF ISO4217\n(2) EUR ISO4217\n(3) JPY ISO4217\n(4) TND ISO4217\n(5) Hearts\n(6) Diamonds\n(7) Spades\n(8) Clubs\n(9) Slice Of Goat Cheese With Fees\n(10) Liter Of Goat Milk With Fees\n\n")
        if unit_type == "1":
            data = '{ "'+ my_nym +'": {"8r6xxNXoAFAbUHXhDJLFsicHkPQF8oitxHdRwg1gzoGh": '+ str(amount) +'}}' #Swiss Franc
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            wallet_response = requests.get(url + balance)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "2":
            data = '{ "'+ my_nym +'": {"HT9jb2tsYxi4zDUiGTaLWFAUpNFyiaUaBZHAJ2oCxHaB": '+ str(amount) +'}}' #Euro
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "3":
            data = '{ "'+ my_nym +'": {"BSuefomsihE9YbLxci5awRGP3CwXPmPkW5vxXnGLVLJD": '+ str(amount) +'}}' #Yen
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "4":
            data = '{ "'+ my_nym +'": {"5grZJeP3cVg7a6ren2bQUnkWvcwQ13YT2DoLvPyG98kW": '+ str(amount) +'}}' #TND
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "5":
            data = '{ "'+ my_nym +'": {"AZQQJwE6ET4xCDKc3g72AnvoqBcTTyF1PtWzoYJD6Miq": '+ str(amount) +'}}' #Hearts
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "6":
            data = '{ "'+ my_nym +'": {"6qYPELToPoAwc71AovjPhC5r9t2f9E4ZUd5JcwY5Tnjy": '+ str(amount) +'}}' #Diamonds
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "7":
            data = '{ "'+ my_nym +'": {"GQtgyCzJJWuz3NJuggdYsLDuf1BfTHmEHZ4Fm7uU8RRf": '+ str(amount) +'}}' #Spades
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "8":
            data = '{ "'+ my_nym +'": {"EodNsm5J1mxgk8Sjq8QrhRwKdJnSN2N58XJiuhxCoJc9": '+ str(amount) +'}}' #Clubs
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "9":
            data = '{ "'+ my_nym +'": {"73DzxX5XgZxoRPuJwY5SrhFsEPsf7ubyeShs1QGfdzxJ": '+ str(amount) +'}}' #Slice Of Goat Cheese With Fees
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        elif unit_type == "10":
            data = '{ "'+ my_nym +'": {"6pkHRpVKXWNt4wY5tNXcz6kpobgg6DFCwo5o9FfYkqic": '+ str(amount) +'}}' #Liter Of Goat Milk With Fees
            requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
            print("Please check your balance, you should have received some units.\n")
        else:
            print("Let's go back to the main menu.\n")
        # faucet_address = "http://platformdemo-faucet.monetas.io/v3.0/transfers"
        # payload_string = {'Hrv9T8sQajt9oGQfE9MudSkndbaPDusGXLmessNYBAbK':{'5grZJeP3cVg7a6ren2bQUnkWvcwQ13YT2DoLvPyG98kW':1011}}
        # my_nym = '9NCL5DYxLLNq1U2AgMVn8u27pMvLaVBXtMy57XktDvd6'
        # faucet_unit = '5grZJeP3cVg7a6ren2bQUnkWvcwQ13YT2DoLvPyG98kW'
        # faucet_amount = 1011
        # payload = {my_nym:{faucet_unit:faucet_amount}}
        # f = requests.post(faucet_address, json=payload_string)
        # f = requests.post(faucet_address, json=payload)
        #
        # This stuff below works:
        # data = '{ "Hrv9T8sQajt9oGQfE9MudSkndbaPDusGXLmessNYBAbK": {"6pkHRpVKXWNt4wY5tNXcz6kpobgg6DFCwo5o9FfYkqic": 10110}}'
        # requests.post('http://platformdemo-faucet.monetas.io/v3.0/transfers', data=data)
        # wallet_response = requests.get(url + balance)
        # print(wallet_response.text)
    elif menu=="q":
        exit(0)
    else:
        print("Invalid response.")

raw_input("\n\nPress the enter key to exit.")
<|endoftext|>