<commit_before>from EXOSIMS.Prototypes.StarCatalog import StarCatalog
import numpy as np
import astropy.units as u
from astropy.coordinates import SkyCoord

class FakeCatalog(StarCatalog):

    def __init__(self, ntargs=1000, star_dist=5, ra0 = 0, dec0 = 0, **specs):

        StarCatalog.__init__(self,**specs)

        # ntargs must be an integer >= 1
        self.ntargs = max(int(ntargs), 1)
        self.ra0  = ra0*u.rad
        self.dec0 = dec0*u.rad

        # list of astropy attributes
        self.coords = self.inverse_method(self.ntargs,star_dist)     # ICRS coordinates
        self.ntargs = int(len(self.coords.ra))
        self.dist = star_dist*np.ones(self.ntargs)*u.pc               # distance
        self.parx = self.dist.to('mas', equivalencies=u.parallax())   # parallax
        self.pmra = np.zeros(self.ntargs)*u.mas/u.yr                 # proper motion in RA
        self.pmdec = np.zeros(self.ntargs)*u.mas/u.yr                # proper motion in DEC
        self.rv = np.zeros(self.ntargs)*u.km/u.s                     # radial velocity

        # list of non-astropy attributes to pass target list filters
        self.Name = np.array([str(x) for x in range(self.ntargs)])   # star names
        self.Spec = np.array(['G']*self.ntargs)                      # spectral types
        self.Umag = np.zeros(self.ntargs)                            # U magnitude
        self.Bmag = np.zeros(self.ntargs)                            # B magnitude
        self.Vmag = 5*np.ones(self.ntargs)                           # V magnitude
        self.Rmag = np.zeros(self.ntargs)                            # R magnitude
        self.Imag = np.zeros(self.ntargs)                            # I magnitude
        self.Jmag = np.zeros(self.ntargs)                            # J magnitude
        self.Hmag = np.zeros(self.ntargs)                            # H magnitude
        self.Kmag = np.zeros(self.ntargs)                            # K magnitude
        self.BV = np.zeros(self.ntargs)                              # B-V Johnson magnitude
        self.MV   = self.Vmag - 5*( np.log10(star_dist) - 1 )   # absolute V magnitude
        self.BC   = -0.10*np.ones(self.ntargs)                       # bolometric correction

        BM        = self.MV + self.BC
        L0        = 3.0128e28
        BMsun     = 4.74
        self.L    = L0*10**(0.4*(BMsun-BM))                     # stellar luminosity in ln(SolLum)
        self.Binary_Cut = np.zeros(self.ntargs, dtype=bool)          # binary closer than 10 arcsec

        # populate outspecs
        self._outspec['ntargs'] = self.ntargs

    def inverse_method(self,N,d):

        # getting sizes of the two angular sep distributions
        nP = int(np.floor(N/2.))     # half of stars in positive branch
        nN = nP + 1 if N % 2 else nP # checks to see if N is odd

        # creating output of logistic function (positive and negative branch)
        tP = np.linspace(0.5,0.99,nP)
        tN = np.linspace(0.5,0.01,nN)[1:] # not using the same reference star twice

        # getting inverse of logistic function as distribution of separations
        fP = np.log( tP / (1 - tP) )
        fP = fP/np.abs(fP[-1])

        fN = np.log( tN / (1 - tN) )
        fN = fN/np.abs(fN[-1])

        # getting angular distributions of stars for two branches
        raP,decP,distsP = self.get_angularDistributions(fP,d,pos=True)
        raN,decN,distsN = self.get_angularDistributions(fN,d,pos=False)

        # putting it all together
        ra    = np.hstack([ raP , raN ])* u.rad
        dec   = np.hstack([ decP , decN ]) * u.rad
        dists = np.hstack([ distsP , distsN ]) *u.pc

        ra  += self.ra0
        dec += self.dec0

        # reference star should be first on the list
        coords = SkyCoord(ra,dec,dists)

        return coords

    def get_angularDistributions(self,f,d,pos=True):

        n = int( len(f) )

#        flips = np.arange(1,n,2) if f[0] == 0 else np.arange(0,n,2)
        flips = np.arange(0,n,2)

        # angular separations from reference star
        psi    = np.pi * f
        cosPsi = np.cos(psi)

        # calculating phi angle (i.e. DEC)
        sinPhi = ( np.abs(cosPsi) + ( 1-np.abs(cosPsi))*np.random.rand(n) )
        phi    = np.arcsin( sinPhi ) # only returns angles from 0 to pi/2

        # calculating phi angle (i.e. RA)
        cosTheta    = cosPsi/sinPhi
        theta       = np.arccos(cosTheta)

        # moving stars to southern hemisphere
        phi[flips] = np.pi-phi[flips]
        if pos:
            theta = 2*np.pi - theta

        # final transforms
        dec   = (np.pi/2. - phi)
        dists = d*np.ones(n)

        return theta, dec, dists<commit_msg>specifying seed for numpy random number generator (sometimes SurveySim is bypassed when creating TL)<commit_after>from EXOSIMS.Prototypes.StarCatalog import StarCatalog
import numpy as np
import astropy.units as u
import random as py_random
from astropy.coordinates import SkyCoord

class FakeCatalog(StarCatalog):

    def __init__(self, ntargs=1000, star_dist=5, ra0 = 0, dec0 = 0, **specs):

        StarCatalog.__init__(self,**specs)

        self.seed = int(specs.get('seed', py_random.randint(1,1e9)))
        np.random.seed(self.seed)

        # ntargs must be an integer >= 1
        self.ntargs = max(int(ntargs), 1)
        self.ra0  = ra0*u.rad
        self.dec0 = dec0*u.rad

        # list of astropy attributes
        self.coords = self.inverse_method(self.ntargs,star_dist)     # ICRS coordinates
        self.ntargs = int(len(self.coords.ra))
        self.dist = star_dist*np.ones(self.ntargs)*u.pc               # distance
        self.parx = self.dist.to('mas', equivalencies=u.parallax())   # parallax
        self.pmra = np.zeros(self.ntargs)*u.mas/u.yr                 # proper motion in RA
        self.pmdec = np.zeros(self.ntargs)*u.mas/u.yr                # proper motion in DEC
        self.rv = np.zeros(self.ntargs)*u.km/u.s                     # radial velocity

        # list of non-astropy attributes to pass target list filters
        self.Name = np.array([str(x) for x in range(self.ntargs)])   # star names
        self.Spec = np.array(['G']*self.ntargs)                      # spectral types
        self.Umag = np.zeros(self.ntargs)                            # U magnitude
        self.Bmag = np.zeros(self.ntargs)                            # B magnitude
        self.Vmag = 5*np.ones(self.ntargs)                           # V magnitude
        self.Rmag = np.zeros(self.ntargs)                            # R magnitude
        self.Imag = np.zeros(self.ntargs)                            # I magnitude
        self.Jmag = np.zeros(self.ntargs)                            # J magnitude
        self.Hmag = np.zeros(self.ntargs)                            # H magnitude
        self.Kmag = np.zeros(self.ntargs)                            # K magnitude
        self.BV = np.zeros(self.ntargs)                              # B-V Johnson magnitude
        self.MV   = self.Vmag - 5*( np.log10(star_dist) - 1 )   # absolute V magnitude
        self.BC   = -0.10*np.ones(self.ntargs)                       # bolometric correction

        BM        = self.MV + self.BC
        L0        = 3.0128e28
        BMsun     = 4.74
        self.L    = L0*10**(0.4*(BMsun-BM))                     # stellar luminosity in ln(SolLum)
        self.Binary_Cut = np.zeros(self.ntargs, dtype=bool)          # binary closer than 10 arcsec

        # populate outspecs
        self._outspec['ntargs'] = self.ntargs

    def inverse_method(self,N,d):

        # getting sizes of the two angular sep distributions
        nP = int(np.floor(N/2.))     # half of stars in positive branch
        nN = nP + 1 if N % 2 else nP # checks to see if N is odd

        # creating output of logistic function (positive and negative branch)
        tP = np.linspace(0.5,0.99,nP)
        tN = np.linspace(0.5,0.01,nN)[1:] # not using the same reference star twice

        # getting inverse of logistic function as distribution of separations
        fP = np.log( tP / (1 - tP) )
        fP = fP/np.abs(fP[-1])

        fN = np.log( tN / (1 - tN) )
        fN = fN/np.abs(fN[-1])

        # getting angular distributions of stars for two branches
        raP,decP,distsP = self.get_angularDistributions(fP,d,pos=True)
        raN,decN,distsN = self.get_angularDistributions(fN,d,pos=False)

        # putting it all together
        ra    = np.hstack([ raP , raN ])* u.rad
        dec   = np.hstack([ decP , decN ]) * u.rad
        dists = np.hstack([ distsP , distsN ]) *u.pc

        ra  += self.ra0
        dec += self.dec0

        # reference star should be first on the list
        coords = SkyCoord(ra,dec,dists)

        return coords

    def get_angularDistributions(self,f,d,pos=True):

        n = int( len(f) )

#        flips = np.arange(1,n,2) if f[0] == 0 else np.arange(0,n,2)
        flips = np.arange(0,n,2)

        # angular separations from reference star
        psi    = np.pi * f
        cosPsi = np.cos(psi)

        # calculating phi angle (i.e. DEC)
        sinPhi = ( np.abs(cosPsi) + ( 1-np.abs(cosPsi))*np.random.rand(n) )
        phi    = np.arcsin( sinPhi ) # only returns angles from 0 to pi/2

        # calculating phi angle (i.e. RA)
        cosTheta    = cosPsi/sinPhi
        theta       = np.arccos(cosTheta)

        # moving stars to southern hemisphere
        phi[flips] = np.pi-phi[flips]
        if pos:
            theta = 2*np.pi - theta

        # final transforms
        dec   = (np.pi/2. - phi)
        dists = d*np.ones(n)

        return theta, dec, dists<|endoftext|>


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

"""
Command Line Interface to the methods exposed by LIEStudio microservices
"""

import argparse
import re
import os, sys

USAGE= """
MDStudio command line interface.

Call a method exposed by a MDStudio microservice using it's public URI

Authentication:
User name and password are retrieved from the shell MDSTUDIO_USER and
MDSTUDIO_PW environmental variables by default or provided using the
'authid' and 'password' command line arguments respectivly.

Default authentication method ('authmethod') is set to 'ticket'.
"""

def _commandline_arg_py2(bytestring):
    """
    Decode unicode command line strings on Python 2.x
    """
    unicode_string = bytestring.decode(sys.getfilesystemencoding())
    return unicode_string

def _commandline_arg_py3(bytestring):
    """
    In Python 3.x everything is unicode
    """
    return bytestring

# Define command line argument unicode decoder based on Python major version
if sys.version[0] == '2':
    _commandline_arg = _commandline_arg_py2
