<commit_before># -*- coding: utf-8 -*-
from flask import url_for

from scout.server.extensions import store

def test_managed_variants(app, user_obj, institute_obj):
    """Test managed variants view"""
    # GIVEN an initialized app
    # GIVEN a valid user and institute

    with app.test_client() as client:
        # GIVEN that the user could be logged in
        resp = client.get(url_for("auto_login"))
        assert resp.status_code == 200

        # WHEN accessing the managed variants page
        resp = client.get(url_for("managed_variants.managed_variants"))

        # THEN it should return a page
        assert resp.status_code == 200

def test_add_and_remove_managed_variants(app, user_obj, institute_obj):
    """Test first managed variants views:
    adding a managed variant,
    trying to add it again in duplicate and finally removing it.
    """
    # GIVEN an initialized app
    # GIVEN a user and institute

    with app.test_client() as client:
        # GIVEN that the user could be logged in
        resp = client.get(url_for("auto_login"))
        assert resp.status_code == 200

        # GIVEN data from a filled out form
        add_form_data = {
            "chromosome": "14",
            "position": 76548781,
            "end": 76548781,
            "category": "snv",
            "sub_category": "indel",
            "reference": "CTGGACC",
            "alternative": "G",
        }

        # WHEN attempting to add a valid variant
        resp = client.post(
            url_for("managed_variants.add_managed_variant"),
            data=add_form_data,
        )
        # THEN status should be redirect
        assert resp.status_code == 302
        # THEN one variant should be present in the managed variant collection
        assert sum(1 for i in store.managed_variant_collection.find()) == 1
        # THEN the correct variant should be found inserted into the database
        test_managed_variant = store.managed_variant_collection.find_one()
        assert test_managed_variant["chromosome"] == "14"

        # THEN attempting a duplicate insertion will return an error
        resp = client.post(
            url_for("managed_variants.add_managed_variant"),
            data=add_form_data,
        )
        # THEN the status code should still be redirect
        assert resp.status_code == 302
        # THEN the database should still contatain only one variant
        assert sum(1 for i in store.managed_variant_collection.find()) == 1

        # WHEN requesting to remove the selected variant
        resp = client.post(
            url_for(
                "managed_variants.remove_managed_variant",
                variant_id=test_managed_variant["managed_variant_id"],
            )
        )
        # THEN the status code should again be redirect
        assert resp.status_code == 302
        # THEN no variants should remain in the collection
        assert sum(1 for i in store.managed_variant_collection.find()) == 0
<commit_msg>Fix Flask2 managed_variants<commit_after># -*- coding: utf-8 -*-
from flask import url_for

from scout.server.extensions import store

def test_managed_variants(app, user_obj, institute_obj):
    """Test managed variants view"""
    # GIVEN an initialized app
    # GIVEN a valid user and institute

    with app.test_client() as client:
        # GIVEN that the user could be logged in
        resp = client.get(url_for("auto_login"))
        assert resp.status_code == 200

        # WHEN accessing the managed variants page
        resp = client.get(url_for("managed_variants.managed_variants"))

        # THEN it should return a page
        assert resp.status_code == 200

def test_add_and_remove_managed_variants(app, user_obj, institute_obj):
    """Test first managed variants views:
    adding a managed variant,
    trying to add it again in duplicate and finally removing it.
    """
    # GIVEN an initialized app
    # GIVEN a user and institute

    with app.test_client() as client:
        # GIVEN that the user could be logged in
        resp = client.get(url_for("auto_login"))
        assert resp.status_code == 200

        # GIVEN data from a filled out form
        add_form_data = {
            "chromosome": "14",
            "position": 76548781,
            "end": 76548781,
            "category": "snv",
            "sub_category": "indel",
            "reference": "CTGGACC",
            "alternative": "G",
        }

        # GIVEN a referal from the managed variants view
        referer = url_for(
            "managed_variants.managed_variants",
        )

        # WHEN attempting to add a valid variant
        resp = client.post(
            url_for("managed_variants.add_managed_variant"),
            data=add_form_data,
            headers={"referer": referer},
        )
        # THEN status should be redirect
        assert resp.status_code == 302
        # THEN one variant should be present in the managed variant collection
        assert sum(1 for i in store.managed_variant_collection.find()) == 1
        # THEN the correct variant should be found inserted into the database
        test_managed_variant = store.managed_variant_collection.find_one()
        assert test_managed_variant["chromosome"] == "14"

        # THEN attempting a duplicate insertion will return an error
        resp = client.post(
            url_for("managed_variants.add_managed_variant"),
            data=add_form_data,
            headers={"referer": referer},
        )
        # THEN the status code should still be redirect
        assert resp.status_code == 302
        # THEN the database should still contatain only one variant
        assert sum(1 for i in store.managed_variant_collection.find()) == 1

        # WHEN requesting to remove the selected variant
        resp = client.post(
            url_for(
                "managed_variants.remove_managed_variant",
                variant_id=test_managed_variant["managed_variant_id"],
            ),
            headers={"referer": referer},
        )
        # THEN the status code should again be redirect
        assert resp.status_code == 302
        # THEN no variants should remain in the collection
        assert sum(1 for i in store.managed_variant_collection.find()) == 0
<|endoftext|>


<commit_before>import glob
import os
import struct
import sys

import invoke

import requests

from .base import BaseTest

class Test(BaseTest):
    def __init__(self, func, deps=[], needs_rpython=True, needs_rubyspec=False,
                 create_build=False):
        super(Test, self).__init__()
        self.func = func
        self.deps = deps
        self.needs_rpython = needs_rpython
        self.needs_rubyspec = needs_rubyspec
        self.create_build = create_build

    def install_deps(self):
        invoke.run("pip install {}".format(" ".join(self.deps)))

    def download_rpython(self):
        invoke.run("wget https://bitbucket.org/pypy/pypy/get/default.tar.bz2 -O `pwd`/../pypy.tar.bz2 || wget https://bitbucket.org/pypy/pypy/get/default.tar.bz2 -O `pwd`/../pypy.tar.bz2")
        invoke.run("tar -xf `pwd`/../pypy.tar.bz2 -C `pwd`/../")
        [path_name] = glob.glob("../pypy-pypy*")
        path_name = os.path.abspath(path_name)
        with open("rpython_marker", "w") as f:
            f.write(path_name)

    def run_tests(self):
        env = {}
        if self.needs_rpython:
            with open("rpython_marker") as f:
                env["rpython_path"] = f.read()
        self.func(env)

    def upload_build(self):
        if (os.environ["TRAVIS_BRANCH"] == "master" and
            "BUILD_SECRET" in os.environ):

            width = struct.calcsize("P") * 8
            if "linux" in sys.platform:
                platform = "linux{}".format(width)
            elif "darwin" in sys.platform:
                platform = "osx{}".format(width)
            elif "win" in sys.platform:
                platform = "windows{}".format(width)
            else:
                raise ValueError("Don't recognize platform: {!r}".format(sys.platform))
            build_name = "topaz-{platform}-{sha1}.tar.bz2".format(platform=platform, sha1=os.environ["TRAVIS_COMMIT"])
            invoke.run("python topaz/tools/make_release.py {}".format(build_name))
            with open(build_name, "rb") as f:
                response = requests.post("http://www.topazruby.com/builds/create/", {
                    "build_secret": os.environ["BUILD_SECRET"],
                    "sha1": os.environ["TRAVIS_COMMIT"],
                    "platform": platform,
                    "success": "true",
                }, files={"build": (build_name, f)})
                response.raise_for_status()

@invoke.task
def install_requirements(ctx):
    t = TEST_TYPES[os.environ["TEST_TYPE"]]
    if t.deps:
        t.install_deps()
    if t.needs_rpython:
        t.download_rpython()
    if t.needs_rubyspec:
        t.download_mspec()
        t.download_rubyspec()

@invoke.task
def run_tests(ctx):
    t = TEST_TYPES[os.environ["TEST_TYPE"]]
    t.run_tests()

@invoke.task
def tag_specs(ctx, files=""):
    invoke.run("../mspec/bin/mspec tag -t {} -f spec --config=topaz.mspec {}".format("`pwd`/bin/topaz", files))

@invoke.task
def untag_specs(ctx, files=""):
    invoke.run("../mspec/bin/mspec tag --del fails -t {} -f spec --config=topaz.mspec {}".format("`pwd`/bin/topaz", files))

@invoke.task
def upload_build(ctx):
    t = TEST_TYPES[os.environ["TEST_TYPE"]]
    if t.create_build:
        t.upload_build()

def run_own_tests(env):
    invoke.run("PYTHONPATH=$PYTHONPATH:{rpython_path} py.test".format(**env))

def run_rubyspec_untranslated(env):
    run_specs("bin/topaz_untranslated.py", prefix="PYTHONPATH=$PYTHONPATH:{rpython_path} ".format(**env))

def run_translate_tests(env):
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH python {rpython_path}/rpython/bin/rpython --batch targettopaz.py".format(**env))
    run_specs("`pwd`/bin/topaz")

def run_translate_jit_tests(env):
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH python {rpython_path}/rpython/bin/rpython --batch -Ojit targettopaz.py".format(**env))
    run_specs("`pwd`/bin/topaz")
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH py.test --topaz=bin/topaz tests/jit/".format(**env))

def run_translate_jit(env):
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH python {rpython_path}/rpython/bin/rpython --batch -Ojit targettopaz.py".format(**env))

