<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File: common.py
# Author: Yuxin Wu <ppwwyyxxc@gmail.com>
import random
import time
import threading
import multiprocessing
import numpy as np
from tqdm import tqdm
from six.moves import queue

from tensorpack import *
from tensorpack.utils.concurrency import *
from tensorpack.utils.stats import *

def play_one_episode(player, func, verbose=False):
    def f(s):
        spc = player.get_action_space()
        act = func([[s]])[0][0].argmax()
        if random.random() < 0.001:
            act = spc.sample()
        if verbose:
            print(act)
        return act
    return np.mean(player.play_one_episode(f))

def play_model(cfg, player):
    predfunc = OfflinePredictor(cfg)
    while True:
        score = play_one_episode(player, predfunc)
        print("Total:", score)

def eval_with_funcs(predictors, nr_eval, get_player_fn):
    class Worker(StoppableThread, ShareSessionThread):
        def __init__(self, func, queue):
            super(Worker, self).__init__()
            self._func = func
            self.q = queue

        def func(self, *args, **kwargs):
            if self.stopped():
                raise RuntimeError("stopped!")
            return self._func(*args, **kwargs)

        def run(self):
            with self.default_sess():
                player = get_player_fn(train=False)
                while not self.stopped():
                    try:
                        score = play_one_episode(player, self.func)
                        # print("Score, ", score)
                    except RuntimeError:
                        return
                    self.queue_put_stoppable(self.q, score)

    q = queue.Queue()
    threads = [Worker(f, q) for f in predictors]

    for k in threads:
        k.start()
        time.sleep(0.1)  # avoid simulator bugs
    stat = StatCounter()
    try:
        for _ in tqdm(range(nr_eval), **get_tqdm_kwargs()):
            r = q.get()
            stat.feed(r)
        logger.info("Waiting for all the workers to finish the last run...")
        for k in threads:
            k.stop()
        for k in threads:
            k.join()
        while q.qsize():
            r = q.get()
            stat.feed(r)
    except:
        logger.exception("Eval")
    finally:
        if stat.count > 0:
            return (stat.average, stat.max)
        return (0, 0)