else:
    _commandline_arg = _commandline_arg_py3

def _abspath(path):
    """
    Check file and resolve absolute path

    :param path: relative path
    :type path:  :py:str

    :return:     absolute path
    :rtype:      :py:str
    """

    if os.path.isfile(path):
        return os.path.abspath(path)

    return None

def _parse_variable_arguments(args, prefix='-'):
    """
    Parse an argument list with keyword argument identified as having a single
    or double dash as prefix (-, --) or other character defined by the `prefix`
    argument.
    All non-keyword arguments following a keyword are assigned values to the
    keyword. If there are no values, the keyword is treated as boolean argument.

    :param args:   argument list to parse
    :type args:    :py:list
    :param prefix: prefix character used to identify keyword arguments
    :type prefix:  :py:str

    :return:       variable name/arguments dictionary
    :rtype:        :py:dict
    """

    # Keyword positions, discard negative numbers
    positions = [e for e, n in enumerate(args) if n.startswith(prefix) and not re.match('^[-+]?[0-9]+$', n)]

    # Split the argument list based on keyword positions
    method_args = {}
    length = len(positions) - 1
    for i, kwp in enumerate(positions):
        if i < length:
            argument = args[kwp: positions[i + 1]]
        else:
            argument = args[kwp:]

        # Check for double declaration of keywords, not allowed
        var_name = argument[0].strip(prefix)
        assert var_name not in method_args, 'Variable declared twice: {0}'.format(var_name)

        # Format boolean argument
        if len(argument) == 1:
            method_args[var_name] = True
        elif len(argument) == 2:
            method_args[var_name] = argument[1]
        else:
            method_args[var_name] = argument[1:]

    return method_args

def lie_cli_parser():
    """
    Command Line Interface parser

    Builds the CLI parser used by the mdstudio_cli script
    """

    # Create the top-level parser
    parser = argparse.ArgumentParser(prog="MDStudio", usage=USAGE, description="MDStudio CLI")

    # Parse application session and microservice WAMP arguments
    parser.add_argument('-u', '--uri', type=_commandline_arg, dest='uri', required=True, help='Microservice method URI')
    parser.add_argument('-c', '--authid', type=_commandline_arg, dest='authid', default=os.environ.get('MDSTUDIO_USER'),
                        help="MDStudio user id")
    parser.add_argument('-p', '--password', type=_commandline_arg, dest='password', default=os.environ.get('MDSTUDIO_PW'),
                        help="MDStudio user pasword")
    parser.add_argument('-m', '--authmethod', type=_commandline_arg, dest='authmethod', default='ticket',
                        help="MDStudio authentication method")

    # parse command line arguments
    options, method_args = parser.parse_known_args()

    # Convert argparse NameSpace object to dict
    options = vars(options)

    # Parse all unknown arguments. These are the keyword arguments passed to
    # the microservice method
    options['package_config'] = _parse_variable_arguments(method_args)

    # Check if there are file path among the variables and convert to absolute paths
    for k, v in options['package_config'].items():
        try:
            if isinstance(v, list):
                options['package_config'][k] = [_abspath(n) for n in v if n]
            else:
                options['package_config'][k] = _abspath(v)
        except:
            pass

    # Add method URI
    options['package_config']['uri'] = options['uri']

    return options
<commit_msg>Small fixes<commit_after># -*- coding: utf-8 -*-

"""
Command Line Interface to the methods exposed by LIEStudio microservices
"""

import argparse
import re
import os, sys

USAGE= """
MDStudio command line interface.

Call a method exposed by a MDStudio microservice using it's public URI

Authentication:
User name and password are retrieved from the shell MDSTUDIO_USER and
MDSTUDIO_PW environmental variables by default or provided using the
'authid' and 'password' command line arguments respectivly.

Default authentication method ('authmethod') is set to 'ticket'.
"""

def _commandline_arg_py2(bytestring):
    """
    Decode unicode command line strings on Python 2.x
    """
    unicode_string = bytestring.decode(sys.getfilesystemencoding())
    return unicode_string

def _commandline_arg_py3(bytestring):
    """
    In Python 3.x everything is unicode
    """
    return bytestring

# Define command line argument unicode decoder based on Python major version
if sys.version[0] == '2':
    _commandline_arg = _commandline_arg_py2
else:
    _commandline_arg = _commandline_arg_py3

def _abspath(path):
    """
    Check file and resolve absolute path

    :param path: relative path
    :type path:  :py:str

    :return:     absolute path
    :rtype:      :py:str
    """

    if os.path.isfile(path):
        return os.path.abspath(path)

    return path

def _parse_variable_arguments(args, prefix='-'):
    """
    Parse an argument list with keyword argument identified as having a single
    or double dash as prefix (-, --) or other character defined by the `prefix`
    argument.
    All non-keyword arguments following a keyword are assigned values to the
    keyword. If there are no values, the keyword is treated as boolean argument.

    :param args:   argument list to parse
    :type args:    :py:list
    :param prefix: prefix character used to identify keyword arguments
    :type prefix:  :py:str

    :return:       variable name/arguments dictionary
    :rtype:        :py:dict
    """

    # Keyword positions, discard negative numbers
    positions = [e for e, n in enumerate(args) if n.startswith(prefix) and not re.match('^[-+]?[0-9]+$', n)]

    # Split the argument list based on keyword positions
    method_args = {}
    length = len(positions) - 1
    for i, kwp in enumerate(positions):
        if i < length:
            argument = args[kwp: positions[i + 1]]
        else:
            argument = args[kwp:]

        # Check for double declaration of keywords, not allowed
        var_name = argument[0].strip(prefix)
        assert var_name not in method_args, 'Variable declared twice: {0}'.format(var_name)

        # Format boolean argument
        if len(argument) == 1:
            method_args[var_name] = True
        elif len(argument) == 2:
            method_args[var_name] = argument[1]
        else:
            method_args[var_name] = argument[1:]

    return method_args

def lie_cli_parser():
    """
    Command Line Interface parser

    Builds the CLI parser used by the mdstudio_cli script
    """

    # Create the top-level parser
    parser = argparse.ArgumentParser(prog="MDStudio", usage=USAGE, description="MDStudio CLI")

    # Parse application session and microservice WAMP arguments
    parser.add_argument('-u', '--uri', type=_commandline_arg, dest='uri', required=True, help='Microservice method URI')
    parser.add_argument('-c', '--authid', type=_commandline_arg, dest='authid', default=os.environ.get('MDSTUDIO_USER'),
                        help="MDStudio user id")
    parser.add_argument('-p', '--password', type=_commandline_arg, dest='password', default=os.environ.get('MDSTUDIO_PW'),
                        help="MDStudio user pasword")
    parser.add_argument('-m', '--authmethod', type=_commandline_arg, dest='authmethod', default='ticket',
                        help="MDStudio authentication method")

    # parse command line arguments
    options, method_args = parser.parse_known_args()

    # Convert argparse NameSpace object to dict
    options = vars(options)

    # Parse all unknown arguments. These are the keyword arguments passed to
    # the microservice method
    options['package_config'] = _parse_variable_arguments(method_args)

    # Check if there are file path among the variables and convert to absolute paths
    for k, v in options['package_config'].items():
        try:
            if isinstance(v, list):
                options['package_config'][k] = [_abspath(n) for n in v if n]
            else:
                options['package_config'][k] = _abspath(v)
        except:
            pass

    # Add method URI
    options['package_config']['uri'] = options['uri']

    return options
<|endoftext|>


<commit_before>import sys
import base64
import json
import subprocess

try:
    import ssl
except ImportError:
    ssl = False

try:
    str_instances = (str, basestring)
except Exception:
    str_instances = (str, )

try:
    import urllib
    from urllib.request import Request, urlopen
    HTTPError = urllib.error.HTTPError
    URLError = urllib.error.URLError
except (AttributeError, ImportError, ValueError):
    import urllib2
    from urllib2 import Request, urlopen
    HTTPError = urllib2.HTTPError
    URLError = urllib2.URLError

try:
    from .. import editor
    from . import shared as G, utils
except ImportError:
    import editor
    import shared as G
    import utils

def get_basic_auth():
    basic_auth = ('%s:%s' % (G.API_KEY or G.USERNAME, G.SECRET)).encode('utf-8')
    basic_auth = base64.encodestring(basic_auth)
    return basic_auth.decode('ascii').replace('\n', '')

class APIResponse():
    def __init__(self, r):
        if isinstance(r, bytes):
            r = r.decode('utf-8')
        if isinstance(r, str_instances):
            lines = r.split('\n')
            self.code = int(lines[0])
            self.body = json.loads('\n'.join(lines[1:]))
        else:
            self.code = r.code
            self.body = json.loads(r.read())