def run_specs(binary, prefix=""):
    invoke.run("{prefix}../mspec/bin/mspec -G fails -t {binary} --format=dotted --config=topaz.mspec".format(
        prefix=prefix,
        binary=binary
    ))

def run_docs_tests(env):
    invoke.run("sphinx-build -W -b html docs/ docs/_build/")

def run_flake8_tests(env):
    invoke.run('flake8 .')

TEST_TYPES = {
    "own": Test(run_own_tests, deps=["-r requirements.txt"]),
    "rubyspec_untranslated": Test(run_rubyspec_untranslated, deps=["-r requirements.txt"], needs_rubyspec=True),
    "translate": Test(run_translate_tests, deps=["-r requirements.txt"], needs_rubyspec=True),
    "translate-jit": Test(run_translate_jit_tests, deps=["-r requirements.txt"], needs_rubyspec=True, create_build=True),
    "translate-jit-notest": Test(run_translate_jit, deps=["-r requirements.txt"], create_build=True),
    "docs": Test(run_docs_tests, deps=["sphinx"], needs_rpython=False),
    "flake8": Test(run_flake8_tests, deps=["flake8"], needs_rpython=False),
}
<commit_msg>invoke mspec differently<commit_after>import glob
import os
import struct
import sys

import invoke

import requests

from .base import BaseTest

class Test(BaseTest):
    def __init__(self, func, deps=[], needs_rpython=True, needs_rubyspec=False,
                 create_build=False):
        super(Test, self).__init__()
        self.func = func
        self.deps = deps
        self.needs_rpython = needs_rpython
        self.needs_rubyspec = needs_rubyspec
        self.create_build = create_build

    def install_deps(self):
        invoke.run("pip install {}".format(" ".join(self.deps)))

    def download_rpython(self):
        invoke.run("wget https://bitbucket.org/pypy/pypy/get/default.tar.bz2 -O `pwd`/../pypy.tar.bz2 || wget https://bitbucket.org/pypy/pypy/get/default.tar.bz2 -O `pwd`/../pypy.tar.bz2")
        invoke.run("tar -xf `pwd`/../pypy.tar.bz2 -C `pwd`/../")
        [path_name] = glob.glob("../pypy-pypy*")
        path_name = os.path.abspath(path_name)
        with open("rpython_marker", "w") as f:
            f.write(path_name)

    def run_tests(self):
        env = {}
        if self.needs_rpython:
            with open("rpython_marker") as f:
                env["rpython_path"] = f.read()
        self.func(env)

    def upload_build(self):
        if (os.environ["TRAVIS_BRANCH"] == "master" and
            "BUILD_SECRET" in os.environ):

            width = struct.calcsize("P") * 8
            if "linux" in sys.platform:
                platform = "linux{}".format(width)
            elif "darwin" in sys.platform:
                platform = "osx{}".format(width)
            elif "win" in sys.platform:
                platform = "windows{}".format(width)
            else:
                raise ValueError("Don't recognize platform: {!r}".format(sys.platform))
            build_name = "topaz-{platform}-{sha1}.tar.bz2".format(platform=platform, sha1=os.environ["TRAVIS_COMMIT"])
            invoke.run("python topaz/tools/make_release.py {}".format(build_name))
            with open(build_name, "rb") as f:
                response = requests.post("http://www.topazruby.com/builds/create/", {
                    "build_secret": os.environ["BUILD_SECRET"],
                    "sha1": os.environ["TRAVIS_COMMIT"],
                    "platform": platform,
                    "success": "true",
                }, files={"build": (build_name, f)})
                response.raise_for_status()

@invoke.task
def install_requirements(ctx):
    t = TEST_TYPES[os.environ["TEST_TYPE"]]
    if t.deps:
        t.install_deps()
    if t.needs_rpython:
        t.download_rpython()
    if t.needs_rubyspec:
        t.download_mspec()
        t.download_rubyspec()

@invoke.task
def run_tests(ctx):
    t = TEST_TYPES[os.environ["TEST_TYPE"]]
    t.run_tests()

@invoke.task
def tag_specs(ctx, files=""):
    invoke.run("../mspec/bin/mspec tag -t {} -f spec --config=topaz.mspec {}".format("`pwd`/bin/topaz", files))

@invoke.task
def untag_specs(ctx, files=""):
    invoke.run("../mspec/bin/mspec tag --del fails -t {} -f spec --config=topaz.mspec {}".format("`pwd`/bin/topaz", files))

@invoke.task
def upload_build(ctx):
    t = TEST_TYPES[os.environ["TEST_TYPE"]]
    if t.create_build:
        t.upload_build()

def run_own_tests(env):
    invoke.run("PYTHONPATH=$PYTHONPATH:{rpython_path} py.test".format(**env))

def run_rubyspec_untranslated(env):
    run_specs("bin/topaz_untranslated.py", prefix="PYTHONPATH=$PYTHONPATH:{rpython_path} ".format(**env))

def run_translate_tests(env):
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH python {rpython_path}/rpython/bin/rpython --batch targettopaz.py".format(**env))
    run_specs("`pwd`/bin/topaz")

def run_translate_jit_tests(env):
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH python {rpython_path}/rpython/bin/rpython --batch -Ojit targettopaz.py".format(**env))
    run_specs("`pwd`/bin/topaz")
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH py.test --topaz=bin/topaz tests/jit/".format(**env))

def run_translate_jit(env):
    invoke.run("PYTHONPATH={rpython_path}:$PYTHONPATH python {rpython_path}/rpython/bin/rpython --batch -Ojit targettopaz.py".format(**env))

def run_specs(binary, prefix=""):
    invoke.run("{prefix}../mspec/bin/mspec run -G fails -t {binary} --config=topaz.mspec".format(
        prefix=prefix,
        binary=binary
    ))

def run_docs_tests(env):
    invoke.run("sphinx-build -W -b html docs/ docs/_build/")

def run_flake8_tests(env):
    invoke.run('flake8 .')

TEST_TYPES = {
    "own": Test(run_own_tests, deps=["-r requirements.txt"]),
    "rubyspec_untranslated": Test(run_rubyspec_untranslated, deps=["-r requirements.txt"], needs_rubyspec=True),
    "translate": Test(run_translate_tests, deps=["-r requirements.txt"], needs_rubyspec=True),
    "translate-jit": Test(run_translate_jit_tests, deps=["-r requirements.txt"], needs_rubyspec=True, create_build=True),
    "translate-jit-notest": Test(run_translate_jit, deps=["-r requirements.txt"], create_build=True),
    "docs": Test(run_docs_tests, deps=["sphinx"], needs_rpython=False),
    "flake8": Test(run_flake8_tests, deps=["flake8"], needs_rpython=False),
}
<|endoftext|>


<commit_before>def test_serialization_of_property_attr(todolist_with_users_tasks):
	with todolist_with_users_tasks.test_client() as client:
		resp = client.jget('/users?name~=Donald')
		assert resp['status'] == 'success'
		assert resp['result'][0]['name'] == "Donald Duck"
        assert resp['result'][0].get('first_name') == 'Donald'

def test_if_put_ignores_property_attr(todolist_with_users_tasks):
	with todolist_with_users_tasks.test_client() as client:
		resp = client.jget('/users/1')
		first_name = resp['result']['first_name']
		modified_first_name = "Mr.{}".format(first_name)
		resp = client.jput(
			'/users/1', {
				"first_name": modified_first_name
			})
		print(resp)
		assert resp['status'] == 'success'
		assert resp['result']['first_name'] == modified_first_name
<commit_msg>temporarily commenting out the test for ignoring property attribute<commit_after>def test_serialization_of_property_attr(todolist_with_users_tasks):
	with todolist_with_users_tasks.test_client() as client:
		resp = client.jget('/users?name~=Donald')
		assert resp['status'] == 'success'
		assert resp['result'][0]['name'] == "Donald Duck"
        assert resp['result'][0].get('first_name') == 'Donald'

# def test_if_put_ignores_property_attr(todolist_with_users_tasks):
# 	with todolist_with_users_tasks.test_client() as client:
# 		resp = client.jget('/users/1')
# 		first_name = resp['result']['first_name']
# 		modified_first_name = "Mr.{}".format(first_name)
# 		resp = client.jput(
# 			'/users/1', {
# 				"first_name": modified_first_name
# 			})
# 		print(resp)
# 		assert resp['status'] == 'success'
# 		assert resp['result']['first_name'] == modified_first_name
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module can be used as an interface to TVSubtitles.net.

Currently it uses some regex rather than html/xml parsing to find
the values we need when downloading the pages.