def eval_model_multithread(cfg, nr_eval, get_player_fn):
    func = OfflinePredictor(cfg)
    NR_PROC = min(multiprocessing.cpu_count() // 2, 8)
    mean, max = eval_with_funcs([func] * NR_PROC, nr_eval, get_player_fn)
    logger.info("Average Score: {}; Max Score: {}".format(mean, max))

class Evaluator(Triggerable):
    def __init__(self, nr_eval, input_names, output_names, get_player_fn):
        self.eval_episode = nr_eval
        self.input_names = input_names
        self.output_names = output_names
        self.get_player_fn = get_player_fn

    def _setup_graph(self):
        NR_PROC = min(multiprocessing.cpu_count() // 2, 20)
        self.pred_funcs = [self.trainer.get_predictor(
            self.input_names, self.output_names)] * NR_PROC

    def _trigger(self):
        t = time.time()
        mean, max = eval_with_funcs(
            self.pred_funcs, self.eval_episode, self.get_player_fn)
        t = time.time() - t
        if t > 10 * 60:  # eval takes too long
            self.eval_episode = int(self.eval_episode * 0.94)
        self.trainer.monitors.put_scalar('mean_score', mean)
        self.trainer.monitors.put_scalar('max_score', max)

def play_n_episodes(player, predfunc, nr):
    logger.info("Start evaluation: ")
    for k in range(nr):
        if k != 0:
            player.restart_episode()
        score = play_one_episode(player, predfunc)
        print("{}/{}, score=", k, nr, score)
<commit_msg>fix logging in RL evaluation<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File: common.py
# Author: Yuxin Wu <ppwwyyxxc@gmail.com>
import random
import time
import threading
import multiprocessing
import numpy as np
from tqdm import tqdm
from six.moves import queue

from tensorpack import *
from tensorpack.utils.concurrency import *
from tensorpack.utils.stats import *

def play_one_episode(player, func, verbose=False):
    def f(s):
        spc = player.get_action_space()
        act = func([[s]])[0][0].argmax()
        if random.random() < 0.001:
            act = spc.sample()
        if verbose:
            print(act)
        return act
    return np.mean(player.play_one_episode(f))

def play_model(cfg, player):
    predfunc = OfflinePredictor(cfg)
    while True:
        score = play_one_episode(player, predfunc)
        print("Total:", score)

def eval_with_funcs(predictors, nr_eval, get_player_fn):
    class Worker(StoppableThread, ShareSessionThread):
        def __init__(self, func, queue):
            super(Worker, self).__init__()
            self._func = func
            self.q = queue

        def func(self, *args, **kwargs):
            if self.stopped():
                raise RuntimeError("stopped!")
            return self._func(*args, **kwargs)

        def run(self):
            with self.default_sess():
                player = get_player_fn(train=False)
                while not self.stopped():
                    try:
                        score = play_one_episode(player, self.func)
                        # print("Score, ", score)
                    except RuntimeError:
                        return
                    self.queue_put_stoppable(self.q, score)

    q = queue.Queue()
    threads = [Worker(f, q) for f in predictors]

    for k in threads:
        k.start()
        time.sleep(0.1)  # avoid simulator bugs
    stat = StatCounter()
    try:
        for _ in tqdm(range(nr_eval), **get_tqdm_kwargs()):
            r = q.get()
            stat.feed(r)
        logger.info("Waiting for all the workers to finish the last run...")
        for k in threads:
            k.stop()
        for k in threads:
            k.join()
        while q.qsize():
            r = q.get()
            stat.feed(r)
    except:
        logger.exception("Eval")
    finally:
        if stat.count > 0:
            return (stat.average, stat.max)
        return (0, 0)

def eval_model_multithread(cfg, nr_eval, get_player_fn):
    func = OfflinePredictor(cfg)
    NR_PROC = min(multiprocessing.cpu_count() // 2, 8)
    mean, max = eval_with_funcs([func] * NR_PROC, nr_eval, get_player_fn)
    logger.info("Average Score: {}; Max Score: {}".format(mean, max))

class Evaluator(Triggerable):
    def __init__(self, nr_eval, input_names, output_names, get_player_fn):
        self.eval_episode = nr_eval
        self.input_names = input_names
        self.output_names = output_names
        self.get_player_fn = get_player_fn

    def _setup_graph(self):
        NR_PROC = min(multiprocessing.cpu_count() // 2, 20)
        self.pred_funcs = [self.trainer.get_predictor(
            self.input_names, self.output_names)] * NR_PROC

    def _trigger(self):
        t = time.time()
        mean, max = eval_with_funcs(
            self.pred_funcs, self.eval_episode, self.get_player_fn)
        t = time.time() - t
        if t > 10 * 60:  # eval takes too long
            self.eval_episode = int(self.eval_episode * 0.94)
        self.trainer.monitors.put_scalar('mean_score', mean)
        self.trainer.monitors.put_scalar('max_score', max)

def play_n_episodes(player, predfunc, nr):
    logger.info("Start evaluation: ")
    for k in range(nr):
        if k != 0:
            player.restart_episode()
        score = play_one_episode(player, predfunc)
        print("{}/{}, score={}".format(k, nr, score))
<|endoftext|>


<commit_before>import json
import requests
import xml.dom.minidom as minidom
from ifind.search.engine import Engine
from ifind.search.response import Response
from engines.exceptions import EngineException

API_ENDPOINT = 'https://www.wikipedia.org/w/api.php'

RESULT_FORMATS = ("XML",)
DEFAULT_RESULT_FORMAT = "XML"

class Wikipedia(Engine):

    def __init__(self, **kwargs):
        """
        Constructor for Wikipedia engine class, inheriting from ifind's Engine.

        :param proxies: dict representing proxies to use
                        i.e. {"http":"10.10.1.10:3128", "https":"10.10.1.10:1080"} (optional)
        """
        Engine.__init__(self, **kwargs)

    def search(self, query):
        """
        Performs a search, retrieves the results and returns them as an ifind response.

        See: http://en.wikipedia.org/w/api.php for API documentation.

        Accepted query parameters:
            top:    specifies maximum amount of results to return, no guarantee on minimum

        :param query: ifind.search.query.Query object
        :return ifind.search.response.Response object
        :raises Bad request etc

        """
        return self._request(query)

    def _request(self, query):

        if not query.format:
            query.format = DEFAULT_RESULT_FORMAT

        if query.format.upper() not in RESULT_FORMATS:
            raise EngineException(self.name, "Engine doesn't support query format type '{0}'".format(query.format))

        search_params = {'format': query.format.lower(),
                         'search': query.terms,
                         'action': 'opensearch',
                         'limit': query.top}

        try:
            response = requests.get(API_ENDPOINT, params=search_params)
        except requests.exceptions.ConnectionError:
            raise EngineException(self.name, "", code=response.status_code)

        if response.status_code != 200:
            raise EngineException(self.name, "", code=response.status_code)

        if query.format.upper() == 'XML':
            return Wikipedia._parse_xml_response(query, response)

    @staticmethod
    def _parse_xml_response(query, results):
        """
        Parses Wikipedia XML response and returns ifind.search.response.Response object.

        :param query: original ifind.search.query.Query object
        :param results: response object (requests) obtained from API request
        :return: ifind.search.response.Response object

        """
        response = Response(query.terms)

        xml_doc = minidom.parseString(results.content)
        results = xml_doc.getElementsByTagName('Item')

        for result in results:
            title = result.getElementsByTagName('Text')[0].firstChild.data
            url = result.getElementsByTagName('Url')[0].firstChild.data
            summary = result.getElementsByTagName('Description')[0].firstChild.data

            response.add_result(title, url, summary)

        return response
<commit_msg>minor import fix<commit_after>import requests
import xml.dom.minidom
from ifind.search.engine import Engine
from ifind.search.response import Response
from ifind.search.engines.exceptions import EngineException

API_ENDPOINT = 'https://www.wikipedia.org/w/api.php'

RESULT_FORMATS = ("XML",)
DEFAULT_RESULT_FORMAT = "XML"

class Wikipedia(Engine):

    def __init__(self, **kwargs):
        """
        Constructor for Wikipedia engine class, inheriting from ifind's Engine.

        :param proxies: dict representing proxies to use
                        i.e. {"http":"10.10.1.10:3128", "https":"10.10.1.10:1080"} (optional)
        """
        Engine.__init__(self, **kwargs)

    def search(self, query):
        """
        Performs a search, retrieves the results and returns them as an ifind response.

        See: http://en.wikipedia.org/w/api.php for API documentation.

        Accepted query parameters:
            top:    specifies maximum amount of results to return, no guarantee on minimum

        :param query: ifind.search.query.Query object
        :return ifind.search.response.Response object
        :raises Bad request etc

        """
        return self._request(query)

    def _request(self, query):

        if not query.format:
            query.format = DEFAULT_RESULT_FORMAT

        if query.format.upper() not in RESULT_FORMATS:
            raise EngineException(self.name, "Engine doesn't support query format type '{0}'".format(query.format))

        search_params = {'format': query.format.lower(),
                         'search': query.terms,
                         'action': 'opensearch',
                         'limit': query.top}

        try:
            response = requests.get(API_ENDPOINT, params=search_params)
        except requests.exceptions.ConnectionError:
            raise EngineException(self.name, "", code=response.status_code)

        if response.status_code != 200:
            raise EngineException(self.name, "", code=response.status_code)

        if query.format.upper() == 'XML':
            return Wikipedia._parse_xml_response(query, response)

    @staticmethod
    def _parse_xml_response(query, results):
        """
        Parses Wikipedia XML response and returns ifind.search.response.Response object.

        :param query: original ifind.search.query.Query object
        :param results: response object (requests) obtained from API request
        :return: ifind.search.response.Response object

        """
        response = Response(query.terms)

        xml_doc = xml.dom.minidom.parseString(results.content)
        results = xml_doc.getElementsByTagName('Item')

        for result in results:
            title = result.getElementsByTagName('Text')[0].firstChild.data
            url = result.getElementsByTagName('Url')[0].firstChild.data
            summary = result.getElementsByTagName('Description')[0].firstChild.data

            response.add_result(title, url, summary)

        return response
<|endoftext|>


<commit_before>'''
Created on Jan 30, 2015

@author: gaprice@lbl.gov
'''
from __future__ import print_function
import os
import inspect
from biokbase.Transform import script_utils
from biokbase.Transform.handler_utils import PlugIns
from biokbase.AbstractHandle.Client import AbstractHandle
from bzrlib.config import ConfigObj
import json
from biokbase.workspace.client import Workspace
import random
import sys
import subprocess
from deep_eq import deep_eq

# TODO run this with makefile
# TODO more test cases

KB_TOKEN = 'KB_AUTH_TOKEN'
TEST_CFG_FILE = 'test.cfg'

FILE_LOC = os.path.split(__file__)[0]

sys.path.append(os.path.join(FILE_LOC, '../'))  # to import demo/setup
# this import is both resolved and used
from demo.setup import TransformVirtualEnv  # @UnresolvedImport @UnusedImport

TRANSFORM_LOC = os.path.join(FILE_LOC, '../../')
# maybe this should be configurable...?
PLUGIN_CFG_LOC = os.path.join(TRANSFORM_LOC, 'plugins/configs')

class Test_Scripts(object):

    @classmethod
    def setup_class(cls):
        cls.token = os.environ.get(KB_TOKEN)
        if not cls.token:
            raise ValueError('No token found in environment variable ' +
                             KB_TOKEN)
        cls.plugins_cfg = PlugIns(PLUGIN_CFG_LOC)
        cfg = ConfigObj(TEST_CFG_FILE)
        for url in ['ws_url', 'shock_url', 'handle_url', 'ujs_url']:
            setattr(cls, url, cfg.get(url))
        tve = TransformVirtualEnv(FILE_LOC, 'venv', TRANSFORM_LOC,
                                  keep_current_venv=False)
        tve.activate_for_current_py_process()
        cls.staged = {}
        cls.stage_data()

    @classmethod
    def stage_data(cls):
        cls.stage_assy_file()

    @classmethod
    def stage_assy_file(cls):
        this_function_name = sys._getframe().f_code.co_name
        src_obj_name = 'test_assy_file'
        src_type = 'KBaseFile.AssemblyFile'

        test_file = os.path.join(FILE_LOC, 'test_files/sample.fa')
        node_id, handle = cls.upload_file_to_shock_and_get_handle(test_file)

        test_json = os.path.join(FILE_LOC, 'test_files/AssemblyFile.json')
        with open(test_json) as assyjsonfile:
            assyjson = json.loads(assyjsonfile.read())
        assyjson['assembly_file']['file']['url'] = cls.shock_url
        assyjson['assembly_file']['file']['id'] = node_id
        assyjson['assembly_file']['file']['hid'] = handle

        src_ws = cls.create_random_workspace(this_function_name)
        ws = Workspace(cls.ws_url, token=cls.token)
        objdata = ws.save_objects(
            {'workspace': src_ws,
             'objects': [{'name': src_obj_name,
                          'type': src_type,
                          'data': assyjson}]
             })[0]
        ref = str(objdata[6]) + '/' + str(objdata[0]) + '/' + str(objdata[4])
        cls.staged['assy_file'] = {'obj_info': objdata,
                                   'node': node_id,
                                   'ref': ref}

    @classmethod
    def upload_file_to_shock_and_get_handle(cls, test_file):
        node_id = script_utils.upload_file_to_shock(
            shock_service_url=cls.shock_url,
            filePath=test_file,
            ssl_verify=False,
            token=cls.token)['id']

        handle = AbstractHandle(cls.handle_url, token=cls.token)
        handle_id = handle.persist_handle({'id': node_id,
                                           'type': 'shock',
                                           'url': cls.shock_url
                                           })
        return node_id, handle_id

    @classmethod
    def create_random_workspace(cls, prefix):
        ws = Workspace(cls.ws_url, token=cls.token)
        ws_name = prefix + '_' + str(random.random())[2:]
        wsinfo = ws.create_workspace({'workspace': ws_name})
        return wsinfo[1]

    @classmethod
    def run_convert_taskrunner(cls, args):
        input_args = cls.plugins_cfg.get_handler_args("convert", args)
        command_list = ['trns_convert_taskrunner.py']

        for k in input_args:
            command_list.append("--{0}".format(k))
            command_list.append("{0}".format(input_args[k]))

        task = subprocess.Popen(command_list, stderr=subprocess.PIPE)
        so, se = task.communicate()
        return so, se, task.returncode

    def test_assyfile_to_cs_basic_ops(self):
        this_function_name = sys._getframe().f_code.co_name
        staged = self.staged['assy_file']

        src_ws = staged['obj_info'][7]
        src_obj_name = staged['obj_info'][1]
        src_type = staged['obj_info'][2].split('-')[0]
        dest_ws = self.create_random_workspace(this_function_name)
        dest_obj_name = 'foo2'
        dest_type = 'KBaseGenomes.ContigSet'
        node_id = staged['node']
        ref = staged['ref']

        args = {'source_kbase_type': src_type,
                'destination_kbase_type': dest_type,
                'source_workspace_name': src_ws,
                'destination_workspace_name': dest_ws,
                'source_object_name': src_obj_name,
                'destination_object_name': dest_obj_name,
                'workspace_service_url': self.ws_url,
                'ujs_service_url': self.ujs_url,
                'working_directory': src_ws}

        stdo, stde, code = self.run_convert_taskrunner(args)
        if stdo:
            raise TestException('Got unexpected data in standard out:\n' +
                                stdo)
        if 'ERROR' in stde:
            raise TestException('Error reported in stderr:\n' + stde)
        if 'INFO - Conversion completed.' not in stde:
            raise TestException('Script did not report as completed:\n' + stde)
        if code != 0:
            raise TestException('Got non zero return code from script')

        ws = Workspace(self.ws_url, token=self.token)
        newobj = ws.get_objects([{'workspace': dest_ws,
                                  'name': dest_obj_name}])[0]
        prov = newobj['provenance'][0]
        assert prov['input_ws_objects'] == [ref]
        assert prov['resolved_ws_objects'] == [ref]
        assert prov['script'] ==\
            'trns_transform_KBaseFile_AssemblyFile_to_KBaseGenomes_ContigSet'
        assert prov['script_ver'] == '0.0.1'

        with open(os.path.join(FILE_LOC, 'test_files/ContigSetOut.json')) as f:
            expected = json.loads(f.read())
        expected['fasta_ref'] = node_id
        deep_eq(expected, newobj['data'], _assert=True)

class TestException(Exception):
    pass

def main():
    # use nosetests to run these tests, this is a hack to get them to run
    # while testing the tests
    Test_Scripts.setup_class()
    ts = Test_Scripts()
    methods = inspect.getmembers(ts, predicate=inspect.ismethod)
    for meth in methods:
        if meth[0].startswith('test_'):
            print("\nRunning " + meth[0])
            meth[1]()

if __name__ == '__main__':
    main()
<commit_msg>Add failing test <commit_after>'''
Created on Jan 30, 2015

@author: gaprice@lbl.gov
'''
from __future__ import print_function
import os
import inspect
from biokbase.Transform import script_utils
from biokbase.Transform.handler_utils import PlugIns
from biokbase.AbstractHandle.Client import AbstractHandle
from bzrlib.config import ConfigObj
import json
from biokbase.workspace.client import Workspace
import random
import sys
import subprocess
from deep_eq import deep_eq

# TODO run this with makefile
# TODO more test cases

KB_TOKEN = 'KB_AUTH_TOKEN'
TEST_CFG_FILE = 'test.cfg'

FILE_LOC = os.path.split(__file__)[0]

sys.path.append(os.path.join(FILE_LOC, '../'))  # to import demo/setup
# this import is both resolved and used
from demo.setup import TransformVirtualEnv  # @UnresolvedImport @UnusedImport

TRANSFORM_LOC = os.path.join(FILE_LOC, '../../')
# maybe this should be configurable...?
PLUGIN_CFG_LOC = os.path.join(TRANSFORM_LOC, 'plugins/configs')

class Test_Scripts(object):

    @classmethod
    def setup_class(cls):
        cls.token = os.environ.get(KB_TOKEN)
        if not cls.token:
            raise ValueError('No token found in environment variable ' +
                             KB_TOKEN)
        cls.plugins_cfg = PlugIns(PLUGIN_CFG_LOC)
        cfg = ConfigObj(TEST_CFG_FILE)
        for url in ['ws_url', 'shock_url', 'handle_url', 'ujs_url']:
            setattr(cls, url, cfg.get(url))
        tve = TransformVirtualEnv(FILE_LOC, 'venv', TRANSFORM_LOC,
                                  keep_current_venv=False)
        tve.activate_for_current_py_process()
        cls.staged = {}
        cls.stage_data()

    @classmethod
    def stage_data(cls):
        cls.stage_assy_file()

    @classmethod
    def stage_assy_file(cls):
        this_function_name = sys._getframe().f_code.co_name
        src_obj_name = 'test_assy_file'
        src_type = 'KBaseFile.AssemblyFile'

        test_file = os.path.join(FILE_LOC, 'test_files/sample.fa')
        node_id, handle = cls.upload_file_to_shock_and_get_handle(test_file)

        test_json = os.path.join(FILE_LOC, 'test_files/AssemblyFile.json')
        with open(test_json) as assyjsonfile:
            assyjson = json.loads(assyjsonfile.read())
        assyjson['assembly_file']['file']['url'] = cls.shock_url
        assyjson['assembly_file']['file']['id'] = node_id
        assyjson['assembly_file']['file']['hid'] = handle

        src_ws = cls.create_random_workspace(this_function_name)
        ws = Workspace(cls.ws_url, token=cls.token)
        objdata = ws.save_objects(
            {'workspace': src_ws,
             'objects': [{'name': src_obj_name,
                          'type': src_type,
                          'data': assyjson}]
             })[0]
        ref = str(objdata[6]) + '/' + str(objdata[0]) + '/' + str(objdata[4])
        cls.staged['assy_file'] = {'obj_info': objdata,
                                   'node': node_id,
                                   'ref': ref}

    @classmethod
    def upload_file_to_shock_and_get_handle(cls, test_file):
        node_id = script_utils.upload_file_to_shock(
            shock_service_url=cls.shock_url,
            filePath=test_file,
            ssl_verify=False,
            token=cls.token)['id']

        handle = AbstractHandle(cls.handle_url, token=cls.token)
        handle_id = handle.persist_handle({'id': node_id,
                                           'type': 'shock',
                                           'url': cls.shock_url
                                           })
        return node_id, handle_id

    @classmethod
    def create_random_workspace(cls, prefix):
        ws = Workspace(cls.ws_url, token=cls.token)
        ws_name = prefix + '_' + str(random.random())[2:]
        wsinfo = ws.create_workspace({'workspace': ws_name})
        return wsinfo[1]

    @classmethod
    def run_convert_taskrunner(cls, args):
        input_args = cls.plugins_cfg.get_handler_args("convert", args)
        command_list = ['trns_convert_taskrunner.py']

        for k in input_args:
            command_list.append("--{0}".format(k))
            command_list.append("{0}".format(input_args[k]))

        task = subprocess.Popen(command_list, stderr=subprocess.PIPE)
        so, se = task.communicate()
        return so, se, task.returncode

    def test_assyfile_to_cs_basic_ops(self):
        this_function_name = sys._getframe().f_code.co_name
        staged = self.staged['assy_file']

        src_ws = staged['obj_info'][7]
        src_obj_name = staged['obj_info'][1]
        src_type = staged['obj_info'][2].split('-')[0]
        dest_ws = self.create_random_workspace(this_function_name)
        dest_obj_name = 'foo2'
        dest_type = 'KBaseGenomes.ContigSet'
        node_id = staged['node']
        ref = staged['ref']

        args = {'source_kbase_type': src_type,
                'destination_kbase_type': dest_type,
                'source_workspace_name': src_ws,
                'destination_workspace_name': dest_ws,
                'source_object_name': src_obj_name,
                'destination_object_name': dest_obj_name,
                'workspace_service_url': self.ws_url,
                'ujs_service_url': self.ujs_url,
                'working_directory': src_ws}

        stdo, stde, code = self.run_convert_taskrunner(args)
        if stdo:
            raise TestException('Got unexpected data in standard out:\n' +
                                stdo)
        if 'ERROR' in stde:
            raise TestException('Error reported in stderr:\n' + stde)
        if 'INFO - Conversion completed.' not in stde:
            raise TestException('Script did not report as completed:\n' + stde)
        if code != 0:
            raise TestException('Got non zero return code from script:' +
                                str(code))

        ws = Workspace(self.ws_url, token=self.token)
        newobj = ws.get_objects([{'workspace': dest_ws,
                                  'name': dest_obj_name}])[0]
        prov = newobj['provenance'][0]
        assert prov['input_ws_objects'] == [ref]
        assert prov['resolved_ws_objects'] == [ref]
        assert prov['script'] ==\
            'trns_transform_KBaseFile_AssemblyFile_to_KBaseGenomes_ContigSet'
        assert prov['script_ver'] == '0.0.1'

        with open(os.path.join(FILE_LOC, 'test_files/ContigSetOut.json')) as f:
            expected = json.loads(f.read())
        expected['fasta_ref'] = node_id
        deep_eq(expected, newobj['data'], _assert=True)

    def test_assyfile_to_cs_fail_ws_error(self):
        this_function_name = sys._getframe().f_code.co_name
        staged = self.staged['assy_file']

        src_ws = staged['obj_info'][7]
        src_obj_name = staged['obj_info'][1]
        src_type = staged['obj_info'][2].split('-')[0]
        dest_ws = self.create_random_workspace(this_function_name)
        dest_obj_name = 'foo2'
        dest_type = 'KBaseGenomes.ContigSet'

        args = {'source_kbase_type': src_type,
                'destination_kbase_type': dest_type,
                'source_workspace_name': src_ws + 'thisllbreakthings',
                'destination_workspace_name': dest_ws,
                'source_object_name': src_obj_name,
                'destination_object_name': dest_obj_name,
                'workspace_service_url': self.ws_url,
                'ujs_service_url': self.ujs_url,
                'working_directory': src_ws}

        stdo, stde, code = self.run_convert_taskrunner(args)
        if stdo:
            raise TestException('Got unexpected data in standard out:\n' +
                                stdo)
        expect = 'Object test_assy_file cannot be accessed: No workspace ' +\
            'with name stage_assy_file'
        if expect not in stde:
            raise TestException('Did not get expected error in stderr:\n' +
                                stde)
        if code != 1:
            raise TestException('Got unexpected return code from script:' +
                                str(code))

class TestException(Exception):
    pass

def main():
    # use nosetests to run these tests, this is a hack to get them to run
    # while testing the tests
    Test_Scripts.setup_class()
    ts = Test_Scripts()
    methods = inspect.getmembers(ts, predicate=inspect.ismethod)
    for meth in methods:
        if meth[0].startswith('test_'):
            print("\nRunning " + meth[0])
            meth[1]()

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


<commit_before># coding: utf-8

import asyncio
import logging
import threading
import queue

from pathlib import Path
from typing import Awaitable, Callable

from ddict import DotAccessDict
from il2fb.ds.middleware.console.client import ConsoleClient
from il2fb.ds.middleware.device_link.client import DeviceLinkClient
from il2fb.parsers.game_log.parsers import GameLogEventParser

from il2fb.ds.airbridge.dedicated_server.console import ConsoleProxy
from il2fb.ds.airbridge.dedicated_server.device_link import DeviceLinkProxy
from il2fb.ds.airbridge.dedicated_server.game_log import GameLogWorker
from il2fb.ds.airbridge.dedicated_server.process import DedicatedServer
from il2fb.ds.airbridge.typing import IntOrNone, StringHandler
from il2fb.ds.airbridge.watch_dog import TextFileWatchDog

LOG = logging.getLogger(__name__)

class Airbridge:

    def __init__(
        self,
        loop: asyncio.AbstractEventLoop,
        config: DotAccessDict,
        state: DotAccessDict,
        dedicated_server: DedicatedServer,
        console_client: ConsoleClient,
        device_link_client: DeviceLinkClient,
    ):
        self._loop = loop
        self._config = config
        self._state = state

        self._dedicated_server = dedicated_server

        self._console_client = console_client
        self._console_client_proxy = None

        self._device_link_client = device_link_client
        self._device_link_client_proxy = None

        self._game_log_watch_dog = None
        self._game_log_watch_dog_thread = None

        self._game_log_worker = None
        self._game_log_worker_thread = None

        self._game_log_line_queue = queue.Queue()
        self._game_log_event_parser = GameLogEventParser()

    async def start(self) -> Awaitable[None]:
        await self._maybe_start_console_client_proxy()
        await self._maybe_start_device_link_client_proxy()
        self._start_game_log_processing()

    async def _maybe_start_console_client_proxy(self) -> None:
        console_proxy_config = self._config.ds.console_proxy
        if console_proxy_config:
            self._console_client_proxy = ConsoleProxy(
                loop=self._loop,
                config=console_proxy_config,
                console_client=self._console_client,
            )
            await self._console_client_proxy.start()

    async def _maybe_start_device_link_client_proxy(self) -> None:
        device_link_proxy_config = self._config.ds.device_link_proxy
        if device_link_proxy_config:
            self._device_link_client_proxy = DeviceLinkProxy(
                loop=self._loop,
                config=device_link_proxy_config,
                device_link_client=self._device_link_client,
            )
            await self._device_link_client_proxy.start()

    def _start_game_log_processing(self):
        self._start_game_log_worker()
        self._start_game_log_watch_dog()

    def _start_game_log_worker(self):
        self._game_log_worker = GameLogWorker(
            string_producer=self._game_log_line_queue.get,
            string_parser=self._game_log_event_parser.parse,
        )
        self._game_log_worker_thread = threading.Thread(
            target=self._game_log_worker.run,
            daemon=True,
        )
        self._game_log_worker_thread.start()

    def _start_game_log_watch_dog(self):
        file_path = Path(self._dedicated_server.config.events.logging.file_name)

        if not file_path.is_absolute():
            file_path = self._dedicated_server.root_dir / file_path

        file_path = file_path.absolute()

        self._game_log_watch_dog = TextFileWatchDog(
            path=file_path,
            state=self._state.game_log_watch_dog,
        )
        self._game_log_watch_dog.subscribe(
            subscriber=self._game_log_line_queue.put_nowait,
        )
        self._game_log_watch_dog_thread = threading.Thread(
            target=self._game_log_watch_dog.run,
            daemon=True,
        )
        self._game_log_watch_dog_thread.start()

    def stop(self) -> None:
        if self._console_client_proxy:
            self._console_client_proxy.stop()

        if self._device_link_client_proxy:
            self._device_link_client_proxy.stop()

        if self._game_log_watch_dog:
            self._game_log_watch_dog.stop()

    async def wait_stopped(self) -> Awaitable[IntOrNone]:
        awaitables = []

        if self._console_client_proxy:
            awaitables.append(self._console_client_proxy.wait_stopped())

        if self._device_link_client_proxy:
            awaitables.append(self._device_link_client_proxy.wait_stopped())

        if awaitables:
            await asyncio.gather(*awaitables, loop=self._loop)

        if self._game_log_watch_dog_thread:
            self._game_log_watch_dog_thread.join()

        if self._game_log_worker_thread:
            self._game_log_worker.stop()
            self._game_log_line_queue.put_nowait(None)
            self._game_log_worker_thread.join()
<commit_msg>Rename '_game_log_line_queue' to '_game_log_string_queue'<commit_after># coding: utf-8

import asyncio
import logging
import threading
import queue

from pathlib import Path
from typing import Awaitable, Callable

from ddict import DotAccessDict
from il2fb.ds.middleware.console.client import ConsoleClient
from il2fb.ds.middleware.device_link.client import DeviceLinkClient
from il2fb.parsers.game_log.parsers import GameLogEventParser

from il2fb.ds.airbridge.dedicated_server.console import ConsoleProxy
from il2fb.ds.airbridge.dedicated_server.device_link import DeviceLinkProxy
from il2fb.ds.airbridge.dedicated_server.game_log import GameLogWorker
from il2fb.ds.airbridge.dedicated_server.process import DedicatedServer
from il2fb.ds.airbridge.typing import IntOrNone, StringHandler
from il2fb.ds.airbridge.watch_dog import TextFileWatchDog

LOG = logging.getLogger(__name__)

class Airbridge:

    def __init__(
        self,
        loop: asyncio.AbstractEventLoop,
        config: DotAccessDict,
        state: DotAccessDict,
        dedicated_server: DedicatedServer,
        console_client: ConsoleClient,
        device_link_client: DeviceLinkClient,
    ):
        self._loop = loop
        self._config = config
        self._state = state

        self._dedicated_server = dedicated_server

        self._console_client = console_client
        self._console_client_proxy = None

        self._device_link_client = device_link_client
        self._device_link_client_proxy = None

        self._game_log_watch_dog = None
        self._game_log_watch_dog_thread = None

        self._game_log_worker = None
        self._game_log_worker_thread = None

        self._game_log_string_queue = queue.Queue()
        self._game_log_event_parser = GameLogEventParser()

    async def start(self) -> Awaitable[None]:
        await self._maybe_start_console_client_proxy()
        await self._maybe_start_device_link_client_proxy()
        self._start_game_log_processing()

    async def _maybe_start_console_client_proxy(self) -> None:
        console_proxy_config = self._config.ds.console_proxy
        if console_proxy_config:
            self._console_client_proxy = ConsoleProxy(
                loop=self._loop,
                config=console_proxy_config,
                console_client=self._console_client,
            )
            await self._console_client_proxy.start()

    async def _maybe_start_device_link_client_proxy(self) -> None:
        device_link_proxy_config = self._config.ds.device_link_proxy
        if device_link_proxy_config:
            self._device_link_client_proxy = DeviceLinkProxy(
                loop=self._loop,
                config=device_link_proxy_config,
                device_link_client=self._device_link_client,
            )
            await self._device_link_client_proxy.start()

    def _start_game_log_processing(self):
        self._start_game_log_worker()
        self._start_game_log_watch_dog()

    def _start_game_log_worker(self):
        self._game_log_worker = GameLogWorker(
            string_producer=self._game_log_string_queue.get,
            string_parser=self._game_log_event_parser.parse,
        )
        self._game_log_worker_thread = threading.Thread(
            target=self._game_log_worker.run,
            daemon=True,
        )
        self._game_log_worker_thread.start()

    def _start_game_log_watch_dog(self):
        file_path = Path(self._dedicated_server.config.events.logging.file_name)

        if not file_path.is_absolute():
            file_path = self._dedicated_server.root_dir / file_path

        file_path = file_path.absolute()

        self._game_log_watch_dog = TextFileWatchDog(
            path=file_path,
            state=self._state.game_log_watch_dog,
        )
        self._game_log_watch_dog.subscribe(
            subscriber=self._game_log_string_queue.put_nowait,
        )
        self._game_log_watch_dog_thread = threading.Thread(
            target=self._game_log_watch_dog.run,
            daemon=True,
        )
        self._game_log_watch_dog_thread.start()

    def stop(self) -> None:
        if self._console_client_proxy:
            self._console_client_proxy.stop()

        if self._device_link_client_proxy:
            self._device_link_client_proxy.stop()

        if self._game_log_watch_dog:
            self._game_log_watch_dog.stop()

    async def wait_stopped(self) -> Awaitable[IntOrNone]:
        awaitables = []

        if self._console_client_proxy:
            awaitables.append(self._console_client_proxy.wait_stopped())

        if self._device_link_client_proxy:
            awaitables.append(self._device_link_client_proxy.wait_stopped())

        if awaitables:
            await asyncio.gather(*awaitables, loop=self._loop)

        if self._game_log_watch_dog_thread:
            self._game_log_watch_dog_thread.join()

        if self._game_log_worker_thread:
            self._game_log_worker.stop()
            self._game_log_string_queue.put_nowait(None)
            self._game_log_worker_thread.join()
<|endoftext|>


<commit_before>from __future__ import unicode_literals
from shutil import rmtree

from django.contrib.auth.models import User
from django.conf import settings
from django.test import TestCase
import factory
from faker import Faker

from .models import Album, Photo

fake = Faker()

class UserFactory(factory.django.DjangoModelFactory):
    """Create a fake user."""
    class Meta:
        model = User

    username = factory.Sequence(lambda n: 'user{}'.format(n))
    first_name = fake.first_name()
    last_name = fake.last_name()
    email = fake.email()

class PhotoFactory(factory.django.DjangoModelFactory):
    """Create a fake photo."""
    class Meta:
        model = Photo

    photo = factory.django.ImageField(upload_to='test_photos/%Y-%m-%d')
    title = fake.sentence()
    description = fake.text()
    user = factory.SubFactory(UserFactory)

class AlbumFactory(factory.django.DjangoModelFactory):
    """Create a fake album."""
    class Meta:
        model = Album

    title = fake.sentence()
    description = fake.text()
    user = factory.SubFactory(UserFactory)

class PhotoTestCase(TestCase):
    """Test photos can be created and assigned to users."""
    @classmethod
    def setUp(cls):
        cls.user1 = UserFactory()
        cls.user1.set_password('secret')
        cls.user1.save()
        for i in range(10):
            PhotoFactory(user=cls.user1)

    def tearDown(cls):
        User.objects.all().delete()
        rmtree(settings.MEDIA_TEST)

    def test_photo_creation(self):
        self.assertEqual(Photo.objects.count(), 10)

    def test_photos_belong_to_user(self):
        pic1 = self.user1.photos.first()
        self.assertEqual(self.user1.photos.count(), 10)
        self.assertEqual(self.user1.username, pic1.user.username)

    def test_photo_do_not_belong_to_other_users(self):
        other_user = UserFactory()
        other_user.set_password('moresecret')
        other_user.save()
        self.assertEqual(other_user.photos.count(), 0)

    def test_photo_deletion_on_user_deletion(self):
        self.assertGreater(Photo.objects.count(), 0)
        self.user1.delete()
        self.assertEqual(Photo.objects.count(), 0)

class AlbumTestCase(TestCase):
    """Test albums can be created and assigned to users and albums."""
    @classmethod
    def setUp(cls):
        cls.user1 = UserFactory()
        cls.user1.set_password('secret')
        cls.user1.save()
        cls.album1 = AlbumFactory(user=cls.user1)
        cls.album2 = AlbumFactory(user=cls.user1)
        cls.pics = []
        for i in range(5):
            pic = PhotoFactory(user=cls.user1)
            pic.save()
            cls.pics.append(pic)

    def tearDown(cls):
        User.objects.all().delete()
        rmtree(settings.MEDIA_TEST)

    def test_album_creation(self):
        self.assertEqual(Album.objects.count(), 2)

    def test_albums_belong_to_user(self):
        self.assertEqual(self.user1.albums.count(), 2)
        self.assertEqual(self.user1.username, self.album1.user.username)

    def test_albums_do_not_belong_to_other_users(self):
        other_user = UserFactory()
        other_user.set_password('moresecret')
        other_user.save()
        self.assertEqual(other_user.albums.count(), 0)

    def test_add_photos_to_albums(self):
        self.assertEqual(self.album1.photos.count(), 0)
        self.album1.photos.add(*self.pics[:3])
        self.album2.photos.add(*self.pics[3:])
        self.assertEqual(self.album1.photos.count(), 3)
        self.assertEqual(self.album2.photos.count(), 2)

    def test_set_album_cover_photo(self):
        self.assertIsNone(self.album1.cover)
        self.album1.cover = self.pics[0]
        self.assertIsInstance(self.album1.cover, Photo)

    def test_album_deletion_on_user_deletion(self):
        self.assertGreater(Album.objects.count(), 0)
        self.user1.delete()
        self.assertEqual(Album.objects.count(), 0)

<commit_msg>Clean up PhotoFactory class<commit_after>from __future__ import unicode_literals
from shutil import rmtree

from django.contrib.auth.models import User
from django.conf import settings
from django.test import TestCase
import factory
from faker import Faker

from .models import Album, Photo

fake = Faker()

class UserFactory(factory.django.DjangoModelFactory):
    """Create a fake user."""
    class Meta:
        model = User

    username = factory.Sequence(lambda n: 'user{}'.format(n))
    first_name = fake.first_name()
    last_name = fake.last_name()
    email = fake.email()

class PhotoFactory(factory.django.DjangoModelFactory):
    """Create a fake photo."""
    class Meta:
        model = Photo

    photo = factory.django.ImageField()
    title = fake.sentence()
    description = fake.text()
    user = factory.SubFactory(UserFactory)

class AlbumFactory(factory.django.DjangoModelFactory):
    """Create a fake album."""
    class Meta:
        model = Album

    title = fake.sentence()
    description = fake.text()
    user = factory.SubFactory(UserFactory)

class PhotoTestCase(TestCase):
    """Test photos can be created and assigned to users."""
    @classmethod
    def setUp(cls):
        cls.user1 = UserFactory()
        cls.user1.set_password('secret')
        cls.user1.save()
        for i in range(10):
            PhotoFactory(user=cls.user1)

    def tearDown(cls):
        User.objects.all().delete()
        rmtree(settings.MEDIA_TEST)

    def test_photo_creation(self):
        self.assertEqual(Photo.objects.count(), 10)

    def test_photos_belong_to_user(self):
        pic1 = self.user1.photos.first()
        self.assertEqual(self.user1.photos.count(), 10)
        self.assertEqual(self.user1.username, pic1.user.username)

    def test_photo_do_not_belong_to_other_users(self):
        other_user = UserFactory()
        other_user.set_password('moresecret')
        other_user.save()
        self.assertEqual(other_user.photos.count(), 0)

    def test_photo_deletion_on_user_deletion(self):
        self.assertGreater(Photo.objects.count(), 0)
        self.user1.delete()
        self.assertEqual(Photo.objects.count(), 0)

class AlbumTestCase(TestCase):
    """Test albums can be created and assigned to users and albums."""
    @classmethod
    def setUp(cls):
        cls.user1 = UserFactory()
        cls.user1.set_password('secret')
        cls.user1.save()
        cls.album1 = AlbumFactory(user=cls.user1)
        cls.album2 = AlbumFactory(user=cls.user1)
        cls.pics = []
        for i in range(5):
            pic = PhotoFactory(user=cls.user1)
            pic.save()
            cls.pics.append(pic)

    def tearDown(cls):
        User.objects.all().delete()
        rmtree(settings.MEDIA_TEST)

    def test_album_creation(self):
        self.assertEqual(Album.objects.count(), 2)

    def test_albums_belong_to_user(self):
        self.assertEqual(self.user1.albums.count(), 2)
        self.assertEqual(self.user1.username, self.album1.user.username)

    def test_albums_do_not_belong_to_other_users(self):
        other_user = UserFactory()
        other_user.set_password('moresecret')
        other_user.save()
        self.assertEqual(other_user.albums.count(), 0)

    def test_add_photos_to_albums(self):
        self.assertEqual(self.album1.photos.count(), 0)
        self.album1.photos.add(*self.pics[:3])
        self.album2.photos.add(*self.pics[3:])
        self.assertEqual(self.album1.photos.count(), 3)
        self.assertEqual(self.album2.photos.count(), 2)

    def test_set_album_cover_photo(self):
        self.assertIsNone(self.album1.cover)
        self.album1.cover = self.pics[0]
        self.assertIsInstance(self.album1.cover, Photo)

    def test_album_deletion_on_user_deletion(self):
        self.assertGreater(Album.objects.count(), 0)
        self.user1.delete()
        self.assertEqual(Album.objects.count(), 0)

<|endoftext|>


<commit_before># from django.http import HttpResponseForbidden
from django.shortcuts import redirect
from django.views.generic import TemplateView, CreateView, DeleteView, UpdateView, ListView
from django.urls import reverse_lazy
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin

from imager_images.models import Photos, Albums
from imager_images.forms import AddAlbumForm, AddPhotoForm, EditAlbumForm, EditPhotoForm

# Create your views here.

class LibraryView(LoginRequiredMixin, TemplateView):
    """Class-based view for library page."""

    template_name = "imager_images/library.html"
    login_url = reverse_lazy("login")

    def get_context_data(self):
        """Library view callable, for a user's library page."""
        user = self.request.user
        photos = Photos.objects.all().filter(
            photographer_id=user.profile.id)
        albums = Albums.objects.all().filter(id=user.profile.id)
        return {
            "user": user,
            "photos": photos,
            "albums": albums
        }

class PhotoGalleryView(ListView):
    """Class-based view for user's photo gallery."""

    template_name = "imager_images/photo_gallery.html"
    model = Photos
    queryset = Photos.objects.all().filter(published='PU')

    def get_context_data(self):
        """Photo Gallery view callable, for a user's photo gallery page."""
        photos = Photos.objects.all().filter(published='PU')
        return {"photos": photos}

class PhotoDetailView(TemplateView):
    """Class-based view for individual photos."""

    template_name = "imager_images/photo_detail.html"

    def get_context_data(self, id):
        """Photo Detail view callable, for an individual photo."""
        photo = Photos.objects.get(id=id)
        return {"photo": photo}

class AddPhotoView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """Class-based view for creating photos."""

    model = Photos
    form_class = AddPhotoForm
    template_name = 'imager_images/add_photo.html'
    login_url = reverse_lazy('login')
    permission_required = "imager_images.add_photo"

    def form_valid(self, form):
        photo = form.save()
        photo.photographer = self.request.user.profile
        photo.published_date = timezone.now()
        photo.save()
        return redirect('library')

class EditPhotoView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """Class-based view for editing photos."""

    model = Photos
    form_class = EditPhotoForm
    template_name = 'imager_images/edit_photo.html'
    login_url = reverse_lazy('login')
    permission_required = 'imager_images.edit_photo'
    success_url = reverse_lazy('library')

class RemovePhotoView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """Delete a photo."""

    template_name = "imager_images/remove_photo.html"
    model = Photos
    login_url = reverse_lazy("login")
    permission_required = [
        "imager_images.add_photo, imager_images.remove_photo"]

    def delete(self, request, pk=None):
        self.photo = Photos.objects.get(pk=pk)
        self.photo.delete()
        return redirect('photo_gallery')

class AlbumGalleryView(ListView):
    """Class-based view for user's album gallery."""

    template_name = "imager_images/album_gallery.html"
    model = Albums
    queryset = albums = Albums.objects.all().filter(published='PU')

    def get_context_data(self):
        """Album Gallery view callable, for a user's albums page"""
        albums = Albums.objects.all().filter(published='PU')
        return {"albums": albums}

class AlbumDetailView(TemplateView):
    """Class-based view for individual albums."""

    template_name = "imager_images/album_detail.html"

    def get_context_data(self, id):
        """Album Detail view callable, for an individual album."""
        album = Albums.objects.all().filter(id=id).first()
        photos = Photos.objects.filter(album__id=id)
        return {"album": album, "photos": photos}

class AddAlbumView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """Class-based view for creating albums."""

    # login_required = True
    model = Albums
    form_class = AddAlbumForm
    template_name = 'imager_images/add_album.html'
    login_url = reverse_lazy('login')
    permission_required = "imager_images.add_album"

    def form_valid(self, form):
        album = form.save()
        album.photographer = self.request.user.profile
        album.published_date = timezone.now()
        album.save()
        return redirect('library')

class RemoveAlbumView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """Delete a photo."""

    template_name = "imager_images/remove_album.html"
    model = Albums
    login_url = reverse_lazy("login")
    permission_required = [
        "imager_images.add_album, imager_images.remove_album"]

    def delete(self, request, pk=None):
        self.album = Albums.objects.get(pk=pk)
        self.album.delete()
        return redirect('album_gallery')

class EditAlbumView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """Class-based view for editing albums."""

    model = Albums
    form_class = EditAlbumForm
    template_name = 'imager_images/edit_album.html'
    login_url = reverse_lazy('login')
    permission_required = "imager_images.edit_album.html"
    success_url = reverse_lazy('library')
<commit_msg>updating views.py to incorporate tag view<commit_after># from django.http import HttpResponseForbidden
from django.shortcuts import redirect
from django.views.generic import TemplateView, CreateView, DeleteView, UpdateView, ListView
from django.urls import reverse_lazy
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin

from imager_images.models import Photos, Albums
from imager_images.forms import AddAlbumForm, AddPhotoForm, EditAlbumForm, EditPhotoForm

# Create your views here.

class LibraryView(LoginRequiredMixin, TemplateView):
    """Class-based view for library page."""

    template_name = "imager_images/library.html"
    login_url = reverse_lazy("login")

    def get_context_data(self):
        """Library view callable, for a user's library page."""
        user = self.request.user
        photos = Photos.objects.all().filter(
            photographer_id=user.profile.id)
        albums = Albums.objects.all().filter(id=user.profile.id)
        return {
            "user": user,
            "photos": photos,
            "albums": albums
        }

class PhotoGalleryView(ListView):
    """Class-based view for user's photo gallery."""

    template_name = "imager_images/photo_gallery.html"
    model = Photos
    queryset = Photos.objects.all().filter(published='PU')

    def get_context_data(self):
        """Photo Gallery view callable, for a user's photo gallery page."""
        photos = Photos.objects.all().filter(published='PU')
        return {"photos": photos}

class TagListView(ListView):
    """The listing for tagged books."""
    template_name = "imager_images/photo_gallery.html"

    def get_queryset(self):
        return Photos.objects.filter(tags__slug=self.kwargs.get("slug")).all()

    def get_context_data(self, **kwargs):
        context = super(TagListView, self).get_context_data(**kwargs)
        context["tag"] = self.kwargs.get("slug")
        return context

class PhotoDetailView(TemplateView):
    """Class-based view for individual photos."""

    template_name = "imager_images/photo_detail.html"

    def get_context_data(self, id):
        """Photo Detail view callable, for an individual photo."""
        photo = Photos.objects.get(id=id)
        return {"photo": photo}

class AddPhotoView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """Class-based view for creating photos."""

    model = Photos
    form_class = AddPhotoForm
    template_name = 'imager_images/add_photo.html'
    login_url = reverse_lazy('login')
    permission_required = "imager_images.add_photo"

    def form_valid(self, form):
        photo = form.save()
        photo.photographer = self.request.user.profile
        photo.published_date = timezone.now()
        photo.save()
        return redirect('library')

class EditPhotoView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """Class-based view for editing photos."""

    model = Photos
    form_class = EditPhotoForm
    template_name = 'imager_images/edit_photo.html'
    login_url = reverse_lazy('login')
    permission_required = 'imager_images.edit_photo'
    success_url = reverse_lazy('library')

class RemovePhotoView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """Delete a photo."""

    template_name = "imager_images/remove_photo.html"
    model = Photos
    login_url = reverse_lazy("login")
    permission_required = [
        "imager_images.add_photo, imager_images.remove_photo"]

    def delete(self, request, pk=None):
        self.photo = Photos.objects.get(pk=pk)
        self.photo.delete()
        return redirect('photo_gallery')

class AlbumGalleryView(ListView):
    """Class-based view for user's album gallery."""

    template_name = "imager_images/album_gallery.html"
    model = Albums
    queryset = albums = Albums.objects.all().filter(published='PU')

    def get_context_data(self):
        """Album Gallery view callable, for a user's albums page"""
        albums = Albums.objects.all().filter(published='PU')
        return {"albums": albums}

class AlbumDetailView(TemplateView):
    """Class-based view for individual albums."""

    template_name = "imager_images/album_detail.html"

    def get_context_data(self, id):
        """Album Detail view callable, for an individual album."""
        album = Albums.objects.all().filter(id=id).first()
        photos = Photos.objects.filter(album__id=id)
        return {"album": album, "photos": photos}

class AddAlbumView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """Class-based view for creating albums."""

    # login_required = True
    model = Albums
    form_class = AddAlbumForm
    template_name = 'imager_images/add_album.html'
    login_url = reverse_lazy('login')
    permission_required = "imager_images.add_album"

    def form_valid(self, form):
        album = form.save()
        album.photographer = self.request.user.profile
        album.published_date = timezone.now()
        album.save()
        return redirect('library')

class RemoveAlbumView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """Delete a photo."""

    template_name = "imager_images/remove_album.html"
    model = Albums
    login_url = reverse_lazy("login")
    permission_required = [
        "imager_images.add_album, imager_images.remove_album"]

    def delete(self, request, pk=None):
        self.album = Albums.objects.get(pk=pk)
        self.album.delete()
        return redirect('album_gallery')

class EditAlbumView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """Class-based view for editing albums."""

    model = Albums
    form_class = EditAlbumForm
    template_name = 'imager_images/edit_album.html'
    login_url = reverse_lazy('login')
    permission_required = "imager_images.edit_album.html"
    success_url = reverse_lazy('library')
<|endoftext|>


<commit_before>"""
Django settings for imagersite project.

Generated by 'django-admin startproject' using Django 1.8.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# Media File Handling
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# STATICFILES_DIRS = (STATIC_ROOT,)

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '!syrw2^^&&f)64%yu3mb041ij$&z2=livnhz^*2zik!b=_e6-o'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'imager_profile',
    'imager_images',
    'bootstrap3',
    'registration',
    'sorl.thumbnail'
)

SITE_ID = 1
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
ACCOUNT_ACTIVATION_DAYS = 7
LOGIN_REDIRECT_URL = '/profile/'
ROOT_URLCONF = 'imagersite.urls'

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            'imager_images',
            'imager_profile',
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'imagersite.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True
<commit_msg>Update settings.py template paths<commit_after>"""
Django settings for imagersite project.

Generated by 'django-admin startproject' using Django 1.8.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# Media File Handling
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# STATICFILES_DIRS = (STATIC_ROOT,)

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '!syrw2^^&&f)64%yu3mb041ij$&z2=livnhz^*2zik!b=_e6-o'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'imager_profile',
    'imager_images',
    'bootstrap3',
    'registration',
    'sorl.thumbnail'
)

SITE_ID = 1
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
ACCOUNT_ACTIVATION_DAYS = 7
LOGIN_REDIRECT_URL = '/profile/'
ROOT_URLCONF = 'imagersite.urls'

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'imager_images/templates'),
            os.path.join(BASE_DIR, 'imager_profile'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'imagersite.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True
<|endoftext|>


<commit_before>
from Queue import Empty, Queue
from time import time
import logging
import shelve
import signal
import optparse

from gevent import monkey, spawn, sleep
from gevent.pool import Pool

#monkey.patch_all(httplib=True)

from circuits import Component, Event
from circuits.core.handlers import HandlerMetaClass
from circuits.app.config import Config as _Config

from circuits import Debugger

Config = HandlerMetaClass('Config', (_Config,), _Config.__dict__.copy())

from arke.collect import Collect
from arke.plugin import CollectPlugins
from arke.persist import Persist

RETRY_INTERVAL_CAP = 300
DEFAULT_CONFIG_FILE = '/etc/arke/arke.conf'

def argparser():
    p = optparse.OptionParser()
    p.add_option('-c', dest='config_filename',
                 action='store', default=DEFAULT_CONFIG_FILE,
                 help='Specify alternate configuration file name')
    p.add_option('-d', '--daemonize', dest='daemonize',
                 action='store_true', default=False,
                 help='Run in the foreground')
    options, args = p.parse_args()

class Agent(Component):
    section = 'agent'
    def __init__(self, config_file=DEFAULT_CONFIG_FILE):
        super(Agent, self).__init__()

        self.config = Config(config_file).register(self)
        self.config.load()

        self.collect_manager = CollectPlugins(base_class=Collect,
                                             entry_points='arke_plugins',
                                            ).register(self)
        self.persist_manager = Persist(1).register(self)

    def exception(self, *args, **kwargs):
        from pprint import pprint
        pprint(args)
        pprint(kwargs)
        raise SystemExit

    def started(self, *args):
        self.collect_manager.load()

if __name__ == '__main__':
    mylogger = logging.getLogger()
    mylogger.setLevel(logging.DEBUG)
    h = logging.StreamHandler()
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    h.setFormatter(formatter)
    mylogger.addHandler(h)

    import sys

    (Agent(sys.argv[1]) + Debugger()).run()

class NoPlugins(Exception): pass

Daemon = object
class agent_daemon(Daemon):
    default_conf = '/etc/arke/arke.conf'
    section = 'agent'

    def read_basic_config(self):
        super(agent_daemon, self).read_basic_config()
        self.hostname = self.config_parser.get('core', 'hostname')
        config.set_main_object(self)

    def __init__(self):
        self.run_queue = Queue()
        self.persist_queue = Queue()
        self.spool = None
        self.stop_now = False

    def on_sighup(self, signalnum, frame):
        logging.info("got sighup")
        self.config_parser.read(self.default_conf)
        self.load_plugins()

    def on_sigterm(self, signalnum, frame):
        logging.info("got sigterm")
        self.stop_now = True

    def add_signal_handlers(self):
        super(self.__class__, self).add_signal_handlers()
        signal.signal(signal.SIGHUP, self.on_sighup)
        signal.signal(signal.SIGINT, self.on_sigterm)

    def run(self):
        logging.debug("initializing spool")
        self.spool = shelve.open(
            self.config_parser.get('core', 'spool_file'))

        self.load_plugins()
        gather_runner = spawn(self.gather_runner)
        persist_runner = spawn(self.persist_runner)

        while 1:
            if self.stop_now and gather_runner.dead and persist_runner.dead:
                break
            sleep(5)

        self.spool.close()

    def load_plugins(self):
        plugin_dirs = self.config_parser.get('core', 'plugin_dirs')
        plugin_dirs = plugin_dirs.replace(',', ' ')
        plugin_dirs = plugin_dirs.split()

        logging.debug("initializing plugin subsystem")
        self.plugin_manager = get_plugin_manager(plugin_dirs)

        no_plugins_activated = True
        for plugin in self.plugin_manager.collection_plugins:
            if not plugin.enabled:
                if plugin.is_activated:
                    logging.info(("active plugin %s is no longer enabled "
                                  "- deactivating.") % plugin.name)
                    plugin.deactivate()
                else:
                    logging.debug(("discovered plugin %s is not enabled. "
                               "skipping activation") % plugin.name)
                continue

            logging.info("activating plugin %s" % plugin.name)
            if not plugin.is_activated:
                plugin.activate()
            no_plugins_activated = False

        if no_plugins_activated:
            raise NoPlugins("No plugins found or enabled.")

    def gather_runner(self):
        pool = Pool(1000)

        while 1:
            if self.stop_now:
                break
            try:
                plugin = self.run_queue.get(True, 5)
            except Empty:
                sleep(1)
                continue

            pool.spawn(self.gather_data, plugin, self.spool)

    def persist_runner(self):
        logging.debug("initializing backend %s" % self.config_parser.get('core', 'persist_backend'))
        persist_backend = getattr(persist, '%s_backend' %
                self.config_parser.get('core', 'persist_backend'))
        persist_backend = persist_backend(config.get_config())

        if self.spool:
            logging.info("found data already in spool. adding to queue")
            for key in self.spool:
                self.persist_queue.put(key)

        pool = Pool(100)

        while 1:
            if self.stop_now:
                break
            try:
                item = self.persist_queue.get(True, 5)
            except Empty:
                sleep(1)
                continue

            pool.spawn(self.persist_data, item, self.spool, persist_backend)

    def gather_data(self, plugin, spool):
        timestamp = time()
        sourcetype = plugin.name
        #key needs to be generated before we normalize
        key = '%f%s' % (timestamp, sourcetype)
        extra = {}

        if plugin.timestamp_as_id:
            #if the timestamp is going to be used as the id, then
            #that means we're going to group multiple results into
            #the same document. round the timestamp in order to ensure
            #we catch everything.
            offset = timestamp % plugin.get_setting('interval')
            timestamp = timestamp - offset
            extra['timestamp_as_id'] = True

        if plugin.custom_schema:
            extra['custom_schema'] = True

        if plugin.format:
            extra['ctype'] = plugin.format.lower()

        logging.debug("gathering data for %s sourcetype" % sourcetype)
        try:
            data = plugin()
        except Exception, e:
            logging.exception("error occurred while gathering data for sourcetype %s" % sourcetype)
            raise e

        spool[key] = (sourcetype, timestamp, data, extra)

        self.persist_queue.put(key)

    def persist_data(self, key, spool, persist_backend):
        (sourcetype, timestamp, data, extra) = spool[key]
        logging.debug("persisting data for %s sourcetype" % sourcetype)

        attempt = 1
        retry = .2
        while 1:
            try:
                persist_backend.write(sourcetype, timestamp, data, self.hostname, extra)
            except Exception:
                logging.exception("attempt %s trying to persist %s data. spool key: %s" % (attempt, sourcetype, key))
            else:
                break

            sleep(retry)
            if retry < RETRY_INTERVAL_CAP:
                retry = attempt * 2
            attempt += 1

        spool.pop(key)

#if __name__ == '__main__':
    #agent_daemon().main()

<commit_msg>throw away the Agent circuits component<commit_after>
from Queue import Empty, Queue
import logging
import signal

from simpledaemon import Daemon
from gevent import monkey, spawn, sleep
from gevent.pool import Pool

monkey.patch_all(httplib=True)

from arke.collect import Collect
from arke.plugin import CollectPlugins
from arke.spool import Spooler
from arke.plugins import persist

RETRY_INTERVAL_CAP = 300
DEFAULT_CONFIG_FILE = '/etc/arke/arke.conf'

class NoPlugins(Exception): pass

class agent_daemon(Daemon):
    default_conf = '/etc/arke/arke.conf'
    section = 'agent'

    def read_basic_config(self):
        super(agent_daemon, self).read_basic_config()
        self.hostname = self.config_parser.get('core', 'hostname')
        config.set_main_object(self)

    def __init__(self):
        self.run_queue = Queue()
        self.persist_queue = Queue()
        self.spool = None
        self.stop_now = False

    def on_sighup(self, signalnum, frame):
        logging.info("got sighup")
        self.config_parser.read(self.default_conf)
        self.load_plugins()

    def on_sigterm(self, signalnum, frame):
        logging.info("got sigterm")
        self.stop_now = True

    def add_signal_handlers(self):
        super(self.__class__, self).add_signal_handlers()
        signal.signal(signal.SIGHUP, self.on_sighup)
        signal.signal(signal.SIGINT, self.on_sigterm)

    def run(self):
        logging.debug("initializing spool")
        self.spool = shelve.open(
            self.config_parser.get('core', 'spool_file'))

        self.load_plugins()
        gather_runner = spawn(self.gather_runner)
        persist_runner = spawn(self.persist_runner)

        while 1:
            if self.stop_now and gather_runner.dead and persist_runner.dead:
                break
            sleep(5)

        self.spool.close()

    def load_plugins(self):
        plugin_dirs = self.config_parser.get('core', 'plugin_dirs')
        plugin_dirs = plugin_dirs.replace(',', ' ')
        plugin_dirs = plugin_dirs.split()

        logging.debug("initializing plugin subsystem")
        self.plugin_manager = get_plugin_manager(plugin_dirs)

        no_plugins_activated = True
        for plugin in self.plugin_manager.collection_plugins:
            if not plugin.enabled:
                if plugin.is_activated:
                    logging.info(("active plugin %s is no longer enabled "
                                  "- deactivating.") % plugin.name)
                    plugin.deactivate()
                else:
                    logging.debug(("discovered plugin %s is not enabled. "
                               "skipping activation") % plugin.name)
                continue

            logging.info("activating plugin %s" % plugin.name)
            if not plugin.is_activated:
                plugin.activate()
            no_plugins_activated = False

        if no_plugins_activated:
            raise NoPlugins("No plugins found or enabled.")

    def gather_runner(self):
        pool = Pool(1000)

        while 1:
            if self.stop_now:
                break
            try:
                plugin = self.run_queue.get(True, 5)
            except Empty:
                sleep(1)
                continue

            pool.spawn(self.gather_data, plugin, self.spool)

    def persist_runner(self):
        logging.debug("initializing backend %s" % self.config_parser.get('core', 'persist_backend'))
        persist_backend = getattr(persist, '%s_backend' %
                self.config_parser.get('core', 'persist_backend'))
        persist_backend = persist_backend(config.get_config())

        if self.spool:
            logging.info("found data already in spool. adding to queue")
            for key in self.spool:
                self.persist_queue.put(key)

        pool = Pool(100)

        while 1:
            if self.stop_now:
                break
            try:
                item = self.persist_queue.get(True, 5)
            except Empty:
                sleep(1)
                continue

            pool.spawn(self.persist_data, item, self.spool, persist_backend)

    def gather_data(self, plugin, spool):
        timestamp = time()
        sourcetype = plugin.name
        #key needs to be generated before we normalize
        key = '%f%s' % (timestamp, sourcetype)
        extra = {}

        if plugin.timestamp_as_id:
            #if the timestamp is going to be used as the id, then
            #that means we're going to group multiple results into
            #the same document. round the timestamp in order to ensure
            #we catch everything.
            offset = timestamp % plugin.get_setting('interval')
            timestamp = timestamp - offset
            extra['timestamp_as_id'] = True

        if plugin.custom_schema:
            extra['custom_schema'] = True

        if plugin.format:
            extra['ctype'] = plugin.format.lower()

        logging.debug("gathering data for %s sourcetype" % sourcetype)
        try:
            data = plugin()
        except Exception, e:
            logging.exception("error occurred while gathering data for sourcetype %s" % sourcetype)
            raise e

        spool[key] = (sourcetype, timestamp, data, extra)

        self.persist_queue.put(key)

    def persist_data(self, key, spool, persist_backend):
        (sourcetype, timestamp, data, extra) = spool[key]
        logging.debug("persisting data for %s sourcetype" % sourcetype)

        attempt = 1
        retry = .2
        while 1:
            try:
                persist_backend.write(sourcetype, timestamp, data, self.hostname, extra)
            except Exception:
                logging.exception("attempt %s trying to persist %s data. spool key: %s" % (attempt, sourcetype, key))
            else:
                break

            sleep(retry)
            if retry < RETRY_INTERVAL_CAP:
                retry = attempt * 2
            attempt += 1

        spool.pop(key)

#if __name__ == '__main__':
    #agent_daemon().main()

<|endoftext|>


<commit_before># coding: utf-8

from objc_util import *
import ui

load_framework('ARKit')

SCNView, SCNScene, SCNNode, SCNLookAtConstraint = map(ObjCClass, ['SCNView', 'SCNScene', 'SCNNode', 'SCNLookAtConstraint'])

ARWorldTrackingSessionConfiguration, ARSessionConfiguration, ARSession = map(ObjCClass,['ARWorldTrackingSessionConfiguration','ARSessionConfiguration','ARSession'])

def renderer_didAdd_for_(_self, _cmd, renderer, node, anchor):
    pass

methods = [renderer_didAdd_for_]
protocols = ['ARSCNViewDelegate']
MyARKitDelegate = create_objc_class('MyARKitDelegate', NSObject, methods=methods, protocols=protocols)

dragonNode = SCNNode.node()

def loadDragon():
    global dragonNode
    dragonScene = SCNScene.sceneNamed_("assets/dragon/dragon.scn")
    dragonNode = dragonScene.rootNode.childNodeWithName_recursively_("dragon", True)

@on_main_thread
def main():
    if ARWorldTrackingSessionConfiguration.isSupported:
        configuration = ARWorldTrackingSessionConfiguration.alloc()
    else:
        configuration = ARSessionConfiguration.alloc()

    arSession = ARSession.alloc()

    arSession.delegate = MyARKitDelegate.alloc().init()

    main_view = ui.View()
    main_view_objc = ObjCInstance(main_view)
    scene_view = SCNView.alloc().initWithFrame_options_(((0,0),(400, 400)), None).autorelease()
    scene_view.setAutoresizingMask_(18)
    scene_view.setAllowsCameraControl_(True)
    main_view_objc.addSubview_(scene_view)
    main_view.name = 'ARKit Demo'

    scene = SCNScene.sceneNamed_("assets/dragon/main.scn")
    scene_view.setScene_(scene)

    loadDragon()

    main_view.present()

if __name__ == '__main__':
    main()
<commit_msg>add the arkit camera stream functionality<commit_after># coding: utf-8

from objc_util import *
import ui
import os
import sys
#from myDebugToolKit import *

load_framework('SceneKit')
load_framework('ARKit')

# Some 'constants' used by ARkit
# But i can't transfer them to the ARKit framework, why ?????
ARWorldAlignmentGravity = 0
ARWorldAlignmentGravityAndHeading = 1
ARWorldAlignmentCamera = 2

ARPlaneDetectionNone = 0
ARPlaneDetectionHorizontal = 1 << 0
ARPlaneDetectionVertical = 1 << 1

ARSCNDebugOptionNone = 0
ARSCNDebugOptionShowWorldOrigin = 1 << 0
ARSCNDebugOptionShowFeaturePoints = 1 << 1

SCNScene = ObjCClass('SCNScene')
ARSCNView = ObjCClass('ARSCNView')
ARWorldTrackingConfiguration = ObjCClass('ARWorldTrackingConfiguration')
ARSession = ObjCClass('ARSession')
UIViewController = ObjCClass('UIViewController')
ARPlaneAnchor = ObjCClass('ARPlaneAnchor')

# I should refactor te following line in a class but I need to learn more the create_objcc_class function
sceneview = None

# Here two little set up functions used by the main class
def createSampleScene():
    # an empty scene
    scene = SCNScene.scene()
    return scene

def createARSceneView(x, y, w, h, debug=True):
    v = ARSCNView.alloc().initWithFrame_((CGRect(CGPoint(x, y), CGSize(w, h))))
    v.setShowsStatistics_(debug)
    # Problem here... feature points are not shown.... despite the method call
    v.setDebugOptions_(ARSCNDebugOptionShowWorldOrigin |ARSCNDebugOptionShowFeaturePoints)
    return v

# Some callback definitions used by create_objc_class
def CustomViewController_touchesBegan_withEvent_(_self, _cmd, _touches, event):
    touches = ObjCInstance(_touches)
    for t in touches:
        loc = t.locationInView_(sceneview)
        sz = ui.get_screen_size()
        print(loc)

def CustomViewController_viewWillAppear_(_self, _cmd, animated):
    configuration = ARWorldTrackingConfiguration.alloc().init()
    # Another problem here...constants aren't well communicated... (my assumption...)
    configuration.setPlaneDetection_ (ARPlaneDetectionHorizontal)
    configuration.setWorldAlignment_(ARWorldAlignmentGravityAndHeading)

    session = sceneview.session()
    session.runWithConfiguration_(configuration)

def CustomViewController_viewWillDisappear_(_self, _cmd, animated):
    session = sceneview.session()
    session.pause()

def MyARSCNViewDelegate_renderer_didAdd_for_(_self, _cmd, scenerenderer, node, anchor):
    if not isinstance(anchor, (ARPlaneAnchor)):
        return
    # to be implemented...

# The main class...
class MyARView(ui.View):
    def __init__(self):
        global sceneview
        self.flex = 'WH'

        screen = ui.get_screen_size()

        # set up the scene
        scene = createSampleScene()

        # set up the ar scene view delegate
        methods = [MyARSCNViewDelegate_renderer_didAdd_for_]
        protocols = ['ARSCNViewDelegate']
        MyARSCNViewDelegate = create_objc_class('MyARSCNViewDelegate', NSObject, methods=methods, protocols=protocols)
        delegate = MyARSCNViewDelegate.alloc().init()

        # set up the ar scene view
        sceneview = createARSceneView(0, 0, screen.width, screen.height)
        sceneview.scene = scene
        sceneview.delegate = delegate

        # set up the custom view controller
        methods = [CustomViewController_touchesBegan_withEvent_,            CustomViewController_viewWillAppear_, CustomViewController_viewWillDisappear_]
        protocols = []
        CustomViewController = create_objc_class('CustomViewController', UIViewController, methods=methods, protocols=protocols)
        cvc = CustomViewController.new().init().autorelease()
        cvc.view = sceneview

        # last set up
        self_objc = ObjCInstance(self)
        self_objc.addSubview_(sceneview)

        # workaround : I need to call manually viewWillAppear as otherwise my callback is not called...
        cvc.viewWillAppear_(False)

    def will_close(self):
        session = sceneview.session()
        session.pause()

@on_main_thread
def main():
    v = MyARView()
    v.present('full_screen', hide_title_bar=True)

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