def proxy_api_request(url, data=None):
    args = ['python', '-m', 'floo.proxy', '--url', url]
    if data:
        args += ["--data", json.dumps(data)]
    proc = subprocess.Popen(args, cwd=G.PLUGIN_PATH, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    (stdout, stderr) = proc.communicate()
    if stderr:
        raise IOError(stderr)

    if proc.poll() != 0:
        raise IOError(stdout)
    r = APIResponse(stdout)
    return r

def hit_url(url, data=None):
    if data:
        data = json.dumps(data).encode('utf-8')
    r = Request(url, data=data)
    r.add_header('Authorization', 'Basic %s' % get_basic_auth())
    r.add_header('Accept', 'application/json')
    r.add_header('Content-type', 'application/json')
    r.add_header('User-Agent', 'Floobits Plugin %s %s %s py-%s.%s' % (
        editor.name(),
        G.__PLUGIN_VERSION__,
        editor.platform(),
        sys.version_info[0],
        sys.version_info[1]
    ))
    return urlopen(r, timeout=5)

def api_request(url, data=None):
    if ssl is False:
        return proxy_api_request(url, data)
    try:
        r = hit_url(url, data)
    except HTTPError as e:
        r = e
    return APIResponse(r)

def create_workspace(post_data):
    url = 'https://%s/api/workspace/' % G.DEFAULT_HOST
    return api_request(url, post_data)

def get_workspace_by_url(url):
    result = utils.parse_url(url)
    api_url = 'https://%s/api/workspace/%s/%s/' % (result['host'], result['owner'], result['workspace'])
    return api_request(api_url)

def get_workspace(owner, workspace):
    api_url = 'https://%s/api/workspace/%s/%s/' % (G.DEFAULT_HOST, owner, workspace)
    return api_request(api_url)

def get_workspaces():
    api_url = 'https://%s/api/workspace/can/view/' % (G.DEFAULT_HOST)
    return api_request(api_url)

def get_orgs():
    api_url = 'https://%s/api/orgs/' % (G.DEFAULT_HOST)
    return api_request(api_url)

def get_orgs_can_admin():
    api_url = 'https://%s/api/orgs/can/admin/' % (G.DEFAULT_HOST)
    return api_request(api_url)

def send_error(data):
    try:
        api_url = 'https://%s/api/error/' % (G.DEFAULT_HOST)
        return api_request(api_url, data)
    except Exception as e:
        print(e)
<commit_msg>More python 3 fixes. Log what we're printing out.<commit_after>import sys
import base64
import json
import subprocess

try:
    import ssl
except ImportError:
    ssl = False

try:
    str_instances = (str, basestring)
except Exception:
    str_instances = (str, )

try:
    import urllib
    from urllib.request import Request, urlopen
    HTTPError = urllib.error.HTTPError
    URLError = urllib.error.URLError
except (AttributeError, ImportError, ValueError):
    import urllib2
    from urllib2 import Request, urlopen
    HTTPError = urllib2.HTTPError
    URLError = urllib2.URLError

try:
    from .. import editor
    from . import msg, shared as G, utils
except ImportError:
    import editor
    import msg
    import shared as G
    import utils

def get_basic_auth():
    basic_auth = ('%s:%s' % (G.API_KEY or G.USERNAME, G.SECRET)).encode('utf-8')
    basic_auth = base64.encodestring(basic_auth)
    return basic_auth.decode('ascii').replace('\n', '')

class APIResponse():
    def __init__(self, r):
        if isinstance(r, bytes):
            r = r.decode('utf-8')
        if isinstance(r, str_instances):
            lines = r.split('\n')
            self.code = int(lines[0])
            self.body = json.loads('\n'.join(lines[1:]))
        else:
            self.code = r.code
            self.body = json.loads(r.read())

def proxy_api_request(url, data=None):
    args = ['python', '-m', 'floo.proxy', '--url', url]
    if data:
        args += ["--data", json.dumps(data)]
    msg.debug('Running %s' % ' '.join(args))
    proc = subprocess.Popen(args, cwd=G.PLUGIN_PATH, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    (stdout, stderr) = proc.communicate()
    if stderr:
        raise IOError(stderr)

    if proc.poll() != 0:
        raise IOError(stdout)
    r = APIResponse(stdout)
    return r

def hit_url(url, data=None):
    if data:
        data = json.dumps(data).encode('utf-8')
    r = Request(url, data=data)
    r.add_header('Authorization', 'Basic %s' % get_basic_auth())
    r.add_header('Accept', 'application/json')
    r.add_header('Content-type', 'application/json')
    r.add_header('User-Agent', 'Floobits Plugin %s %s %s py-%s.%s' % (
        editor.name(),
        G.__PLUGIN_VERSION__,
        editor.platform(),
        sys.version_info[0],
        sys.version_info[1]
    ))
    return urlopen(r, timeout=5)

def api_request(url, data=None):
    if ssl is False:
        return proxy_api_request(url, data)
    try:
        r = hit_url(url, data)
    except HTTPError as e:
        r = e
    return APIResponse(r)

def create_workspace(post_data):
    url = 'https://%s/api/workspace/' % G.DEFAULT_HOST
    return api_request(url, post_data)

def get_workspace_by_url(url):
    result = utils.parse_url(url)
    api_url = 'https://%s/api/workspace/%s/%s/' % (result['host'], result['owner'], result['workspace'])
    return api_request(api_url)

def get_workspace(owner, workspace):
    api_url = 'https://%s/api/workspace/%s/%s/' % (G.DEFAULT_HOST, owner, workspace)
    return api_request(api_url)

def get_workspaces():
    api_url = 'https://%s/api/workspace/can/view/' % (G.DEFAULT_HOST)
    return api_request(api_url)

def get_orgs():
    api_url = 'https://%s/api/orgs/' % (G.DEFAULT_HOST)
    return api_request(api_url)

def get_orgs_can_admin():
    api_url = 'https://%s/api/orgs/can/admin/' % (G.DEFAULT_HOST)
    return api_request(api_url)

def send_error(data):
    try:
        api_url = 'https://%s/api/error/' % (G.DEFAULT_HOST)
        return api_request(api_url, data)
    except Exception as e:
        print(e)
<|endoftext|>


<commit_before>import os, sys

try:
    import simplejson as json
except ImportError:
    import json

from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED

MEDIATYPES = {
    'html': "text/html",
    'xhtml': "application/xhtml+xml",
    'css': 'text/css',
    'json': "application/json",

    'png': 'image/png',
    'gif': 'image/gif',
    'jpg': 'image/jpeg',
    'jpeg': 'image/jpeg',
    'svg': 'image/svg+xml',

    'ncx': 'application/x-dtbncx+xml',
    'dtb': 'application/x-dtbook+xml',
    'xml': 'application/xml',

    'pdf': "application/pdf",
    'txt': 'text/plain',

    'epub': "application/epub+zip",
    'booki': "application/x-booki+zip",

    None: 'application/octet-stream',
}

#metadata construction routines
DC = "http://purl.org/dc/elements/1.1/"
FM = "http://booki.cc/"

def get_metadata(metadata, key, ns=DC,
                 scheme='', default=[]):
    """Get a list of metadata values matching a key, namespace and
    scheme.  If the ns or scheme are not set, they default to Dublin
    Core and an empty string, respectively.

    If no values are set, an empty list is returned, unless the
    default argument is given, in which case you get that.
    """
    values = metadata.get(ns, {}).get(key, {})
    if scheme == '*':
        return sum(values.values(), [])
    return values.get(scheme, default)

def get_metadata_schemes(metadata, key, ns=DC):
    """Say what schemes are available for a given key and namespace."""
    values = metadata.get(ns, {}).get(key, {})
    return values.keys()

def add_metadata(metadata, key, value, ns=DC, scheme=''):
    """Add a metadata (ns, key, scheme, value) tuple. Namespace
    defaults to Dublin Core, and scheme to an empty string.  In most
    cases that is what you want."""
    namespace = metadata.setdefault(ns, {})
    items = namespace.setdefault(key, {})
    values = items.setdefault(scheme, [])
    values.append(value)

def clear_metadata(metadata, key, ns=DC, scheme='*'):
    """Clear metadata for a key in a namespace (ns).  If namespace is
    ommited, Dublin Core is assumed.  If a scheme is specified (and is
    not '*'), only metadata in that scheme is removed.  By default all
    schemes are removed.

    If ns is '*', that key is removed from all namespaces.
    """
    if ns in metadata:
        if key in metadata[ns]:
            if scheme == '*':
                metadata[ns][key] = {}
            elif scheme in metadata[ns][key]:
                del metadata[ns][key][scheme]
        elif ns == '*':
            for ns in metadata:
                clear_metadata(metadata, key, ns, scheme)

class BookiZip(object):
    """Helper for writing booki-zips"""

    def __init__(self, filename, info={}):
        """Start a new zip and put an uncompressed 'mimetype' file at the
        start.  This idea is copied from the epub specification, and
        allows the file type to be dscovered by reading the first few
        bytes."""
        self.zipfile = ZipFile(filename, 'w', ZIP_DEFLATED, allowZip64=True)
        self.write_blob('mimetype', MEDIATYPES['booki'], ZIP_STORED)
        self.filename = filename
        self.manifest = {}
        self.info = info

    def write_blob(self, filename, blob, compression=ZIP_DEFLATED, mode=0644):
        """Add something to the zip without adding to manifest"""
        zinfo = ZipInfo(filename)
        zinfo.external_attr = mode << 16L # set permissions
        zinfo.compress_type = compression
        self.zipfile.writestr(zinfo, blob)

    def add_to_package(self, ID, fn, blob, mediatype=None,
                       contributors=[], rightsholders=[], license=[]):
        """Add an item to the zip, and save it in the manifest.  If
        mediatype is not provided, it will be guessed according to the
        extrension."""
        self.write_blob(fn, blob)
        if mediatype is None:
            ext = fn[fn.rfind('.') + 1:]
            mediatype = MEDIATYPES.get(ext, MEDIATYPES[None])
        self.manifest[ID] = {
            "url":           fn,
            "mimetype":      mediatype,
            "contributors":  contributors,
            "rightsholders": rightsholders,
            "license":       license,
            }

    def _close(self):
        self.zipfile.close()

    def finish(self):
        """Finalise the metadata and write to disk"""
        self.info['manifest'] = self.manifest
        infojson = json.dumps(self.info, indent=2)
        self.add_to_package('info.json', 'info.json', infojson, 'application/json')
        self._close()

<commit_msg>Add tiff extension to bookizip.<commit_after>import os, sys

try:
    import simplejson as json
except ImportError:
    import json

from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED

MEDIATYPES = {
    'html': "text/html",
    'xhtml': "application/xhtml+xml",
    'css': 'text/css',
    'json': "application/json",

    'png': 'image/png',
    'gif': 'image/gif',
    'jpg': 'image/jpeg',
    'jpeg': 'image/jpeg',
    'svg': 'image/svg+xml',
    'tiff': 'image/tiff',

    'ncx': 'application/x-dtbncx+xml',
    'dtb': 'application/x-dtbook+xml',
    'xml': 'application/xml',

    'pdf': "application/pdf",
    'txt': 'text/plain',

    'epub': "application/epub+zip",
    'booki': "application/x-booki+zip",

    None: 'application/octet-stream',
}

#metadata construction routines
DC = "http://purl.org/dc/elements/1.1/"
FM = "http://booki.cc/"

def get_metadata(metadata, key, ns=DC,
                 scheme='', default=[]):
    """Get a list of metadata values matching a key, namespace and
    scheme.  If the ns or scheme are not set, they default to Dublin
    Core and an empty string, respectively.

    If no values are set, an empty list is returned, unless the
    default argument is given, in which case you get that.
    """
    values = metadata.get(ns, {}).get(key, {})
    if scheme == '*':
        return sum(values.values(), [])
    return values.get(scheme, default)

def get_metadata_schemes(metadata, key, ns=DC):
    """Say what schemes are available for a given key and namespace."""
    values = metadata.get(ns, {}).get(key, {})
    return values.keys()

def add_metadata(metadata, key, value, ns=DC, scheme=''):
    """Add a metadata (ns, key, scheme, value) tuple. Namespace
    defaults to Dublin Core, and scheme to an empty string.  In most
    cases that is what you want."""
    namespace = metadata.setdefault(ns, {})
    items = namespace.setdefault(key, {})
    values = items.setdefault(scheme, [])
    values.append(value)

def clear_metadata(metadata, key, ns=DC, scheme='*'):
    """Clear metadata for a key in a namespace (ns).  If namespace is
    ommited, Dublin Core is assumed.  If a scheme is specified (and is
    not '*'), only metadata in that scheme is removed.  By default all
    schemes are removed.

    If ns is '*', that key is removed from all namespaces.
    """
    if ns in metadata:
        if key in metadata[ns]:
            if scheme == '*':
                metadata[ns][key] = {}
            elif scheme in metadata[ns][key]:
                del metadata[ns][key][scheme]
        elif ns == '*':
            for ns in metadata:
                clear_metadata(metadata, key, ns, scheme)

class BookiZip(object):
    """Helper for writing booki-zips"""

    def __init__(self, filename, info={}):
        """Start a new zip and put an uncompressed 'mimetype' file at the
        start.  This idea is copied from the epub specification, and
        allows the file type to be dscovered by reading the first few
        bytes."""
        self.zipfile = ZipFile(filename, 'w', ZIP_DEFLATED, allowZip64=True)
        self.write_blob('mimetype', MEDIATYPES['booki'], ZIP_STORED)
        self.filename = filename
        self.manifest = {}
        self.info = info

    def write_blob(self, filename, blob, compression=ZIP_DEFLATED, mode=0644):
        """Add something to the zip without adding to manifest"""
        zinfo = ZipInfo(filename)
        zinfo.external_attr = mode << 16L # set permissions
        zinfo.compress_type = compression
        self.zipfile.writestr(zinfo, blob)

    def add_to_package(self, ID, fn, blob, mediatype=None,
                       contributors=[], rightsholders=[], license=[]):
        """Add an item to the zip, and save it in the manifest.  If
        mediatype is not provided, it will be guessed according to the
        extrension."""
        self.write_blob(fn, blob)
        if mediatype is None:
            ext = fn[fn.rfind('.') + 1:]
            mediatype = MEDIATYPES.get(ext, MEDIATYPES[None])
        self.manifest[ID] = {
            "url":           fn,
            "mimetype":      mediatype,
            "contributors":  contributors,
            "rightsholders": rightsholders,
            "license":       license,
            }

    def _close(self):
        self.zipfile.close()

    def finish(self):
        """Finalise the metadata and write to disk"""
        self.info['manifest'] = self.manifest
        infojson = json.dumps(self.info, indent=2)
        self.add_to_package('info.json', 'info.json', infojson, 'application/json')
        self._close()

<|endoftext|>


<commit_before>'''
1. There are a row of houses, each house can be painted with three colors red, blue and green.
The cost of painting each house with a certain color is different. You have to paint all the houses
such that no two adjacent houses have the same color. You have to paint the houses with minimum cost.
How would you do it?

Note: Painting house-1 with red costs different from painting house-2 with red. The costs are different
for each house and each color.

Reference: http://karmaandcoding.blogspot.com/2012/02/house-coloring-with-red-blue-and-green.html
'''

def sort_colors(matrix):
        if not matrix or not matrix[0]: return 0
        house_num = len(matrix)
        color_num = len(matrix[0])

        dp = [ [0 for i in xrange(color_num)] for j in xrange(house_num)]

        for i in xrange(house_num):
                for j in xrange(color_num):
                        if i == 0:
                                dp[0][j] = matrix[0][j]
                        else:
                                tmp = dp[i-1][:j] + dp[i-1][j+1:]
                                lastmin = min(tmp)
                                dp[i][j] = lastmin + matrix[i][j]
        return min(dp[house_num-1])

matrix = [[1, 2, 3], [6, 7, 5], [2, 6, 8]]
print sort_colors(matrix)

'''
2. Copy Random List, optimization use O(1)
'''

'''
3. large scale下怎么设计一个根据关键词查询status的service。我自然又是一顿瞎扯，神马invert index, consistent hashing, 想到什么扯什么。
然而这并没有什么卵用。。不论扯到什么大哥都要刨根问底，我到最后就完全招架不住了。。大哥的表情也就越来越蛋疼了。。这轮结束后我觉得基本
就没戏了，design面这么烂基本是硬伤，弥补不了了。
'''

'''
4
有这么一个class Contact，里面有一个string的name，和一个vector 装着email address，是这个Contact有的address，用一个list装着是因为一个人有可能有多个email，现在给你vector，比如
{
    { "Johhhn", {"john@gmail.com"} },
    { "Mary", {"mary@gmail.com"} },
    { "John", {"john@yahoo.com"} },
    { "John", {"john@gmail.com", "john@yahoo.com", "john@hotmail.com"} },
    { "Bob",  {"bob@gmail.com"} }
}

现在我们知道如果email address相同的话，那么就说明是同一个人，现在要做的是根据这些email address，
把同一个contact给group起来. 比如我们就可以知道#1，#3，#4是同一个人。注意不能根据名字来group，因为有可
能有相同名字的人，或者同一个人有可能有不同的名字来注册之类的。

* Reference: http://www.fgdsb.com/tags/Union-Find/
'''

class Contact:
    def __init__(self, name, email):
        self.name = name
        self.emails = email # list of emails

class UnionFind:
    def __init__(self, n):
        self.father = [i for i in xrange(n)]
        self.ranks = [0 for i in xrange(n)]

    def find(self, x):
        if self.father[x] == x:
            return x
        return find(self.father[x])

    def do_union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y: return
        if self.ranks[x] < self.ranks[y]:
            self.father[x] = y
        else:
            self.father[y] = x
            if self.ranks[x] == self.ranks[y]:
                self.ranks[x] += 1

class Solution:
    def group_contacts(self, contact):
        n = len(contact)
        uf = UnionFind(n)
        email_map = {}
        # first build the map like
        # {"john@gmail.com":[0,3],
        #  "mary@gmail.com": [1],
        #  "john@yahoo.com": [2,3],
        #  "john@hotmail.com": [3],
        #  "bob@gmail.com": [4]}
        for i in xrange(n):
            for email in contact[i].emails:
                email_map.setdefault(email, []).append(i)

        # then for each list in each email, join them into one group
        # so father init: [0,1,2,3,4]
        # after [0,1,0,0,4]
        for p in email_map:
            for j in xrange(len(email_map[p])-1):
                uf.do_union(j, j+1)

        # Then group for each root, create a list
        # {0: [0,2,3],
        #  1, [1],
        #  4, [4]}
        group = {}
        for i in xrange(n):
            group.setdefault(uf.find(i),[]).append(i)

        result = []
        for p in group:
            rec = []
            for i in group[p]:
                rec.append(contact[i])
            result.append(rec)
        return result

<commit_msg>Update facebook面经集合.py<commit_after>'''
1. There are a row of houses, each house can be painted with three colors red, blue and green.
The cost of painting each house with a certain color is different. You have to paint all the houses
such that no two adjacent houses have the same color. You have to paint the houses with minimum cost.
How would you do it?

Note: Painting house-1 with red costs different from painting house-2 with red. The costs are different
for each house and each color.

Reference: http://karmaandcoding.blogspot.com/2012/02/house-coloring-with-red-blue-and-green.html
'''

def sort_colors(matrix):
        if not matrix or not matrix[0]: return 0
        house_num = len(matrix)
        color_num = len(matrix[0])

        dp = [ [0 for i in xrange(color_num)] for j in xrange(house_num)]

        for i in xrange(house_num):
                for j in xrange(color_num):
                        if i == 0:
                                dp[0][j] = matrix[0][j]
                        else:
                                tmp = dp[i-1][:j] + dp[i-1][j+1:]
                                lastmin = min(tmp)
                                dp[i][j] = lastmin + matrix[i][j]
        return min(dp[house_num-1])

matrix = [[1, 2, 3], [6, 7, 5], [2, 6, 8]]
print sort_colors(matrix)

'''
2. Copy Random List, optimization use O(1)
'''

'''
3. large scale下怎么设计一个根据关键词查询status的service。我自然又是一顿瞎扯，神马invert index, consistent hashing, 想到什么扯什么。
然而这并没有什么卵用。。不论扯到什么大哥都要刨根问底，我到最后就完全招架不住了。。大哥的表情也就越来越蛋疼了。。这轮结束后我觉得基本
就没戏了，design面这么烂基本是硬伤，弥补不了了。
'''

'''
4
有这么一个class Contact，里面有一个string的name，和一个vector 装着email address，是这个Contact有的address，用一个list装着是因为一个人有可能有多个email，现在给你vector，比如
{
    { "Johhhn", {"john@gmail.com"} },
    { "Mary", {"mary@gmail.com"} },
    { "John", {"john@yahoo.com"} },
    { "John", {"john@gmail.com", "john@yahoo.com", "john@hotmail.com"} },
    { "Bob",  {"bob@gmail.com"} }
}

现在我们知道如果email address相同的话，那么就说明是同一个人，现在要做的是根据这些email address，
把同一个contact给group起来. 比如我们就可以知道#1，#3，#4是同一个人。注意不能根据名字来group，因为有可
能有相同名字的人，或者同一个人有可能有不同的名字来注册之类的。

* Reference: http://www.fgdsb.com/tags/Union-Find/
'''

class Contact:
    def __init__(self, name, email):
        self.name = name
        self.emails = email # list of emails

class UnionFind:
    def __init__(self, n):
        self.father = [i for i in xrange(n)]
        self.ranks = [0 for i in xrange(n)]

    def find(self, x):
        if self.father[x] == x:
            return x
        return find(self.father[x])

    def do_union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y: return
        if self.ranks[x] < self.ranks[y]:
            self.father[x] = y
        else:
            self.father[y] = x
            if self.ranks[x] == self.ranks[y]:
                self.ranks[x] += 1

class Solution:
    def group_contacts(self, contact):
        n = len(contact)
        uf = UnionFind(n)
        email_map = {}
        # first build the map like
        # {"john@gmail.com":[0,3],
        #  "mary@gmail.com": [1],
        #  "john@yahoo.com": [2,3],
        #  "john@hotmail.com": [3],
        #  "bob@gmail.com": [4]}
        for i in xrange(n):
            for email in contact[i].emails:
                email_map.setdefault(email, []).append(i)

        # then for each list in each email, join them into one group
        # so father init: [0,1,2,3,4]
        # after [0,1,0,0,4]
        for p in email_map:
            for j in xrange(len(email_map[p])-1):
                uf.do_union(j, j+1)

        # Then group for each root, create a list
        # {0: [0,2,3],
        #  1, [1],
        #  4, [4]}
        group = {}
        for i in xrange(n):
            group.setdefault(uf.find(i),[]).append(i)

        result = []
        for p in group:
            rec = []
            for i in group[p]:
                rec.append(contact[i])
            result.append(rec)
        return result

'''
5. 给你一个array，返回array里面最大数字的index，
但是必须是最大数字里面随机的一个index。比如[2,1,2,1,5,4,5,5]必须返回[4,6,7]中的随机的一个数字，要求O(1)space.

# Reservoir Sampling https://github.com/UmassJin/Leetcode/blob/master/Algorithm/Reservoir_Sampling_Google.md
# http://www.fgdsb.com/2015/01/15/random-maximum/
'''

import random

def random_max(array):
    if not array: return None
    n = len(array)
    imax = -1 << 31
    result = 0

    for i in xrange(len(array)):
        if array[i] > imax:
            imax = array[i]
            count = 1
            result = array[i]
        elif array[i] == imax:
            count += 1
            print "count: ", count
            if random.randrange(count) == 0:
                print "count: ", count
                print "i: ", i
                result = array[i]
    return result

test = [2,1,2,1,5,4,5,5]
print random_max(test)
<|endoftext|>


<commit_before>"""
Backup your entire facebook conversations.

Friend list is read from a config file.
"""

import json
import os
import requests
import sys
import time

from config import friends, form_data, headers

# Can be used to download a range of messages
offset = 0
limit = 2000

timestamp = 0

# Used to find the end of conversation thread
END_MARK = "end_of_history"

FB_URL = "https://www.facebook.com/ajax/mercury/thread_info.php"

ROOT = "Messages"

def mkdir(f):
    """ Create a directory if it doesn't already exist. """
    if not os.path.exists(f):
        os.makedirs(f)

def fetch(data):
    """ Fetch data from Facebook. """

    offset = [v for k, v in data.items() if 'offset' in k][0]
    limit = [v for k, v in data.items() if 'limit' in k][0]

    print("\t%7d  -  %7d" % (offset, offset+limit))

    response = requests.post(FB_URL, data=data, headers=headers)

    # Account for 'for (;;);' in the beginning of the text.
    return response.content[9:]

def confirm(question):
    """ Confirm whether the files should be moved. """
    valid = {'y': True, 'n': False}
    while True:
        sys.stdout.write(question + " [y/n]: ")
        choice = raw_input().lower()
        if choice in valid:
            return valid[choice]
        else:
            sys.stdout.write("Please respond with 'y' or 'n'.\n")

if __name__ == '__main__':

    for friend_id, friend_name in friends.items():

        if not confirm("Fetch converstaion with '%s'?" % friend_name):
            continue

        print("Retrieving Messages of: %s" % friend_name)

        # Setup data directory
        dirname = os.path.join(ROOT, friend_name)
        mkdir(dirname)

        # We want it ALL!
        offset, data = 0, {"payload": ""}
        while END_MARK not in data['payload']:

            form_data["messages[user_ids][%s][offset]" % friend_id] = offset
            form_data["messages[user_ids][%s][limit]" % friend_id] = limit
            form_data["messages[user_ids][%s][timestamp]" % friend_id] = str(timestamp)

            content = fetch(form_data)

            # Handle facebook rate limits
            while not content:
                print("Facebook Rate Limit Reached. Retrying after 30 secs")
                time.sleep(30)
                content = fetch(form_data)

            # Build JSON representation
            data = json.loads(content)

            # Dump Data
            filename = "%s.json" % (limit+offset)
            with open(os.path.join(dirname, filename), "w") as op:
                json.dump(data, op, indent=2)

            # Next!
            offset = offset + limit
            timestamp = data['payload']['actions'][0]['timestamp']
            time.sleep(2)

        # Make the form_data usable for the next user
        form_data.pop("messages[user_ids][%s][offset]" % friend_id)
        form_data.pop("messages[user_ids][%s][limit]" % friend_id)

        print("\t---END---")
<commit_msg>Facebook: Reset some parameters everytime<commit_after>"""
Backup your entire facebook conversations.

Friend list is read from a config file.
"""

import json
import os
import requests
import sys
import time

from config import friends, form_data, headers

# Can be used to download a range of messages
limit = 2000

# Used to find the end of conversation thread
END_MARK = "end_of_history"

FB_URL = "https://www.facebook.com/ajax/mercury/thread_info.php"

ROOT = "Messages"

def mkdir(f):
    """ Create a directory if it doesn't already exist. """
    if not os.path.exists(f):
        os.makedirs(f)

def fetch(data):
    """ Fetch data from Facebook. """

    offset = [v for k, v in data.items() if 'offset' in k][0]
    limit = [v for k, v in data.items() if 'limit' in k][0]

    print("\t%6d  -  %6d" % (offset, offset+limit))

    response = requests.post(FB_URL, data=data, headers=headers)

    # Account for 'for (;;);' in the beginning of the text.
    return response.content[9:]

def confirm(question):
    """ Confirm whether the files should be moved. """
    valid = {'y': True, 'n': False}
    while True:
        sys.stdout.write(question + " [y/n]: ")
        choice = raw_input().lower()
        if choice in valid:
            return valid[choice]
        else:
            sys.stdout.write("Please respond with 'y' or 'n'.\n")

if __name__ == '__main__':

    for friend_id, friend_name in friends.items():

        if not confirm("Fetch converstaion with '%s'?" % friend_name):
            continue

        print("Retrieving Messages of: %s" % friend_name)

        # Setup data directory
        dirname = os.path.join(ROOT, friend_name)
        mkdir(dirname)

        # These parameters need to be reset everytime
        offset = 0
        timestamp = 0
        data = {"payload": ""}

        # We want it ALL!
        while END_MARK not in data['payload']:

            form_data["messages[user_ids][%s][offset]" % friend_id] = offset
            form_data["messages[user_ids][%s][limit]" % friend_id] = limit
            form_data["messages[user_ids][%s][timestamp]" % friend_id] = str(timestamp)

            content = fetch(form_data)

            # Handle facebook rate limits
            while not content:
                print("Facebook Rate Limit Reached. Retrying after 30 secs")
                time.sleep(30)
                content = fetch(form_data)

            # Build JSON representation
            data = json.loads(content)

            # Dump Data
            filename = "%s.json" % (limit+offset)
            with open(os.path.join(dirname, filename), "w") as op:
                json.dump(data, op, indent=2)

            # Next!
            offset = offset + limit
            timestamp = data['payload']['actions'][0]['timestamp']
            time.sleep(2)

        # Make the form_data usable for the next user
        form_data.pop("messages[user_ids][%s][offset]" % friend_id)
        form_data.pop("messages[user_ids][%s][limit]" % friend_id)

        print("\t-----END-----")
<|endoftext|>


<commit_before>import discord
import os
from datetime import datetime
from discord.ext import commands

from .utils.dataIO import dataIO
from .utils import checks

try: # check if BeautifulSoup4 is installed
    from bs4 import BeautifulSoup
    soupAvailable = True
except:
    soupAvailable = False

import aiohttp

class hangman:
    def __init__(self, bot):
        self.bot = bot
        self.path = "data/Fox-Cogs/hangman"
        self.file_path = "data/Fox-Cogs/hangman/hangman.json"
        self.the_data = dataIO.load_json(self.file_path)
        self.hangman = (
        """
            _________
            |/
            |
            |
            |
            |
            |
            |___
        """,

        """
           _________
            |/   |
            |
            |
            |
            |
            |
            |___
            H""",

        """
           _________
            |/   |
            |   (_)
            |
            |
            |
            |
            |___
            HA""",

        """
           ________
            |/   |
            |   (_)
            |    |
            |    |
            |
            |
            |___
            HAN""",

        """
           _________
            |/   |
            |   (_)
            |   /|
            |    |
            |
            |
            |___
            HANG""",

        """
           _________
            |/   |
            |   (_)
            |   /|\
            |    |
            |
            |
            |___
            HANGM""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   /
            |
            |___
            HANGMA""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   / \
            |
            |___
            HANGMAN""")

    def save_data(self):
        dataIO.save_json(self.file_path, self.the_data)

    @commands.command(aliases=['h'], pass_context=True)
    async def hangman(self, ctx, guess : str=None):
        """Play a game of hangman against the bot!"""
        if guess is None:
            if self.the_data["running"] == True:
                await self.bot.say("Game of hangman is already running!\nEnter your guess!")
                """await self.bot.send_cmd_help(ctx)"""
            else:
                await self.bot.say("Starting a game of hangman!")
                await self._startgame()
                await self._printgame()

        else:
            await self.bot.say("A game of hangman is now stopping!")
            await self._stopgame()
        """
        #self.the_data["WOAH"]["knarly"] = "Biiiiiitch"
        if "Yeah dude" not in self.the_data:
            self.the_data["Yeah dude"]={}
        self.the_data["Yeah dude"]["knarly"]= {"ur lyin" : True,
                                               "kick-ass" : { "no way!!!" : "Biiiiiitch" },
                                               "created_at" : datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                                               }

        #self.the_data["Yeah dude"]["knarly"] = "ur lyin"
        #self.the_data["Yeah dude"]["knarly"]["kick-ass"]["no way!!!"] = "Biiiiiitch"
        self.save_data()
        """

    async def _startgame(self):
        self.the_data["running"] = True
        self.the_data["hangman"] = 0
        self.save_data()

        #self._getphrase()
        #self._printgame()

    async def _stopgame(self):
        self.the_data["running"] = False
        self.save_data()

    async def _getphrase(self):
        '''Get a new phrase for the game'''
        url = "https://www.playstationtrophies.org/forum/wheel-of-fortune-2012-/176009-wheel-fortune-answer-list.html"
        async with aiohttp.get(url) as response:
            soupObject = BeautifulSoup(await response.text(), "html.parser")
        try:
            online = soupObject.find(class_='home-stats').find('li').find('strong').get_text()
            await self.bot.say(online + ' players are playing this game at the moment')
        except:
            await self.bot.say("Couldn't load amount of players. No one is playing this game anymore or there's an error.")

    async def _guessletter(self):
        '''Checks the guess on a letter'''

    async def _printgame(self):
        '''Print the current state of game'''
        await self.bot.say(self.hangman[the_data["hangman"]])
        self.the_data["hangman"] += 1
        self.save_data()

def check_folders():
    if not os.path.exists("data/Fox-Cogs"):
        print("Creating data/Fox-Cogs folder...")
        os.makedirs("data/Fox-Cogs")

    if not os.path.exists("data/Fox-Cogs/hangman"):
        print("Creating data/Fox-Cogs/hangman folder...")
        os.makedirs("data/Fox-Cogs/hangman")

def check_files():
    if not dataIO.is_valid_json("data/Fox-Cogs/hangman/hangman.json"):
        dataIO.save_json("data/Fox-Cogs/hangman/hangman.json" ,{"running" : False, "hangman" : 0 })

def setup(bot):
    check_folders()
    check_files()
    if soupAvailable:
        bot.add_cog(hangman(bot))
    else:
        raise RuntimeError("You need to run `pip3 install beautifulsoup4`")
        <commit_msg>shorter<commit_after>import discord
import os
from datetime import datetime
from discord.ext import commands

from .utils.dataIO import dataIO
from .utils import checks

try: # check if BeautifulSoup4 is installed
    from bs4 import BeautifulSoup
    soupAvailable = True
except:
    soupAvailable = False

import aiohttp

class hangman:
    def __init__(self, bot):
        self.bot = bot
        self.path = "data/Fox-Cogs/hangman"
        self.file_path = "data/Fox-Cogs/hangman/hangman.json"
        self.the_data = dataIO.load_json(self.file_path)
        self.hangman = ( "","H","HA","HAN","HANG","HANGM","HANGMA","HANGMAN")

        '''self.hangman = (
        """
            _________
            |/
            |
            |
            |
            |
            |
            |___
            """,

        """
           _________
            |/   |
            |
            |
            |
            |
            |
            |___
            H""",

        """
           _________
            |/   |
            |   (_)
            |
            |
            |
            |
            |___
            HA""",

        """
           ________
            |/   |
            |   (_)
            |    |
            |    |
            |
            |
            |___
            HAN""",

        """
           _________
            |/   |
            |   (_)
            |   /|
            |    |
            |
            |
            |___
            HANG""",

        """
           _________
            |/   |
            |   (_)
            |   /|\
            |    |
            |
            |
            |___
            HANGM""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   /
            |
            |___
            HANGMA""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   / \
            |
            |___
            HANGMAN""")'''

    def save_data(self):
        dataIO.save_json(self.file_path, self.the_data)

    @commands.command(aliases=['h'], pass_context=True)
    async def hangman(self, ctx, guess : str=None):
        """Play a game of hangman against the bot!"""
        if guess is None:
            if self.the_data["running"] == True:
                await self.bot.say("Game of hangman is already running!\nEnter your guess!")
                """await self.bot.send_cmd_help(ctx)"""
            else:
                await self.bot.say("Starting a game of hangman!")
                await self._startgame()
                await self._printgame()

        else:
            await self.bot.say("A game of hangman is now stopping!")
            await self._stopgame()
        """
        #self.the_data["WOAH"]["knarly"] = "Biiiiiitch"
        if "Yeah dude" not in self.the_data:
            self.the_data["Yeah dude"]={}
        self.the_data["Yeah dude"]["knarly"]= {"ur lyin" : True,
                                               "kick-ass" : { "no way!!!" : "Biiiiiitch" },
                                               "created_at" : datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                                               }

        #self.the_data["Yeah dude"]["knarly"] = "ur lyin"
        #self.the_data["Yeah dude"]["knarly"]["kick-ass"]["no way!!!"] = "Biiiiiitch"
        self.save_data()
        """

    async def _startgame(self):
        self.the_data["running"] = True
        self.the_data["hangman"] = 0
        self.save_data()

        #self._getphrase()
        #self._printgame()

    async def _stopgame(self):
        self.the_data["running"] = False
        self.save_data()

    async def _getphrase(self):
        '''Get a new phrase for the game'''
        url = "https://www.playstationtrophies.org/forum/wheel-of-fortune-2012-/176009-wheel-fortune-answer-list.html"
        async with aiohttp.get(url) as response:
            soupObject = BeautifulSoup(await response.text(), "html.parser")
        try:
            online = soupObject.find(class_='home-stats').find('li').find('strong').get_text()
            await self.bot.say(online + ' players are playing this game at the moment')
        except:
            await self.bot.say("Couldn't load amount of players. No one is playing this game anymore or there's an error.")

    async def _guessletter(self):
        '''Checks the guess on a letter'''

    async def _printgame(self):
        '''Print the current state of game'''
        await self.bot.say(self.hangman[the_data["hangman"]])
        self.the_data["hangman"] += 1
        self.save_data()

def check_folders():
    if not os.path.exists("data/Fox-Cogs"):
        print("Creating data/Fox-Cogs folder...")
        os.makedirs("data/Fox-Cogs")

    if not os.path.exists("data/Fox-Cogs/hangman"):
        print("Creating data/Fox-Cogs/hangman folder...")
        os.makedirs("data/Fox-Cogs/hangman")

def check_files():
    if not dataIO.is_valid_json("data/Fox-Cogs/hangman/hangman.json"):
        dataIO.save_json("data/Fox-Cogs/hangman/hangman.json" ,{"running" : False, "hangman" : 0 })

def setup(bot):
    check_folders()
    check_files()
    if soupAvailable:
        bot.add_cog(hangman(bot))
    else:
        raise RuntimeError("You need to run `pip3 install beautifulsoup4`")
        <|endoftext|>


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

"""
Work out the first ten digits of the sum of the following one-hundred 50-digit numbers. (Numbers in text file)
"""

import time

filename = '13_numbers_to_sum.txt'

def get_sol():
    total = sum([int(s.strip()) for s in open(filename).readlines()])
    return int(str(total)[:10])

start = time.time()

print(get_sol())

elapsed = (time.time() - start)
print("\nThis code took: {} seconds".format(str(elapsed)))

def test_function():
    assert get_sol() == 5537376230
<commit_msg>Removed test on 13 b/c of file needing import<commit_after>#!/usr/bin/env python

"""
Work out the first ten digits of the sum of the following one-hundred 50-digit numbers. (Numbers in text file)
"""

import time

filename = '13_numbers_to_sum.txt'

def get_sol():
    total = sum([int(s.strip()) for s in open(filename).readlines()])
    return int(str(total)[:10])

start = time.time()

print(get_sol())

elapsed = (time.time() - start)
print("\nThis code took: {} seconds".format(str(elapsed)))

#def test_function():
#    assert get_sol() == 5537376230
<|endoftext|>


<commit_before>from django import forms
from django.utils.translation import ugettext_lazy as _
from sentry.plugins.bases.issue import IssuePlugin
from sentry.utils import json

import sentry_github_issues
import urllib2

class GitHubIssuesOptionsForm(forms.Form):
    repo = forms.CharField(label=_('Repository Name'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. getsentry/sentry'}),
        help_text=_('Enter your repository name, including the owner.'))

    access_token = forms.CharField(label=_('access token'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. xxxxxxxxxxxxxxxxxxxxxxxx'}),
        help_text=_('Enter your personal access token, create here https://github.com/settings/tokens/new'))

    api_endpoint = forms.CharField(label=_('API endpoint'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. https://github.example.com/api/v3/'}),
        help_text=_('if Github Enterprise, Enter api endpoint. '), required=False)

    web_endpoint = forms.CharField(label=_('Web endpoint'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. https://github.example.com/'}),
        help_text=_('if Github Enterprise, Enter web endpoint. '), required=False)

    label = forms.CharField(label=_('label'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. sentry'}),
        help_text=_('Enter label text.'), required=False)

class GitHubIssuesPlugin(IssuePlugin):
    slug = 'github-issues'
    title = _('GitHub Issues')
    author = 'Yoshiori SHOJI'
    author_url = 'https://github.com/yoshiori'
    version = sentry_github_issues.VERSION
    description = "Integrate GitHub issues by linking a repository to a project."
    resource_links = [
        ('Bug Tracker', 'https://github.com/yoshiori/sentry-github-issues/issues'),
        ('Source', 'https://github.com/yoshiori/sentry-github-issues'),
    ]
    conf_key = slug
    project_conf_form = GitHubIssuesOptionsForm

    def is_configured(self, request, project, **kwargs):
        return bool(self.get_option('repo', project))

    def get_new_issue_title(self, **kwargs):
        return 'Create GitHub Issue'

    def create_issue(self, request, group, form_data, **kwargs):
        repo = self.get_option('repo', group.project)
        api_endpoint = self.get_option('api_endpoint', group.project) or "https://api.github.com/"

        url = '%srepos/%s/issues' % (api_endpoint, repo,)
        data = {
          "title": form_data['title'],
        }
        data["body"] = '%s\n\n[View on Sentry]' % (form_data['description'], group.get_absolute_url())
        label = self.get_option('label', group.project)
        if label:
            data["label"] = [label]

        req = urllib2.Request(url, json.dumps(data))
        req.add_header('User-Agent', 'sentry-issue-github/%s' % self.version)
        req.add_header('Authorization', 'token %s' % self.get_option('access_token', group.project))
        req.add_header('Content-Type', 'application/json')

        try:
            resp = urllib2.urlopen(req)
        except Exception, e:
            if isinstance(e, urllib2.HTTPError):
                msg = e.read()
                if 'application/json' in e.headers.get('Content-Type', ''):
                    try:
                        msg = json.loads(msg)
                        msg = msg['message']
                    except Exception:
                        pass
            else:
                msg = unicode(e)
            raise forms.ValidationError(_('Error communicating with GitHub issues: %s') % (msg,))

        try:
            data = json.loads(resp.read())
        except Exception, e:
            raise forms.ValidationError(_('Error decoding response from GitHub issues: %s') % (e,))

        return data['number']

    def get_issue_label(self, group, issue_id, **kwargs):
        return 'GH-%s' % issue_id

    def get_issue_url(self, group, issue_id, **kwargs):
        repo = self.get_option('repo', group.project)
        web_endpoint = self.get_option('web_endpoint', group.project) or "https://github.com/"
        return '%s%s/issues/%s' % (web_endpoint, repo, issue_id)
<commit_msg>Fix labels param<commit_after>from django import forms
from django.utils.translation import ugettext_lazy as _
from sentry.plugins.bases.issue import IssuePlugin
from sentry.utils import json

import sentry_github_issues
import urllib2

class GitHubIssuesOptionsForm(forms.Form):
    repo = forms.CharField(label=_('Repository Name'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. getsentry/sentry'}),
        help_text=_('Enter your repository name, including the owner.'))

    access_token = forms.CharField(label=_('access token'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. xxxxxxxxxxxxxxxxxxxxxxxx'}),
        help_text=_('Enter your personal access token, create here https://github.com/settings/tokens/new'))

    api_endpoint = forms.CharField(label=_('API endpoint'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. https://github.example.com/api/v3/'}),
        help_text=_('if Github Enterprise, Enter api endpoint. '), required=False)

    web_endpoint = forms.CharField(label=_('Web endpoint'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. https://github.example.com/'}),
        help_text=_('if Github Enterprise, Enter web endpoint. '), required=False)

    label = forms.CharField(label=_('label'),
        widget=forms.TextInput(attrs={'placeholder': 'e.g. sentry'}),
        help_text=_('Enter label text.'), required=False)

class GitHubIssuesPlugin(IssuePlugin):
    slug = 'github-issues'
    title = _('GitHub Issues')
    author = 'Yoshiori SHOJI'
    author_url = 'https://github.com/yoshiori'
    version = sentry_github_issues.VERSION
    description = "Integrate GitHub issues by linking a repository to a project."
    resource_links = [
        ('Bug Tracker', 'https://github.com/yoshiori/sentry-github-issues/issues'),
        ('Source', 'https://github.com/yoshiori/sentry-github-issues'),
    ]
    conf_key = slug
    project_conf_form = GitHubIssuesOptionsForm

    def is_configured(self, request, project, **kwargs):
        return bool(self.get_option('repo', project))

    def get_new_issue_title(self, **kwargs):
        return 'Create GitHub Issue'

    def create_issue(self, request, group, form_data, **kwargs):
        repo = self.get_option('repo', group.project)
        api_endpoint = self.get_option('api_endpoint', group.project) or "https://api.github.com/"

        url = '%srepos/%s/issues' % (api_endpoint, repo,)
        data = {
          "title": form_data['title'],
        }
        data["body"] = '%s\n\n[View on Sentry]' % (form_data['description'], group.get_absolute_url())
        labels = self.get_option('label', group.project)
        if labels:
            data["labels"] = [x.strip() for x in labels.split(",")]

        req = urllib2.Request(url, json.dumps(data))
        req.add_header('User-Agent', 'sentry-issue-github/%s' % self.version)
        req.add_header('Authorization', 'token %s' % self.get_option('access_token', group.project))
        req.add_header('Content-Type', 'application/json')

        try:
            resp = urllib2.urlopen(req)
        except Exception, e:
            if isinstance(e, urllib2.HTTPError):
                msg = e.read()
                if 'application/json' in e.headers.get('Content-Type', ''):
                    try:
                        msg = json.loads(msg)
                        msg = msg['message']
                    except Exception:
                        pass
            else:
                msg = unicode(e)
            raise forms.ValidationError(_('Error communicating with GitHub issues: %s') % (msg,))

        try:
            data = json.loads(resp.read())
        except Exception, e:
            raise forms.ValidationError(_('Error decoding response from GitHub issues: %s') % (e,))

        return data['number']

    def get_issue_label(self, group, issue_id, **kwargs):
        return 'GH-%s' % issue_id

    def get_issue_url(self, group, issue_id, **kwargs):
        repo = self.get_option('repo', group.project)
        web_endpoint = self.get_option('web_endpoint', group.project) or "https://github.com/"
        return '%s%s/issues/%s' % (web_endpoint, repo, issue_id)
<|endoftext|>


<commit_before>import os
import re
import string

def filelist(root):
    """Return a fully-qualified list of filenames under root directory"""

def get_text(fileName):
    f = open(fileName)
    s = f.read()
    f.close()
    return s

def words(text):
    """
    Given a string, return a list of words normalized as follows.
    Split the string to make words first by using regex compile() function
    and string.punctuation + '0-9\\r\\t\\n]' to replace all those
    char with a space character.
    Split on space to get word list.
    Ignore words < 3 char long.
    Lowercase all words
    """

def results(docs, terms):
    """
    Given a list of fully-qualifed filenames, return an HTML file
    that displays the results and up to 2 lines from the file.
    Return at most 100 results.  Arg terms is a list of string terms.
    """

def filenames(docs):
    """Return just the filenames from list of fully-qualified filenames"""
    if docs is None:
        return []
    return [os.path.basename(d) for d in docs]
<commit_msg>tweak<commit_after>import os
import re
import string

def filelist(root):
    """Return a fully-qualified list of filenames under root directory"""

def get_text(fileName):
    f = open(fileName)
    s = f.read()
    f.close()
    return s

def words(text):
    """
    Given a string, return a list of words normalized as follows.
    Split the string to make words first by using regex compile() function
    and string.punctuation + '0-9\\r\\t\\n]' to replace all those
    char with a space character.
    Split on space to get word list.
    Ignore words < 3 char long.
    Lowercase all words
    """

def results(docs, terms):
    """
    Given a list of fully-qualifed filenames, return an HTML file
    that displays the results and up to 2 lines from the file
    that have at least one of the search terms.
    Return at most 100 results.  Arg terms is a list of string terms.
    """

def filenames(docs):
    """Return just the filenames from list of fully-qualified filenames"""
    if docs is None:
        return []
    return [os.path.basename(d) for d in docs]
<|endoftext|>


<commit_before>from __future__ import unicode_literals
import re
from django.utils import datetime_safe
from django.utils import six
from django.template import loader, Context
from haystack.exceptions import SearchFieldError

class NOT_PROVIDED:
    pass

DATETIME_REGEX = re.compile('^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})(T|\s+)(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2}).*?$')

# All the SearchFields variants.

class SearchField(object):
    """The base implementation of a search field."""
    field_type = None

    def __init__(self, model_attr=None, use_template=False, template_name=None,
                 document=False, indexed=True, stored=True, faceted=False,
                 default=NOT_PROVIDED, null=False, index_fieldname=None,
                 facet_class=None, boost=1.0, weight=None):
        # Track what the index thinks this field is called.
        self.instance_name = None
        self.model_attr = model_attr
        self.use_template = use_template
        self.template_name = template_name
        self.document = document
        self.indexed = indexed
        self.stored = stored
        self.faceted = faceted
        self._default = default
        self.null = null
        self.index_fieldname = index_fieldname
        self.boost = weight or boost
        self.is_multivalued = False

        # We supply the facet_class for making it easy to create a faceted
        # field based off of this field.
        self.facet_class = facet_class

        if self.facet_class is None:
            self.facet_class = FacetCharField

        self.set_instance_name(None)

    def set_instance_name(self, instance_name):
        self.instance_name = instance_name

        if self.index_fieldname is None:
            self.index_fieldname = self.instance_name

    def has_default(self):
        """Returns a boolean of whether this field has a default value."""
        return self._default is not NOT_PROVIDED

    @property
    def default(self):
        """Returns the default value for the field."""
        if callable(self._default):
            return self._default()

        return self._default

    def prepare(self, obj):
        """
        Takes data from the provided object and prepares it for storage in the
        index.
        """
        # Give priority to a template.
        if self.use_template:
            return self.prepare_template(obj)
        elif self.model_attr is not None:
            # Check for `__` in the field for looking through the relation.
            attrs = self.model_attr.split('__')
            current_object = obj

            for attr in attrs:
                if not hasattr(current_object, attr):
                    raise SearchFieldError("The model '%s' does not have a model_attr '%s'." % (repr(obj), attr))

                current_object = getattr(current_object, attr, None)

                if current_object is None:
                    if self.has_default():
                        current_object = self._default
                        # Fall out of the loop, given any further attempts at
                        # accesses will fail misreably.
                        break
                    elif self.null:
                        current_object = None
                        # Fall out of the loop, given any further attempts at
                        # accesses will fail misreably.
                        break
                    else:
                        raise SearchFieldError("The model '%s' has an empty model_attr '%s' and doesn't allow a default or null value." % (repr(obj), attr))

            if callable(current_object):
                return current_object()

            return current_object

        if self.has_default():
            return self.default
        else:
            return None

    def prepare_template(self, obj):
        """
        Flattens an object for indexing.

        This loads a template
        (``search/indexes/{app_label}/{model_name}_{field_name}.txt``) and
        returns the result of rendering that template. ``object`` will be in
        its context.
        """
        if self.instance_name is None and self.template_name is None:
            raise SearchFieldError("This field requires either its instance_name variable to be populated or an explicit template_name in order to load the correct template.")

        if self.template_name is not None:
            template_names = self.template_name

            if not isinstance(template_names, (list, tuple)):
                template_names = [template_names]
        else:
            template_names = ['search/indexes/%s/%s_%s.txt' % (obj._meta.app_label, obj._meta.module_name, self.instance_name)]

        t = loader.select_template(template_names)
        return t.render(Context({'object': obj}))

    def convert(self, value):
        """
        Handles conversion between the data found and the type of the field.

        Extending classes should override this method and provide correct
        data coercion.
        """
        return value

class CharField(SearchField):
    field_type = 'string'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetCharField

        super(CharField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(CharField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return six.text_type(value)

class LocationField(SearchField):
    field_type = 'location'

    def prepare(self, obj):
        from haystack.utils.geo import ensure_point

        value = super(LocationField, self).prepare(obj)

        if value is None:
            return None

        pnt = ensure_point(value)
        pnt_lng, pnt_lat = pnt.get_coords()
        return "%s,%s" % (pnt_lat, pnt_lng)

    def convert(self, value):
        from haystack.utils.geo import ensure_point, Point

        if value is None:
            return None

        if hasattr(value, 'geom_type'):
            value = ensure_point(value)
            return value

        if isinstance(value, six.string_types):
            lat, lng = value.split(',')
        elif isinstance(value, (list, tuple)):
            # GeoJSON-alike
            lat, lng = value[1], value[0]
        elif isinstance(value, dict):
            lat = value.get('lat', 0)
            lng = value.get('lon', 0)

        value = Point(float(lng), float(lat))
        return value

class NgramField(CharField):
    field_type = 'ngram'

    def __init__(self, **kwargs):
        if kwargs.get('faceted') is True:
            raise SearchFieldError("%s can not be faceted." % self.__class__.__name__)

        super(NgramField, self).__init__(**kwargs)

class EdgeNgramField(NgramField):
    field_type = 'edge_ngram'

class IntegerField(SearchField):
    field_type = 'integer'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetIntegerField

        super(IntegerField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(IntegerField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return int(value)

class FloatField(SearchField):
    field_type = 'float'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetFloatField

        super(FloatField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(FloatField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return float(value)

class DecimalField(SearchField):
    field_type = 'string'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetDecimalField

        super(DecimalField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(DecimalField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return six.text_type(value)

class BooleanField(SearchField):
    field_type = 'boolean'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetBooleanField

        super(BooleanField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(BooleanField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return bool(value)

class DateField(SearchField):
    field_type = 'date'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetDateField

        super(DateField, self).__init__(**kwargs)

    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, six.string_types):
            match = DATETIME_REGEX.search(value)

            if match:
                data = match.groupdict()
                return datetime_safe.date(int(data['year']), int(data['month']), int(data['day']))
            else:
                raise SearchFieldError("Date provided to '%s' field doesn't appear to be a valid date string: '%s'" % (self.instance_name, value))

        return value

class DateTimeField(SearchField):
    field_type = 'datetime'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetDateTimeField

        super(DateTimeField, self).__init__(**kwargs)

    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, six.string_types):
            match = DATETIME_REGEX.search(value)

            if match:
                data = match.groupdict()
                return datetime_safe.datetime(int(data['year']), int(data['month']), int(data['day']), int(data['hour']), int(data['minute']), int(data['second']))
            else:
                raise SearchFieldError("Datetime provided to '%s' field doesn't appear to be a valid datetime string: '%s'" % (self.instance_name, value))

        return value

class MultiValueField(SearchField):
    field_type = 'string'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetMultiValueField

        if kwargs.get('use_template') is True:
            raise SearchFieldError("'%s' fields can not use templates to prepare their data." % self.__class__.__name__)

        super(MultiValueField, self).__init__(**kwargs)
        self.is_multivalued = True

    def prepare(self, obj):
        return self.convert(super(MultiValueField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return list(value)

class FacetField(SearchField):
    """
    ``FacetField`` is slightly different than the other fields because it can
    work in conjunction with other fields as its data source.

    Accepts an optional ``facet_for`` kwarg, which should be the field name
    (not ``index_fieldname``) of the field it should pull data from.
    """
    instance_name = None

    def __init__(self, **kwargs):
        handled_kwargs = self.handle_facet_parameters(kwargs)
        super(FacetField, self).__init__(**handled_kwargs)

    def handle_facet_parameters(self, kwargs):
        if kwargs.get('faceted', False):
            raise SearchFieldError("FacetField (%s) does not accept the 'faceted' argument." % self.instance_name)

        if not kwargs.get('null', True):
            raise SearchFieldError("FacetField (%s) does not accept False for the 'null' argument." % self.instance_name)

        if not kwargs.get('indexed', True):
            raise SearchFieldError("FacetField (%s) does not accept False for the 'indexed' argument." % self.instance_name)

        if kwargs.get('facet_class'):
            raise SearchFieldError("FacetField (%s) does not accept the 'facet_class' argument." % self.instance_name)

        self.facet_for = None
        self.facet_class = None

        # Make sure the field is nullable.
        kwargs['null'] = True

        if 'facet_for' in kwargs:
            self.facet_for = kwargs['facet_for']
            del(kwargs['facet_for'])

        return kwargs

    def get_facet_for_name(self):
        return self.facet_for or self.instance_name

class FacetCharField(FacetField, CharField):
    pass

class FacetIntegerField(FacetField, IntegerField):
    pass

class FacetFloatField(FacetField, FloatField):
    pass

class FacetDecimalField(FacetField, DecimalField):
    pass

class FacetBooleanField(FacetField, BooleanField):
    pass

class FacetDateField(FacetField, DateField):
    pass

class FacetDateTimeField(FacetField, DateTimeField):
    pass

class FacetMultiValueField(FacetField, MultiValueField):
    pass
<commit_msg>Use get_model_ct_tuple to generate template name<commit_after># encoding: utf-8
from __future__ import unicode_literals

import re

from django.template import Context, loader
from django.utils import datetime_safe, six

from haystack.exceptions import SearchFieldError
from haystack.utils import get_model_ct_tuple

class NOT_PROVIDED:
    pass

DATETIME_REGEX = re.compile('^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})(T|\s+)(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2}).*?$')

# All the SearchFields variants.

class SearchField(object):
    """The base implementation of a search field."""
    field_type = None

    def __init__(self, model_attr=None, use_template=False, template_name=None,
                 document=False, indexed=True, stored=True, faceted=False,
                 default=NOT_PROVIDED, null=False, index_fieldname=None,
                 facet_class=None, boost=1.0, weight=None):
        # Track what the index thinks this field is called.
        self.instance_name = None
        self.model_attr = model_attr
        self.use_template = use_template
        self.template_name = template_name
        self.document = document
        self.indexed = indexed
        self.stored = stored
        self.faceted = faceted
        self._default = default
        self.null = null
        self.index_fieldname = index_fieldname
        self.boost = weight or boost
        self.is_multivalued = False

        # We supply the facet_class for making it easy to create a faceted
        # field based off of this field.
        self.facet_class = facet_class

        if self.facet_class is None:
            self.facet_class = FacetCharField

        self.set_instance_name(None)

    def set_instance_name(self, instance_name):
        self.instance_name = instance_name

        if self.index_fieldname is None:
            self.index_fieldname = self.instance_name

    def has_default(self):
        """Returns a boolean of whether this field has a default value."""
        return self._default is not NOT_PROVIDED

    @property
    def default(self):
        """Returns the default value for the field."""
        if callable(self._default):
            return self._default()

        return self._default

    def prepare(self, obj):
        """
        Takes data from the provided object and prepares it for storage in the
        index.
        """
        # Give priority to a template.
        if self.use_template:
            return self.prepare_template(obj)
        elif self.model_attr is not None:
            # Check for `__` in the field for looking through the relation.
            attrs = self.model_attr.split('__')
            current_object = obj

            for attr in attrs:
                if not hasattr(current_object, attr):
                    raise SearchFieldError("The model '%s' does not have a model_attr '%s'." % (repr(obj), attr))

                current_object = getattr(current_object, attr, None)

                if current_object is None:
                    if self.has_default():
                        current_object = self._default
                        # Fall out of the loop, given any further attempts at
                        # accesses will fail misreably.
                        break
                    elif self.null:
                        current_object = None
                        # Fall out of the loop, given any further attempts at
                        # accesses will fail misreably.
                        break
                    else:
                        raise SearchFieldError("The model '%s' has an empty model_attr '%s' and doesn't allow a default or null value." % (repr(obj), attr))

            if callable(current_object):
                return current_object()

            return current_object

        if self.has_default():
            return self.default
        else:
            return None

    def prepare_template(self, obj):
        """
        Flattens an object for indexing.

        This loads a template
        (``search/indexes/{app_label}/{model_name}_{field_name}.txt``) and
        returns the result of rendering that template. ``object`` will be in
        its context.
        """
        if self.instance_name is None and self.template_name is None:
            raise SearchFieldError("This field requires either its instance_name variable to be populated or an explicit template_name in order to load the correct template.")

        if self.template_name is not None:
            template_names = self.template_name

            if not isinstance(template_names, (list, tuple)):
                template_names = [template_names]
        else:
            app_label, model_name = get_model_ct_tuple(obj)
            template_names = ['search/indexes/%s/%s_%s.txt' % (app_label, model_name, self.instance_name)]

        t = loader.select_template(template_names)
        return t.render(Context({'object': obj}))

    def convert(self, value):
        """
        Handles conversion between the data found and the type of the field.

        Extending classes should override this method and provide correct
        data coercion.
        """
        return value

class CharField(SearchField):
    field_type = 'string'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetCharField

        super(CharField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(CharField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return six.text_type(value)

class LocationField(SearchField):
    field_type = 'location'

    def prepare(self, obj):
        from haystack.utils.geo import ensure_point

        value = super(LocationField, self).prepare(obj)

        if value is None:
            return None

        pnt = ensure_point(value)
        pnt_lng, pnt_lat = pnt.get_coords()
        return "%s,%s" % (pnt_lat, pnt_lng)

    def convert(self, value):
        from haystack.utils.geo import ensure_point, Point

        if value is None:
            return None

        if hasattr(value, 'geom_type'):
            value = ensure_point(value)
            return value

        if isinstance(value, six.string_types):
            lat, lng = value.split(',')
        elif isinstance(value, (list, tuple)):
            # GeoJSON-alike
            lat, lng = value[1], value[0]
        elif isinstance(value, dict):
            lat = value.get('lat', 0)
            lng = value.get('lon', 0)

        value = Point(float(lng), float(lat))
        return value

class NgramField(CharField):
    field_type = 'ngram'

    def __init__(self, **kwargs):
        if kwargs.get('faceted') is True:
            raise SearchFieldError("%s can not be faceted." % self.__class__.__name__)

        super(NgramField, self).__init__(**kwargs)

class EdgeNgramField(NgramField):
    field_type = 'edge_ngram'

class IntegerField(SearchField):
    field_type = 'integer'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetIntegerField

        super(IntegerField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(IntegerField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return int(value)

class FloatField(SearchField):
    field_type = 'float'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetFloatField

        super(FloatField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(FloatField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return float(value)

class DecimalField(SearchField):
    field_type = 'string'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetDecimalField

        super(DecimalField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(DecimalField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return six.text_type(value)

class BooleanField(SearchField):
    field_type = 'boolean'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetBooleanField

        super(BooleanField, self).__init__(**kwargs)

    def prepare(self, obj):
        return self.convert(super(BooleanField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return bool(value)

class DateField(SearchField):
    field_type = 'date'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetDateField

        super(DateField, self).__init__(**kwargs)

    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, six.string_types):
            match = DATETIME_REGEX.search(value)

            if match:
                data = match.groupdict()
                return datetime_safe.date(int(data['year']), int(data['month']), int(data['day']))
            else:
                raise SearchFieldError("Date provided to '%s' field doesn't appear to be a valid date string: '%s'" % (self.instance_name, value))

        return value

class DateTimeField(SearchField):
    field_type = 'datetime'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetDateTimeField

        super(DateTimeField, self).__init__(**kwargs)

    def convert(self, value):
        if value is None:
            return None

        if isinstance(value, six.string_types):
            match = DATETIME_REGEX.search(value)

            if match:
                data = match.groupdict()
                return datetime_safe.datetime(int(data['year']), int(data['month']), int(data['day']), int(data['hour']), int(data['minute']), int(data['second']))
            else:
                raise SearchFieldError("Datetime provided to '%s' field doesn't appear to be a valid datetime string: '%s'" % (self.instance_name, value))

        return value

class MultiValueField(SearchField):
    field_type = 'string'

    def __init__(self, **kwargs):
        if kwargs.get('facet_class') is None:
            kwargs['facet_class'] = FacetMultiValueField

        if kwargs.get('use_template') is True:
            raise SearchFieldError("'%s' fields can not use templates to prepare their data." % self.__class__.__name__)

        super(MultiValueField, self).__init__(**kwargs)
        self.is_multivalued = True

    def prepare(self, obj):
        return self.convert(super(MultiValueField, self).prepare(obj))

    def convert(self, value):
        if value is None:
            return None

        return list(value)

class FacetField(SearchField):
    """
    ``FacetField`` is slightly different than the other fields because it can
    work in conjunction with other fields as its data source.

    Accepts an optional ``facet_for`` kwarg, which should be the field name
    (not ``index_fieldname``) of the field it should pull data from.
    """
    instance_name = None

    def __init__(self, **kwargs):
        handled_kwargs = self.handle_facet_parameters(kwargs)
        super(FacetField, self).__init__(**handled_kwargs)

    def handle_facet_parameters(self, kwargs):
        if kwargs.get('faceted', False):
            raise SearchFieldError("FacetField (%s) does not accept the 'faceted' argument." % self.instance_name)

        if not kwargs.get('null', True):
            raise SearchFieldError("FacetField (%s) does not accept False for the 'null' argument." % self.instance_name)

        if not kwargs.get('indexed', True):
            raise SearchFieldError("FacetField (%s) does not accept False for the 'indexed' argument." % self.instance_name)

        if kwargs.get('facet_class'):
            raise SearchFieldError("FacetField (%s) does not accept the 'facet_class' argument." % self.instance_name)

        self.facet_for = None
        self.facet_class = None

        # Make sure the field is nullable.
        kwargs['null'] = True

        if 'facet_for' in kwargs:
            self.facet_for = kwargs['facet_for']
            del(kwargs['facet_for'])

        return kwargs

    def get_facet_for_name(self):
        return self.facet_for or self.instance_name

class FacetCharField(FacetField, CharField):
    pass

class FacetIntegerField(FacetField, IntegerField):
    pass

class FacetFloatField(FacetField, FloatField):
    pass

class FacetDecimalField(FacetField, DecimalField):
    pass

class FacetBooleanField(FacetField, BooleanField):
    pass

class FacetDateField(FacetField, DateField):
    pass

class FacetDateTimeField(FacetField, DateTimeField):
    pass

class FacetMultiValueField(FacetField, MultiValueField):
    pass
<|endoftext|>