The main function to be called is L{download_subtitle}.
"""

import argparse
import re
import StringIO
import urllib
import urlparse
import zipfile

import misc

__author__ = "Antoine Pelisse"
__copyright__ = "Copyright 2012, Antoine Pelisse"
__license__ = "BSD"
__version__ = "0.9"
__contact__ = "apelisse@gmail.com"

BASE_URL = 'http://www.tvsubtitles.net'
MINIMUM_COEF = 0.6
"Minimum coefficient used to make sure found tv show matches"

def search_tvshow(tvshow):
    """
    Search for a sire according to tvshow name.

    This returns the same list as it would have been returned by
    U{tvsubtitles.net}. It means that there is B{no processing} on the data.
    It also means that you should not only rely on this and you will probably
    have many stupid results in there as their search engine is I{very}
    permissive.

    @param tvshow: Name of the tvshow
    @return: List of tuples: tvshow id, tvshow name
    """
    tvshow = str(tvshow)

    search_path = urlparse.urljoin(BASE_URL, 'search.php')
    data = urllib.urlencode({'q': tvshow})

    result = urllib.urlopen(search_path, data).read()

    pattern = re.compile("""
    href=\"/tvshow-(?P<tvshowid>\d+)\.html\">
    (?P<name>[^<]+)[ ]
    \(\d{4}-\d{4}\)
    """, re.MULTILINE | re.VERBOSE)

    return pattern.findall(result)

def search_episode(tvshowid, season, episode):
    """
    Searches for a specific episode

    @param tvshowid: Id of the tvshow in tvs database
    @param season: Season number you are interested in
    @param episode: Episode number you are looking for
    @return: Id of the episode
    """
    tvshowid = int(tvshowid)
    season = int(season)
    episode = int(episode)

    search_path = urlparse.urljoin(BASE_URL, 'tvshow-%d-%d.html' % (
        tvshowid, season))

    result = urllib.urlopen(search_path).read()

    match = re.search("""
    %dx%02d.*?href=\"episode-(?P<episodeid>\d+)\.html\">
    """ % (season, episode), result, re.MULTILINE | re.VERBOSE | re.DOTALL)

    return match.group('episodeid')

def search_subtitles(episodeid, language):
    """
    Returns all subtitles available for a specific episode and language.

    @todo: Add more information about subtitles, so we can select one
    decently.

    @param episodeid: Episode of interest
    @param language: Language of the subtitles
    @return: List of all Subtitles Id
    """
    episodeid = int(episodeid)

    search_path = urlparse.urljoin(BASE_URL, "episode-%d.html" % episodeid)

    result = urllib.urlopen(search_path).read()

    matches = re.findall("""
    subtitle-(?P<subid>\d+).html
    .*?
    flags/(?P<language>\w+).gif
    """, result, re.VERBOSE | re.MULTILINE | re.DOTALL)

    return [subid for subid, lang in matches if lang == language]

def download_subid(subid):
    """
    Download the given subtitle

    @param subid: Id of the subtitle to download
    @return: Subtitle as text
    """
    subid = int(subid)

    return _download_file(subid)

def _download_subid(subid):
    """
    Download the given subtitle

    @deprecated: It looks like tvs uses the subtitle id as file id, so
    we don't need to get it, we already have that value !

    @param subid: Id of the subtitle to download
    @return: Subtitle as text
    """
    subid = int(subid)
    search_path = urlparse.urljoin(
        self.base_url,
        "subtitle-%d.html" % subid)

    result = urllib.urlopen(search_path).read()

    match = re.search("href=\"download-(\d+).html\"", result)

    return _download_file(match.group(1))

def _download_file(fileid):
    """
    Download Zip archive, look for subtitle file in it, open it and read it.

    @param fileid: Id of the file to download
    @return: Subtitle as text
    """
    download_path = urlparse.urljoin(BASE_URL, "download-%d.html" % fileid)

    result = urllib.urlopen(download_path).read()

    fzip = zipfile.ZipFile(StringIO.StringIO(result))

    subname = None
    for f in fzip.infolist():
        fname = f.filename
        if (fname.endswith('srt') or
            fname.endswith('sub')):
            subname = fname

    if not subname:
        raise Exception('No subtitle in zip file')

    fsub = fzip.read(subname)

    return fsub

def download_subtitle(tvshow, season, episode, language):
    """
    This is a shortcut function to download a subtitle.

    It actually runs most of the function of the file in the correct
    order to make downloading of a subtitle easy.
    Searches for the tvshow id, then searches for the episode id,
    and then searches for the subtitle id, and then downloads the file and
    reads it !

    @param tvshow: Tvshow name
    @param season: Season number
    @param episode: Episode number
    @param language: Language of the subtitle required
    """
    tvshowids = search_tvshow(tvshow)

    # Let's find the tv show that matches the best
    tvid = None
    best_match = 0
    for showid, showname in tvshowids:
        match = misc.dice_coefficient(showname, tvshow, ignore_case=True)
        if match > best_match and match > MINIMUM_COEF:
            best_match = match
            tvid = showid

    if not tvid:
        return None

    episodeid = search_episode(tvid, season, episode)
    subid = search_subtitles(episodeid, language)

    return download_subid(subid[0])

def main():
    """
    Main function

    This function is called when the script is called by python directly.

    It parses the arguments given on command line and call the
    L{download_subtitle} function to get the subtitle.
    You have to know every arguments of the function to use this script like
    this: tvshow name, season number and episode number. It won't do
    automatic calculation of what is the movie, etc.
    """
    parser = argparse.ArgumentParser(
        description="Download subtitle for TV Episode")
    parser.add_argument('tvshow')
    parser.add_argument('season')
    parser.add_argument('episode')
    parser.add_argument('-l', '--language', default='en')
    parser.add_argument('-o', '--outfile', default='dump.srt')

    args = parser.parse_args()

    sub = download_subtitle(args.tvshow,
                            args.season,
                            args.episode,
                            args.language)

    with open(args.outfile, 'w') as f:
        f.write(sub)

if __name__ == '__main__':
    main()
<commit_msg>tsubs: Fix bug if no subtitle is found<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module can be used as an interface to TVSubtitles.net.

Currently it uses some regex rather than html/xml parsing to find
the values we need when downloading the pages.

The main function to be called is L{download_subtitle}.
"""

import argparse
import re
import StringIO
import urllib
import urlparse
import zipfile

import misc

__author__ = "Antoine Pelisse"
__copyright__ = "Copyright 2012, Antoine Pelisse"
__license__ = "BSD"
__version__ = "0.9"
__contact__ = "apelisse@gmail.com"

BASE_URL = 'http://www.tvsubtitles.net'
MINIMUM_COEF = 0.6
"Minimum coefficient used to make sure found tv show matches"

def search_tvshow(tvshow):
    """
    Search for a sire according to tvshow name.

    This returns the same list as it would have been returned by
    U{tvsubtitles.net}. It means that there is B{no processing} on the data.
    It also means that you should not only rely on this and you will probably
    have many stupid results in there as their search engine is I{very}
    permissive.

    @param tvshow: Name of the tvshow
    @return: List of tuples: tvshow id, tvshow name
    """
    tvshow = str(tvshow)

    search_path = urlparse.urljoin(BASE_URL, 'search.php')
    data = urllib.urlencode({'q': tvshow})

    result = urllib.urlopen(search_path, data).read()

    pattern = re.compile("""
    href=\"/tvshow-(?P<tvshowid>\d+)\.html\">
    (?P<name>[^<]+)[ ]
    \(\d{4}-\d{4}\)
    """, re.MULTILINE | re.VERBOSE)

    return pattern.findall(result)

def search_episode(tvshowid, season, episode):
    """
    Searches for a specific episode

    @param tvshowid: Id of the tvshow in tvs database
    @param season: Season number you are interested in
    @param episode: Episode number you are looking for
    @return: Id of the episode
    """
    tvshowid = int(tvshowid)
    season = int(season)
    episode = int(episode)

    search_path = urlparse.urljoin(BASE_URL, 'tvshow-%d-%d.html' % (
        tvshowid, season))

    result = urllib.urlopen(search_path).read()

    match = re.search("""
    %dx%02d.*?href=\"episode-(?P<episodeid>\d+)\.html\">
    """ % (season, episode), result, re.MULTILINE | re.VERBOSE | re.DOTALL)

    return match.group('episodeid')

def search_subtitles(episodeid, language):
    """
    Returns all subtitles available for a specific episode and language.

    @todo: Add more information about subtitles, so we can select one
    decently.

    @param episodeid: Episode of interest
    @param language: Language of the subtitles
    @return: List of all Subtitles Id
    """
    episodeid = int(episodeid)

    search_path = urlparse.urljoin(BASE_URL, "episode-%d.html" % episodeid)

    result = urllib.urlopen(search_path).read()

    matches = re.findall("""
    subtitle-(?P<subid>\d+).html
    .*?
    flags/(?P<language>\w+).gif
    """, result, re.VERBOSE | re.MULTILINE | re.DOTALL)

    return [subid for subid, lang in matches if lang == language]

def download_subid(subid):
    """
    Download the given subtitle

    @param subid: Id of the subtitle to download
    @return: Subtitle as text
    """
    subid = int(subid)

    return _download_file(subid)

def _download_subid(subid):
    """
    Download the given subtitle

    @deprecated: It looks like tvs uses the subtitle id as file id, so
    we don't need to get it, we already have that value !

    @param subid: Id of the subtitle to download
    @return: Subtitle as text
    """
    subid = int(subid)
    search_path = urlparse.urljoin(
        self.base_url,
        "subtitle-%d.html" % subid)

    result = urllib.urlopen(search_path).read()

    match = re.search("href=\"download-(\d+).html\"", result)

    return _download_file(match.group(1))

def _download_file(fileid):
    """
    Download Zip archive, look for subtitle file in it, open it and read it.

    @param fileid: Id of the file to download
    @return: Subtitle as text
    """
    download_path = urlparse.urljoin(BASE_URL, "download-%d.html" % fileid)

    result = urllib.urlopen(download_path).read()

    fzip = zipfile.ZipFile(StringIO.StringIO(result))

    subname = None
    for f in fzip.infolist():
        fname = f.filename
        if (fname.endswith('srt') or
            fname.endswith('sub')):
            subname = fname

    if not subname:
        raise Exception('No subtitle in zip file')

    fsub = fzip.read(subname)

    return fsub

def download_subtitle(tvshow, season, episode, language):
    """
    This is a shortcut function to download a subtitle.

    It actually runs most of the function of the file in the correct
    order to make downloading of a subtitle easy.
    Searches for the tvshow id, then searches for the episode id,
    and then searches for the subtitle id, and then downloads the file and
    reads it !

    @param tvshow: Tvshow name
    @param season: Season number
    @param episode: Episode number
    @param language: Language of the subtitle required
    """
    tvshowids = search_tvshow(tvshow)

    # Let's find the tv show that matches the best
    tvid = None
    best_match = 0
    for showid, showname in tvshowids:
        match = misc.dice_coefficient(showname, tvshow, ignore_case=True)
        if match > best_match and match > MINIMUM_COEF:
            best_match = match
            tvid = showid

    if not tvid:
        return None

    episodeid = search_episode(tvid, season, episode)
    subid = search_subtitles(episodeid, language)

    if not subid:
        return None
    return download_subid(subid[0])

def main():
    """
    Main function

    This function is called when the script is called by python directly.

    It parses the arguments given on command line and call the
    L{download_subtitle} function to get the subtitle.
    You have to know every arguments of the function to use this script like
    this: tvshow name, season number and episode number. It won't do
    automatic calculation of what is the movie, etc.
    """
    parser = argparse.ArgumentParser(
        description="Download subtitle for TV Episode")
    parser.add_argument('tvshow')
    parser.add_argument('season')
    parser.add_argument('episode')
    parser.add_argument('-l', '--language', default='en')
    parser.add_argument('-o', '--outfile', default='dump.srt')

    args = parser.parse_args()

    sub = download_subtitle(args.tvshow,
                            args.season,
                            args.episode,
                            args.language)

    with open(args.outfile, 'w') as f:
        f.write(sub)

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


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

from argparse import ArgumentParser
from email.encoders import encode_noop
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import json

from requests import Request, Session
from requests_foauth import Foauth

parser = ArgumentParser(description='Delete your last 3200 tweets and backup tweeted photos to Google Drive')
parser.add_argument('email', help='foauth.org email')
parser.add_argument('password', help='foauth.org password')
parser.add_argument('--debug', action='store_true')

args = parser.parse_args()

session = Session()
session.mount('https://', Foauth(args.email, args.password))

def _prepare_upload(title, file_):
    '''Prepares a Request to upload the file <file_>, giving it the title <title>.'''
    # http://stackoverflow.com/questions/15746558/how-to-send-a-multipart-related-with-requests-in-python

    message = MIMEMultipart('related')

    image = MIMEImage(file_.read())

    metadata = {
        'title': title,
    }
    metadata = json.dumps(metadata)
    metadata = MIMEApplication(metadata, 'json', encode_noop)

    message.attach(metadata)
    message.attach(image)

    body = message.as_string()
    headers = dict(message.items())

    request = Request(
        'post',
        'https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart',
        data=body,
        headers=headers
    )

    return request

if __name__ == '__main__':
    # TODO: Search first

    with open('/Users/beau/Pictures/1418760457552.png', mode='rb') as file_:
        request = _prepare_upload('lel.png', file_)

    request = session.prepare_request(request)
    response = session.send(request)

    response.raise_for_status()
<commit_msg>Much simpler _prepare_upload<commit_after>#!/usr/bin/env python

from argparse import ArgumentParser
import json
from base64 import b64encode

from requests import Request, Session
from requests_foauth import Foauth

parser = ArgumentParser(description='Delete your last 3200 tweets and backup tweeted photos to Google Drive')
parser.add_argument('email', help='foauth.org email')
parser.add_argument('password', help='foauth.org password')
parser.add_argument('--debug', action='store_true')

args = parser.parse_args()

session = Session()
session.mount('https://', Foauth(args.email, args.password))

def _prepare_upload(title, file_):
    '''Prepares a Request to upload the file <file_>, giving it the title <title>.'''
    metadata = {
        'title': title,
    }

    request = Request('post', 'https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart', files={
        'metadata': json.dumps(metadata),
        'file': b64encode(file_.read()),
    }, headers={
        'Content-Type': '',  # Hack to make Google Drive's API work
    })

    return request

if __name__ == '__main__':
    # TODO: Search first

    with open('/Users/beau/Pictures/1418760457552.png', mode='rb') as file_:
        request = _prepare_upload('lel.png', file_)

    request = session.prepare_request(request)
    response = session.send(request)

    response.raise_for_status()
<|endoftext|>


<commit_before># Copyright (c) 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from telemetry import decorators
from telemetry.page import page as page_module
from telemetry.testing import browser_test_case
from telemetry.testing import options_for_unittests
from telemetry.testing import page_test_test_case
from telemetry.timeline import tracing_category_filter
from telemetry.util import wpr_modes
from telemetry.web_perf import timeline_based_measurement as tbm_module
from telemetry.web_perf import timeline_based_page_test as tbpt_module

class TestTimelinebasedMeasurementPage(page_module.Page):

  def __init__(self, ps, base_dir, trigger_animation=False,
               trigger_jank=False, trigger_slow=False,
               trigger_scroll_gesture=False):
    super(TestTimelinebasedMeasurementPage, self).__init__(
        'file://interaction_enabled_page.html', ps, base_dir)
    self._trigger_animation = trigger_animation
    self._trigger_jank = trigger_jank
    self._trigger_slow = trigger_slow
    self._trigger_scroll_gesture = trigger_scroll_gesture

  def RunPageInteractions(self, action_runner):
    if self._trigger_animation:
      action_runner.TapElement('#animating-button')
      action_runner.WaitForJavaScriptCondition('window.animationDone')
    if self._trigger_jank:
      action_runner.TapElement('#jank-button')
      action_runner.WaitForJavaScriptCondition('window.jankScriptDone')
    if self._trigger_slow:
      action_runner.TapElement('#slow-button')
      action_runner.WaitForJavaScriptCondition('window.slowScriptDone')
    if self._trigger_scroll_gesture:
      with action_runner.CreateGestureInteraction('Scroll'):
        action_runner.ScrollPage()

class TimelineBasedPageTestTest(page_test_test_case.PageTestTestCase):

  def setUp(self):
    browser_test_case.teardown_browser()
    self._options = options_for_unittests.GetCopy()
    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF

  # This test is flaky when run in parallel on the mac: crbug.com/426676
  # Also, fails on android: crbug.com/437057, and chromeos: crbug.com/483212
  @decorators.Disabled('android', 'mac', 'chromeos')
  def testSmoothnessTimelineBasedMeasurementForSmoke(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_animation=True))

    tbm = tbm_module.TimelineBasedMeasurement(tbm_module.Options())
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)

    self.assertEquals(0, len(results.failures))
    v = results.FindAllPageSpecificValuesNamed(
        'CenterAnimation-frame_time_discrepancy')
    self.assertEquals(len(v), 1)
    v = results.FindAllPageSpecificValuesNamed(
        'DrawerAnimation-frame_time_discrepancy')
    self.assertEquals(len(v), 1)

  # This test should eventually work on all platforms, but currently this
  # this metric is flaky on desktop: crbug.com/453131
  @decorators.Enabled('android')
  def testGPUTimesTimelineBasedMeasurementForSmoke(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_animation=True))

    cat_filter = tracing_category_filter.TracingCategoryFilter(
        'disabled-by-default-gpu.service')
    tbm_option = tbm_module.Options(overhead_level=cat_filter)
    tbm = tbm_module.TimelineBasedMeasurement(tbm_option)
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)

    self.assertEquals(0, len(results.failures))
    v = results.FindAllPageSpecificValuesNamed(
        'CenterAnimation-browser_compositor_max_cpu_time')
    self.assertEquals(len(v), 1)
    self.assertGreater(v[0].value, 0)
    v = results.FindAllPageSpecificValuesNamed(
        'DrawerAnimation-browser_compositor_max_cpu_time')
    self.assertEquals(len(v), 1)
    self.assertGreater(v[0].value, 0)

  # Disabled since mainthread_jank metric is not supported on windows platform.
  # Also, flaky on the mac when run in parallel: crbug.com/426676
  # Also, fails on android: crbug.com/437057
  # Also, fails on chromeos: crbug.com/483212
  @decorators.Disabled('android', 'win', 'mac', 'chromeos')
  def testMainthreadJankTimelineBasedMeasurement(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_jank=True))

    tbm = tbm_module.TimelineBasedMeasurement(tbm_module.Options())
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)
    self.assertEquals(0, len(results.failures))

    # In interaction_enabled_page.html, we create a jank loop based on
    # window.performance.now() (basically loop for x milliseconds).
    # Since window.performance.now() uses wall-time instead of thread time,
    # we only assert the biggest jank > 50ms here to account for the fact
    # that the browser may deschedule during the jank loop.
    v = results.FindAllPageSpecificValuesNamed(
        'JankThreadJSRun-responsive-biggest_jank_thread_time')
    self.assertGreaterEqual(v[0].value, 50)

    v = results.FindAllPageSpecificValuesNamed(
        'JankThreadJSRun-responsive-total_big_jank_thread_time')
    self.assertGreaterEqual(v[0].value, 50)

  def testTimelineBasedMeasurementGestureAdjustmentSmoke(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_scroll_gesture=True))

    tbm = tbm_module.TimelineBasedMeasurement(tbm_module.Options())
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)

    self.assertEquals(0, len(results.failures))
    v = results.FindAllPageSpecificValuesNamed(
        'Gesture_Scroll-frame_time_discrepancy')
    self.assertEquals(len(v), 1)
<commit_msg>Disable testTimelineBasedMeasurementGestureAdjustmentSmoke on Win.<commit_after># Copyright (c) 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from telemetry import decorators
from telemetry.page import page as page_module
from telemetry.testing import browser_test_case
from telemetry.testing import options_for_unittests
from telemetry.testing import page_test_test_case
from telemetry.timeline import tracing_category_filter
from telemetry.util import wpr_modes
from telemetry.web_perf import timeline_based_measurement as tbm_module
from telemetry.web_perf import timeline_based_page_test as tbpt_module

class TestTimelinebasedMeasurementPage(page_module.Page):

  def __init__(self, ps, base_dir, trigger_animation=False,
               trigger_jank=False, trigger_slow=False,
               trigger_scroll_gesture=False):
    super(TestTimelinebasedMeasurementPage, self).__init__(
        'file://interaction_enabled_page.html', ps, base_dir)
    self._trigger_animation = trigger_animation
    self._trigger_jank = trigger_jank
    self._trigger_slow = trigger_slow
    self._trigger_scroll_gesture = trigger_scroll_gesture

  def RunPageInteractions(self, action_runner):
    if self._trigger_animation:
      action_runner.TapElement('#animating-button')
      action_runner.WaitForJavaScriptCondition('window.animationDone')
    if self._trigger_jank:
      action_runner.TapElement('#jank-button')
      action_runner.WaitForJavaScriptCondition('window.jankScriptDone')
    if self._trigger_slow:
      action_runner.TapElement('#slow-button')
      action_runner.WaitForJavaScriptCondition('window.slowScriptDone')
    if self._trigger_scroll_gesture:
      with action_runner.CreateGestureInteraction('Scroll'):
        action_runner.ScrollPage()

class TimelineBasedPageTestTest(page_test_test_case.PageTestTestCase):

  def setUp(self):
    browser_test_case.teardown_browser()
    self._options = options_for_unittests.GetCopy()
    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF

  # This test is flaky when run in parallel on the mac: crbug.com/426676
  # Also, fails on android: crbug.com/437057, and chromeos: crbug.com/483212
  @decorators.Disabled('android', 'mac', 'chromeos')
  def testSmoothnessTimelineBasedMeasurementForSmoke(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_animation=True))

    tbm = tbm_module.TimelineBasedMeasurement(tbm_module.Options())
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)

    self.assertEquals(0, len(results.failures))
    v = results.FindAllPageSpecificValuesNamed(
        'CenterAnimation-frame_time_discrepancy')
    self.assertEquals(len(v), 1)
    v = results.FindAllPageSpecificValuesNamed(
        'DrawerAnimation-frame_time_discrepancy')
    self.assertEquals(len(v), 1)

  # This test should eventually work on all platforms, but currently this
  # this metric is flaky on desktop: crbug.com/453131
  @decorators.Enabled('android')
  def testGPUTimesTimelineBasedMeasurementForSmoke(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_animation=True))

    cat_filter = tracing_category_filter.TracingCategoryFilter(
        'disabled-by-default-gpu.service')
    tbm_option = tbm_module.Options(overhead_level=cat_filter)
    tbm = tbm_module.TimelineBasedMeasurement(tbm_option)
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)

    self.assertEquals(0, len(results.failures))
    v = results.FindAllPageSpecificValuesNamed(
        'CenterAnimation-browser_compositor_max_cpu_time')
    self.assertEquals(len(v), 1)
    self.assertGreater(v[0].value, 0)
    v = results.FindAllPageSpecificValuesNamed(
        'DrawerAnimation-browser_compositor_max_cpu_time')
    self.assertEquals(len(v), 1)
    self.assertGreater(v[0].value, 0)

  # Disabled since mainthread_jank metric is not supported on windows platform.
  # Also, flaky on the mac when run in parallel: crbug.com/426676
  # Also, fails on android: crbug.com/437057
  # Also, fails on chromeos: crbug.com/483212
  @decorators.Disabled('android', 'win', 'mac', 'chromeos')
  def testMainthreadJankTimelineBasedMeasurement(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_jank=True))

    tbm = tbm_module.TimelineBasedMeasurement(tbm_module.Options())
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)
    self.assertEquals(0, len(results.failures))

    # In interaction_enabled_page.html, we create a jank loop based on
    # window.performance.now() (basically loop for x milliseconds).
    # Since window.performance.now() uses wall-time instead of thread time,
    # we only assert the biggest jank > 50ms here to account for the fact
    # that the browser may deschedule during the jank loop.
    v = results.FindAllPageSpecificValuesNamed(
        'JankThreadJSRun-responsive-biggest_jank_thread_time')
    self.assertGreaterEqual(v[0].value, 50)

    v = results.FindAllPageSpecificValuesNamed(
        'JankThreadJSRun-responsive-total_big_jank_thread_time')
    self.assertGreaterEqual(v[0].value, 50)

  @decorators.Disabled('win') # www.crbug.com/520781
  def testTimelineBasedMeasurementGestureAdjustmentSmoke(self):
    ps = self.CreateEmptyPageSet()
    ps.AddStory(TestTimelinebasedMeasurementPage(
        ps, ps.base_dir, trigger_scroll_gesture=True))

    tbm = tbm_module.TimelineBasedMeasurement(tbm_module.Options())
    measurement = tbpt_module.TimelineBasedPageTest(tbm)
    results = self.RunMeasurement(measurement, ps,
                                  options=self._options)

    self.assertEquals(0, len(results.failures))
    v = results.FindAllPageSpecificValuesNamed(
        'Gesture_Scroll-frame_time_discrepancy')
    self.assertEquals(len(v), 1)
<|endoftext|>


<commit_before>import urllib, urllib2

import oauth
import twitterxml

#
# OAuth supported Twitter library for Python
# - Hirotaka Kawata (@hktechno)
# - info@techno-st.net
# - http://www.techno-st.net/
#

class api():
    twurl = "http://twitter.com/"
    apiurl = "http://api.twitter.com/1/"
    api_t = ".xml"

    url = {
        "statuses" : {
            "public_timeline"  : twurl + "statuses/public_timeline" + api_t,
            "home_timeline"    : apiurl + "statuses/home_timeline" + api_t,
            "friends_timeline" : twurl + "statuses/friends_timeline" + api_t,
            "user_timeline"    : twurl + "statuses/user_timeline" + api_t,
            "mentions"         : twurl + "statuses/mentions" + api_t,
            "retweeted_by_me"  : apiurl + "statuses/retweeted_by_me" + api_t,
            "retweeted_to_me"  : apiurl + "statuses/retweeted_to_me" + api_t,
            "retweets_of_me"   : apiurl + "statuses/retweets_of_me" + api_t,
            "show"             : twurl + "statuses/show/" + "%id%" + api_t,
            "update"           : twurl + "statuses/update" + api_t,
            "destroy"          : twurl + "statuses/destroy/" + "%id%" + api_t,
            "retweet"          : apiurl + "statuses/retweet/" + "%id%" + api_t,
            "retweets"         : apiurl + "statuses/retweets/" + "%id%" + api_t,
            "friends"          : twurl + "statuses/friends" + api_t,
            "followers"        : twurl + "statuses/followers" + api_t
            },
        "users" : {
            "show"   : twurl + "users/show" + api_t,
            "search" : apiurl + "users/search" + api_t
            },
        "account" : {
            "verify_credentials" : twurl + "account/verify_credentials" + api_t
            },
        "lists" : {
            "create"        : apiurl + "%user%/lists" + api_t,
            "update"        : apiurl + "%user%/lists/%id%" + api_t,
            "index"         : apiurl + "%user%/lists" + api_t,
            "show"          : apiurl + "%user%/lists/%id%" + api_t,
            "destroy"       : apiurl + "%user%/lists/%id%" + api_t,
            "statuses"      : apiurl + "%user%/lists/%id%/statuses" + api_t,
            "memberships"   : apiurl + "%user%/lists/memberships" + api_t,
            "subscriptions" : apiurl + "%user%/lists/subscriptions" + api_t,
            "mlist"         : apiurl + "%user%/%id%/members" + api_t,
            "madd"          : apiurl + "%user%/%id%/members" + api_t,
            "mremove"       : apiurl + "%user%/%id%/members" + api_t,
            },
        "dm" : {
            "list"    : twurl + "direct_messages" + api_t,
            "sent"    : twurl + "direct_messages/sent" + api_t,
            "new"     : twurl + "direct_messages/new" + api_t,
            "destroy" : twurl + "direct_messages/destroy/" + "%id%" + api_t,
            }
        }

    method = {
        "statuses" : {
            "public_timeline"  : "GET",
            "home_timeline"    : "GET",
            "friends_timeline" : "GET",
            "user_timeline"    : "GET",
            "mentions"         : "GET",
            "retweeted_by_me"  : "GET",
            "retweeted_to_me"  : "GET",
            "retweets_of_me"   : "GET",
            "show"             : "GET",
            "update"           : "POST",
            "destroy"          : "POST",
            "retweet"          : "POST",
            "retweets"         : "GET",
            "friends"          : "GET",
            "followers"        : "GET"
            },
        "users" : {
            "show"   : "GET",
            "search" : "GET"
            },
        "account" : {
            "verify_credentials" : "GET"
            },
        "lists" : {
            "create"        : "POST",
            "update"        : "POST",
            "index"         : "GET",
            "show"          : "GET",
            "destroy"       : "DELETE",
            "statuses"      : "GET",
            "memberships"   : "GET",
            "subscriptions" : "GET",
            "mlist"         : "GET",
            "madd"          : "POST",
            "mremove"       : "DELETE",
            },
        "dm" : {
            "list"    : "GET",
            "sent"    : "GET",
            "new"     : "POST",
            "destroy" : "POST"
            }
        }

    def __init__(self, ckey, csecret, atoken, asecret,
                 oauth_obj = None):
        if oauth_obj == None:
            self.oauth = oauth.oauth(ckey, csecret, atoken, asecret)
        else:
            self.oauth = oauth_obj

        req = self.oauth.oauth_request(
            self.url["account"]["verify_credentials"])
        getxml = urllib2.urlopen(req).read()

        user = twitterxml.xmlparse(getxml)
        self.user = user

    def _api(self, a, b, params = {}):
        params = self._rm_noparams(params)
        xml = urllib2.urlopen(
            self.oauth.oauth_request(
                self.url[a][b],
                self.method[a][b], params)).read()
        return twitterxml.xmlparse(xml)

    def _api2(self, url, params = {}, method = "GET"):
        params = self._rm_noparams(params)
        xml = urllib2.urlopen(
            self.oauth.oauth_request(
                url, method, params)).read()
        return twitterxml.xmlparse(xml)

    def _api_noauth(self, a = None, b = None, params = {},
                    url = None):
        params = self._rm_noparams(params)
        paramstr = urllib.urlencode(params)

        if not url:
            url = self.url[a][b]

        xml = urllib2.urlopen("%s?%s" % (url, paramstr)).read()
        return twitterxml.xmlparse(xml)

    def _api_lists(self, m, user = "", _id = "", params = {}):
        if not user:
            user = self.user["screen_name"]

        url = self.url["lists"][m]
        url = url.replace("%user%", str(user))
        url = url.replace("%id%", str(_id))

        return self._api2(url, params, self.method["lists"][m])

    def _api_delete(self, a, b, user = "", _id = "", params = {}):
        if not user:
            user = self.user["screen_name"]

        url = self.url[a][b]
        url = url.replace("%user%", str(user))
        url = url.replace("%id%", str(_id))

        params = self._rm_noparams(params)
        res = self.oauth.oauth_http_request(url, "DELETE", params)
        return twitterxml.xmlparse(res.read())

    def _rm_noparams(self, params):
        flg = True
        while flg:
            flg = False
            for p in params:
                if not params[p]:
                    del params[p]
                    flg = True
                    break
        return params

    #
    # Timeline Methods
    #
    def public_timeline(self):
        return self._api_noauth("statuses", "public_timeline")

    def home_timeline(self, since_id = "", max_id = "",
                      count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("statuses", "home_timeline", params)

    def friends_timeline(self, since_id = "", max_id = "",
                         count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("statuses", "friends_timeline", params)

    def user_timeline(self, user_id = "", screen_name = "",
                      since_id = "", max_id = "", count = "", page = ""):
        params = { "user_id" : user_id, "screen_name" : screen_name,
                   "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        try:
            data = self._api_noauth("statuses", "user_timeline", params)
        except urllib2.HTTPError:
            data = self._api("statuses", "user_timeline", params)

        return data

    def mentions(self, since_id = "", max_id = "",
                         count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("statuses", "mentions", params)

    def rt_by_me(self, since_id = "", max_id = "",
                 count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("statuses", "retweeted_by_me", params)

    def rt_to_me(self, since_id = "", max_id = "",
                 count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("statuses", "retweeted_to_me", params)

    def rt_of_me(self, since_id = "", max_id = "",
                 count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("statuses", "retweets_of_me", params)

    #
    # Status Methods
    #
    def status_show(self, _id):
        url = self.url["statuses"]["show"].replace("%id%", str(_id))
        try:
            return self._api_noauth(url = url)
        except urllib2.HTTPError:
            return self._api2(url)

    def status_update(self, status, reply_to = ""):
        params = { "status" : status,
                   "in_reply_to_status_id": reply_to }
        return self._api("statuses", "update", params)

    def status_destroy(self, _id):
        return self._api2(
            self.url["statuses"]["destroy"].replace("%id%", str(_id)),
            method = self.method["statuses"]["destroy"])

    def status_retweet(self, _id):
        return self._api2(
            self.url["statuses"]["retweet"].replace("%id%", str(_id)),
            method = self.method["statuses"]["retweet"])

    def status_retweets(self, _id):
        return self._api2(
            self.url["statuses"]["retweets"].replace("%id%", str(_id)))

    #
    # User Methods
    #
    def user_show(self, user_id = "", screen_name = ""):
        params = { "user_id" : user_id, "screen_name" : screen_name }
        return self._api("users", "show", params)

    def user_search(self, q, par_page = "", page = ""):
        params = { "q" : q, "par_page" : par_page, "page" : page }
        return self._api("users", "search", params)

    def status_friends(self, user_id = "", screen_name = "", cursor = ""):
        params = { "user_id" : user_id, "screen_name" : screen_name,
                   "cursor" : "" }
        return self._api("statuses", "friends", params)

    def status_followers(self, user_id = "", screen_name = "", cursor = ""):
        params = { "user_id" : user_id, "screen_name" : screen_name,
                   "cursor" : "" }
        return self._api("statuses", "followers", params)

    #
    # Lists Methods
    #
    def lists_create(self, name, mode = "", description = ""):
        params = { "name" : name, "mode" : mode,
                   "description" : description }
        return self._api_lists("create", params = params)

    def lists_update(self, _id, name = "", mode = "", description = ""):
        params = { "name" : name, "mode" : mode,
                   "description" : description }
        return self._api_lists("update", _id = _id, params = params)

    def lists_index(self, user = "", cursor = ""):
        params = { "cursor" : cursor }
        return self._api_lists("index", user, params = params)

    def lists_show(self, _id, user = ""):
        return self._api_lists("show", user, _id)

    def lists_destroy(self, _id):
        return self._api_delete("lists", "destroy", _id = _id)

    def lists_statuses(self, _id, user = "",
                       since_id = "", max_id = "", count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api_lists("statuses", user, _id, params)

    def lists_memberships(self, user = "", cursor = ""):
        params = { "cursor" : cursor }
        return self._api_lists("memberships", user, params = params)

    def lists_subscriptions(self, user = "", cursor = ""):
        params = { "cursor" : cursor }
        return self._api_lists("subscriptions", user, params = params)

    #
    # Lists Members Methods
    #
    def lists_mlist(self, _id, user = "", cursor = ""):
        params = { "cursor" : cursor }
        return self._api_lists("mlist", user, _id, params)

    def lists_madd(self, member, _id, user = ""):
        params = { "id" : member }
        return self._api.lists("madd", user, _id, params)

    def lists_mremove(self, member, _id, user = ""):
        params = { "id" : member }
        return self._api.lists("mremove", user, _id, params)

    def lists_mshow(self, member, _id, user = "", cursor = ""):
        pass

    #
    # List Subscribers Methods
    #
    def lists_slist(self):
        pass
    def lists_sadd(self):
        pass
    def lists_sremove(self):
        pass
    def lists_sshow(self):
        pass

    #
    # Direct Message Methods
    #
    def dm_list(self, since_id = "", max_id = "",
            count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("dm", "list", params)

    def dm_sent(self, since_id = "", max_id = "",
            count = "", page = ""):
        params = { "since_id" : since_id, "max_id" : max_id,
                   "count" : count, "page" : page }
        return self._api("dm", "sent", params)

    def dm_destroy(self, _id):
        return self._api2(
            self.url["dm"]["destroy"].replace("%id%", str(_id)),
            method = self.method["dm"]["destroy"])

    def dm_new(self, user, text):
        params = { "user" : user, "text" : text }
        return self._api("dm", "new", params)

if __name__ == "__main__":
    import sys

    api = api(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

    print api.user["screen_name"]
    for status in api.home_timeline(count = 10):
        print "%15s: %s" % (
            status["user"]["screen_name"], status["text"])
<commit_msg>method args changes to use **kwargs<commit_after>import urllib, urllib2

import oauth
import twitterxml

#
# OAuth supported Twitter library for Python
# - Hirotaka Kawata (@hktechno)
# - info@techno-st.net
# - http://www.techno-st.net/
#

class api():
    twurl = "http://twitter.com/"
    apiurl = "http://api.twitter.com/1/"
    api_t = ".xml"

    url = {
        "statuses" : {
            "public_timeline"  : twurl + "statuses/public_timeline" + api_t,
            "home_timeline"    : apiurl + "statuses/home_timeline" + api_t,
            "friends_timeline" : twurl + "statuses/friends_timeline" + api_t,
            "user_timeline"    : twurl + "statuses/user_timeline" + api_t,
            "mentions"         : twurl + "statuses/mentions" + api_t,
            "retweeted_by_me"  : apiurl + "statuses/retweeted_by_me" + api_t,
            "retweeted_to_me"  : apiurl + "statuses/retweeted_to_me" + api_t,
            "retweets_of_me"   : apiurl + "statuses/retweets_of_me" + api_t,
            "show"             : twurl + "statuses/show/" + "%id%" + api_t,
            "update"           : twurl + "statuses/update" + api_t,
            "destroy"          : twurl + "statuses/destroy/" + "%id%" + api_t,
            "retweet"          : apiurl + "statuses/retweet/" + "%id%" + api_t,
            "retweets"         : apiurl + "statuses/retweets/" + "%id%" + api_t,
            "friends"          : twurl + "statuses/friends" + api_t,
            "followers"        : twurl + "statuses/followers" + api_t
            },
        "users" : {
            "show"   : twurl + "users/show" + api_t,
            "search" : apiurl + "users/search" + api_t
            },
        "account" : {
            "verify_credentials" : twurl + "account/verify_credentials" + api_t
            },
        "lists" : {
            "create"        : apiurl + "%user%/lists" + api_t,
            "update"        : apiurl + "%user%/lists/%id%" + api_t,
            "index"         : apiurl + "%user%/lists" + api_t,
            "show"          : apiurl + "%user%/lists/%id%" + api_t,
            "destroy"       : apiurl + "%user%/lists/%id%" + api_t,
            "statuses"      : apiurl + "%user%/lists/%id%/statuses" + api_t,
            "memberships"   : apiurl + "%user%/lists/memberships" + api_t,
            "subscriptions" : apiurl + "%user%/lists/subscriptions" + api_t,
            "mlist"         : apiurl + "%user%/%id%/members" + api_t,
            "madd"          : apiurl + "%user%/%id%/members" + api_t,
            "mremove"       : apiurl + "%user%/%id%/members" + api_t,
            },
        "dm" : {
            "list"    : twurl + "direct_messages" + api_t,
            "sent"    : twurl + "direct_messages/sent" + api_t,
            "new"     : twurl + "direct_messages/new" + api_t,
            "destroy" : twurl + "direct_messages/destroy/" + "%id%" + api_t,
            }
        }

    method = {
        "statuses" : {
            "public_timeline"  : "GET",
            "home_timeline"    : "GET",
            "friends_timeline" : "GET",
            "user_timeline"    : "GET",
            "mentions"         : "GET",
            "retweeted_by_me"  : "GET",
            "retweeted_to_me"  : "GET",
            "retweets_of_me"   : "GET",
            "show"             : "GET",
            "update"           : "POST",
            "destroy"          : "POST",
            "retweet"          : "POST",
            "retweets"         : "GET",
            "friends"          : "GET",
            "followers"        : "GET"
            },
        "users" : {
            "show"   : "GET",
            "search" : "GET"
            },
        "account" : {
            "verify_credentials" : "GET"
            },
        "lists" : {
            "create"        : "POST",
            "update"        : "POST",
            "index"         : "GET",
            "show"          : "GET",
            "destroy"       : "DELETE",
            "statuses"      : "GET",
            "memberships"   : "GET",
            "subscriptions" : "GET",
            "mlist"         : "GET",
            "madd"          : "POST",
            "mremove"       : "DELETE",
            },
        "dm" : {
            "list"    : "GET",
            "sent"    : "GET",
            "new"     : "POST",
            "destroy" : "POST"
            }
        }

    def __init__(self, ckey, csecret, atoken, asecret,
                 oauth_obj = None):
        if oauth_obj == None:
            self.oauth = oauth.oauth(ckey, csecret, atoken, asecret)
        else:
            self.oauth = oauth_obj

        req = self.oauth.oauth_request(
            self.url["account"]["verify_credentials"])
        getxml = urllib2.urlopen(req).read()

        user = twitterxml.xmlparse(getxml)
        self.user = user

    def _api(self, a, b, params = {}):
        params = self._rm_noparams(params)
        xml = urllib2.urlopen(
            self.oauth.oauth_request(
                self.url[a][b],
                self.method[a][b], params)).read()
        return twitterxml.xmlparse(xml)

    def _api2(self, url, params = {}, method = "GET"):
        params = self._rm_noparams(params)
        xml = urllib2.urlopen(
            self.oauth.oauth_request(
                url, method, params)).read()
        return twitterxml.xmlparse(xml)

    def _api_noauth(self, a = None, b = None, params = {},
                    url = None):
        params = self._rm_noparams(params)
        paramstr = urllib.urlencode(params)

        if not url:
            url = self.url[a][b]

        xml = urllib2.urlopen("%s?%s" % (url, paramstr)).read()
        return twitterxml.xmlparse(xml)

    def _api_lists(self, m, user = "", _id = "", params = {}):
        if not user:
            user = self.user["screen_name"]

        url = self.url["lists"][m]
        url = url.replace("%user%", str(user))
        url = url.replace("%id%", str(_id))

        return self._api2(url, params, self.method["lists"][m])

    def _api_delete(self, a, b, user = "", _id = "", params = {}):
        if not user:
            user = self.user["screen_name"]

        url = self.url[a][b]
        url = url.replace("%user%", str(user))
        url = url.replace("%id%", str(_id))

        params = self._rm_noparams(params)
        res = self.oauth.oauth_http_request(url, "DELETE", params)
        return twitterxml.xmlparse(res.read())

    def _rm_noparams(self, params):
        flg = True
        while flg:
            flg = False
            for p in params:
                if not params[p]:
                    del params[p]
                    flg = True
                    break
        return params

    def _idtype(uid):
        if str(uid).isdigit():
            return "user_id"
        else:
            return "screen_name"

    #
    # Timeline Methods
    #
    def public_timeline(self):
        return self._api_noauth("statuses", "public_timeline")

    def home_timeline(self, **params):
        return self._api("statuses", "home_timeline", params)

    def friends_timeline(self, **params):
        return self._api("statuses", "friends_timeline", params)

    def user_timeline(self, **params):
        # hmm... userid...
        try:
            data = self._api_noauth("statuses", "user_timeline", params)
        except urllib2.HTTPError:
            data = self._api("statuses", "user_timeline", params)

        return data

    def mentions(self, **params):
        return self._api("statuses", "mentions", params)

    def rt_by_me(self, **params):
        return self._api("statuses", "retweeted_by_me", params)

    def rt_to_me(self, **params):
        return self._api("statuses", "retweeted_to_me", params)

    def rt_of_me(self, **params):
        return self._api("statuses", "retweets_of_me", params)

    #
    # Status Methods
    #
    def status_show(self, _id):
        url = self.url["statuses"]["show"].replace("%id%", str(_id))
        try:
            return self._api_noauth(url = url)
        except urllib2.HTTPError:
            return self._api2(url)

    def status_update(self, status, **params):
        params["status"] = status
        return self._api("statuses", "update", params)

    def status_destroy(self, _id):
        return self._api2(
            self.url["statuses"]["destroy"].replace("%id%", str(_id)),
            method = self.method["statuses"]["destroy"])

    def status_retweet(self, _id):
        return self._api2(
            self.url["statuses"]["retweet"].replace("%id%", str(_id)),
            method = self.method["statuses"]["retweet"])

    def status_retweets(self, _id):
        return self._api2(
            self.url["statuses"]["retweets"].replace("%id%", str(_id)))

    #
    # User Methods
    #
    def user_show(self, user):
        params = { self._idtype(user) : user }
        return self._api("users", "show", params)

    def user_search(self, **params):
        return self._api("users", "search", params)

    def status_friends(self, user, **params):
        params[self._idtype(user)] = user
        return self._api("statuses", "friends", params)

    def status_followers(self, user, **params):
        params[self._idtype(user)] = user
        return self._api("statuses", "followers", params)

    #
    # Lists Methods
    #
    def lists_create(self, name, **params):
        params["name"] = name
        return self._api_lists("create", params = params)

    def lists_update(self, _id, **params):
        return self._api_lists("update", _id = _id, params = params)

    def lists_index(self, user = "", **params):
        return self._api_lists("index", user, params = params)

    def lists_show(self, _id, user = "", **params):
        return self._api_lists("show", user, _id)

    def lists_destroy(self, _id, **params):
        return self._api_delete("lists", "destroy", _id = _id, params = params)

    def lists_statuses(self, _id, user = "", **params):
        return self._api_lists("statuses", user, _id, params)

    def lists_memberships(self, user = "", **params):
        return self._api_lists("memberships", user, params = params)

    def lists_subscriptions(self, user = "", **params):
        return self._api_lists("subscriptions", user, params = params)

    #
    # Lists Members Methods
    #
    def lists_mlist(self, _id, user = "", **params):
        return self._api_lists("mlist", user, _id, params)

    def lists_madd(self, member, _id, user = "", **params):
        params["id"] = member
        return self._api.lists("madd", user, _id, params)

    def lists_mremove(self, member, _id, user = "", **params):
        params["id"] = member
        return self._api.lists("mremove", user, _id, params)

    def lists_mshow(self, member, _id, user = "", **params):

    #
    # List Subscribers Methods
    #
    def lists_slist(self):
        pass
    def lists_sadd(self):
        pass
    def lists_sremove(self):
        pass
    def lists_sshow(self):
        pass

    #
    # Direct Message Methods
    #
    def dm_list(self, **params):
        return self._api("dm", "list", params)

    def dm_sent(self, **params):
        return self._api("dm", "sent", params)

    def dm_destroy(self, _id):
        return self._api2(
            self.url["dm"]["destroy"].replace("%id%", str(_id)),
            method = self.method["dm"]["destroy"])

    def dm_new(self, user, text, **params):
        params["user"] = user
        params["text"] = text
        return self._api("dm", "new", params)

if __name__ == "__main__":
    import sys

    api = api(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

    print api.user["screen_name"]
    for status in api.home_timeline(count = 10):
        print "%15s: %s" % (
            status["user"]["screen_name"], status["text"])
<|endoftext|>


<commit_before>from phovea_server.ns import Namespace, request, abort
from . import db
from .utils import map_scores
from phovea_server.util import jsonify
from phovea_server.security import login_required
import logging

__author__ = 'Samuel Gratzl'
_log = logging.getLogger(__name__)
app = Namespace(__name__)

def load_ids(idtype, mapping):
  import phovea_server.plugin

  manager = phovea_server.plugin.lookup('idmanager')
  manager.load(idtype, mapping)

@app.route('/')
@login_required
def list_database():
  return jsonify([v[0].dump(k) for k, v in db.configs.items()])

@app.route('/<database>/')
@login_required
def list_view(database):
  config_engine = db.resolve(database)
  if not config_engine:
    return 404, 'Not Found'
  return jsonify([v.dump(k) for k, v in config_engine[0].views.items()])

def _assign_ids(r, view):
  return r and (request.args.get('_assignids', False) or (view.assign_ids and '_id' not in r[0]))

def _return_query():
  return request.args.get('_return_query', False)

@app.route('/<database>/<view_name>')
@login_required
def get_data_api(database, view_name):
  if _return_query():
    return jsonify(db.get_query(database, view_name, None, request.args))

  r, view = db.get_data(database, view_name, None, request.args)

  if _assign_ids(r, view):
    r = db.assign_ids(r, view.idtype)
  return jsonify(r)

@app.route('/<database>/<view_name>/filter')
@login_required
def get_filtered_data(database, view_name):
  """
  version of getting data in which the arguments starting with `filter_` are used to build a where clause
  :param database:
  :param view_name:
  :return:
  """
  if _return_query():
    return jsonify(db.get_filtered_query(database, view_name, request.args))

  r, view = db.get_filtered_data(database, view_name, request.args)

  if _assign_ids(r, view):
    r = db.assign_ids(r, view.idtype)
  return jsonify(r)

@app.route('/<database>/<view_name>/score')
@login_required
def get_score_data(database, view_name):
  """
  version of getting data like filter with additional mapping of score entries
  :param database:
  :param view_name:
  :return:
  """
  if _return_query():
    return jsonify(db.get_filtered_query(database, view_name, request.args))

  r, view = db.get_filtered_data(database, view_name, request.args)

  data_idtype = view.idtype
  target_idtype = request.args.get('target', data_idtype)

  if data_idtype != target_idtype:
    mapped_scores = map_scores(r, data_idtype, target_idtype)
  else:
    mapped_scores = r

  if _assign_ids(mapped_scores, view):
    mapped_scores = db.assign_ids(mapped_scores, target_idtype)
  return jsonify(mapped_scores)

@app.route('/<database>/<view_name>/count')
@login_required
def get_count_data(database, view_name):
  """
  similar to the /filter clause but returns the count of results instead of the rows itself
  :param database:
  :param view_name:
  :return:
  """
  if _return_query():
    return jsonify(db.get_count_query(database, view_name, request.args))

  r = db.get_count(database, view_name, request.args)

  return jsonify(r)

@app.route('/<database>/<view_name>/desc')
@login_required
def get_desc(database, view_name):
  config, _ = db.resolve(database)
  # convert to index lookup
  # row id start with 1
  if view_name not in config.views:
    abort(404)

  view = config.views[view_name]

  return jsonify(dict(idType=view.idtype, columns=view.columns.values()))

@app.route('/<database>/<view_name>/lookup')
@login_required
def lookup(database, view_name):
  """
  Does the same job as search, but paginates the result set
  This function is used in conjunction with Select2 form elements
  """
  query = str(request.args.get('query', '')).lower()
  page = int(request.args.get('page', 0))  # zero based
  limit = int(request.args.get('limit', 30))  # or 'all'

  if _return_query():
    return db.lookup_query(database, view_name, query, page, limit, request.args)

  r_items, more, view = db.lookup(database, view_name, query, page, limit, request.args)

  if _assign_ids(r_items, view):
    r_items = db.assign_ids(r_items, view.idtype)
  return jsonify(dict(items=r_items, more=more))

def create():
  """
   entry point of this plugin
  """
  app.debug = True
  return app
<commit_msg>support for exporting CSV files<commit_after>from phovea_server.ns import Namespace, request, abort, Response
from . import db
from .utils import map_scores
from phovea_server.util import jsonify
from phovea_server.security import login_required
import logging

__author__ = 'Samuel Gratzl'
_log = logging.getLogger(__name__)
app = Namespace(__name__)

def load_ids(idtype, mapping):
  import phovea_server.plugin

  manager = phovea_server.plugin.lookup('idmanager')
  manager.load(idtype, mapping)

@app.route('/')
@login_required
def list_database():
  return jsonify([v[0].dump(k) for k, v in db.configs.items()])

@app.route('/<database>/')
@login_required
def list_view(database):
  config_engine = db.resolve(database)
  if not config_engine:
    return 404, 'Not Found'
  return jsonify([v.dump(k) for k, v in config_engine[0].views.items()])

def _assign_ids(r, view):
  return r and (request.args.get('_assignids', False) or (view.assign_ids and '_id' not in r[0]))

def _return_query():
  return request.args.get('_return_query', False)

def _formatCsv(array_of_dicts):
  import pandas as pd
  import io

  if not array_of_dicts:
    return Response('', mimetype='text/csv')

  out = io.BytesIO()
  d = pd.DataFrame.from_records(array_of_dicts)
  d.to_csv(out, sep='\t', encoding='utf-8', index = False)
  return Response(out.getvalue(), mimetype='text/csv')

def _formatter(view_name):
  if view_name.endswith('.csv'):
    return view_name[:-4], _formatCsv
  return view_name, jsonify

@app.route('/<database>/<view_name>')
@login_required
def get_data_api(database, view_name):
  view_name, format = _formatter(view_name)
  if _return_query():
    return jsonify(db.get_query(database, view_name, None, request.args))

  r, view = db.get_data(database, view_name, None, request.args)

  if _assign_ids(r, view):
    r = db.assign_ids(r, view.idtype)
  return format(r)

@app.route('/<database>/<view_name>/filter')
@login_required
def get_filtered_data(database, view_name):
  """
  version of getting data in which the arguments starting with `filter_` are used to build a where clause
  :param database:
  :param view_name:
  :return:
  """
  view_name, format = _formatter(view_name)
  if _return_query():
    return jsonify(db.get_filtered_query(database, view_name, request.args))

  r, view = db.get_filtered_data(database, view_name, request.args)

  if _assign_ids(r, view):
    r = db.assign_ids(r, view.idtype)
  return format(r)

@app.route('/<database>/<view_name>/score')
@login_required
def get_score_data(database, view_name):
  """
  version of getting data like filter with additional mapping of score entries
  :param database:
  :param view_name:
  :return:
  """
  view_name, format = _formatter(view_name)
  if _return_query():
    return jsonify(db.get_filtered_query(database, view_name, request.args))

  r, view = db.get_filtered_data(database, view_name, request.args)

  data_idtype = view.idtype
  target_idtype = request.args.get('target', data_idtype)

  if data_idtype != target_idtype:
    mapped_scores = map_scores(r, data_idtype, target_idtype)
  else:
    mapped_scores = r

  if _assign_ids(mapped_scores, view):
    mapped_scores = db.assign_ids(mapped_scores, target_idtype)
  return format(mapped_scores)

@app.route('/<database>/<view_name>/count')
@login_required
def get_count_data(database, view_name):
  """
  similar to the /filter clause but returns the count of results instead of the rows itself
  :param database:
  :param view_name:
  :return:
  """
  view_name, _ = _formatter(view_name)
  if _return_query():
    return jsonify(db.get_count_query(database, view_name, request.args))

  r = db.get_count(database, view_name, request.args)

  return jsonify(r)

@app.route('/<database>/<view_name>/desc')
@login_required
def get_desc(database, view_name):
  view_name, _ = _formatter(view_name)
  config, _ = db.resolve(database)
  # convert to index lookup
  # row id start with 1
  if view_name not in config.views:
    abort(404)

  view = config.views[view_name]

  return jsonify(dict(idType=view.idtype, columns=view.columns.values()))

@app.route('/<database>/<view_name>/lookup')
@login_required
def lookup(database, view_name):
  """
  Does the same job as search, but paginates the result set
  This function is used in conjunction with Select2 form elements
  """
  view_name, _ = _formatter(view_name)
  query = str(request.args.get('query', '')).lower()
  page = int(request.args.get('page', 0))  # zero based
  limit = int(request.args.get('limit', 30))  # or 'all'

  if _return_query():
    return db.lookup_query(database, view_name, query, page, limit, request.args)

  r_items, more, view = db.lookup(database, view_name, query, page, limit, request.args)

  if _assign_ids(r_items, view):
    r_items = db.assign_ids(r_items, view.idtype)
  return jsonify(dict(items=r_items, more=more))

def create():
  """
   entry point of this plugin
  """
  app.debug = True
  return app
<|endoftext|>