<commit_before>import os
import sys
import asyncio
import pymongo
import traceback

import virtool.utils

LIST_PROJECTION = [
    "_id",
    "task",
    "status",
    "proc",
    "mem",
    "user"
]

def dispatch_processor(document):
    """
    Removes the ``status`` and ``args`` fields from the job document.
    Adds a ``username`` field, an ``added`` date taken from the first status entry in the job document, and
    ``state`` and ``progress`` fields taken from the most recent status entry in the job document.
    :param document: a document to process.
    :type document: dict

    :return: a processed documents.
    :rtype: dict
    """
    document = virtool.utils.base_processor(document)

    status = document.pop("status")

    last_update = status[-1]

    document.update({
        "state": last_update["state"],
        "stage": last_update["stage"],
        "created_at": status[0]["timestamp"],
        "progress": status[-1]["progress"]
    })

    return document

class Job:

    def __init__(self, loop, executor, db, settings, dispatch, job_id, task_name, task_args, proc, mem):
        self.loop = loop
        self.executor = executor
        self.db = db
        self.settings = settings
        self.dispatch = dispatch
        self.id = job_id
        self.task_name = task_name
        self.task_args = task_args
        self.proc = proc
        self.mem = mem

        self.started = False
        self.finished = False

        self._progress = 0
        self._state = "waiting"
        self._stage = None
        self._error = None
        self._cancelled = False
        self._task = None
        self._process_task = None
        self._stage_list = None
        self._log_path = os.path.join(self.settings.get("data_path"), "logs", "jobs", self.id)
        self._log_buffer = list()

    def start(self):
        self._task = self.loop.create_task(self.run())
        self.started = True

    async def run(self):
        for method in self._stage_list:
            name = method.__name__

            await self.add_status(stage=name, state="running")

            try:
                await self.add_log("Stage: {}".format(name))
                await method()
            except asyncio.CancelledError:
                self._cancelled = True
            except:
                self._error = handle_exception()

            if self._error or self._cancelled:
                break

        self._progress = 1

        if self._error:
            await self.add_status(state="error")
            await self.cleanup()
        elif self._cancelled:
            await self.add_status(state="cancelled")
            await self.cleanup()
        else:
            await self.add_status(state="complete")

        await self.run_in_executor(flush_log, self._log_path, self._log_buffer)

        self.finished = True

    async def run_in_executor(self, func, *args):
        await self.add_log("Process: {}".format(func.__name__))
        self._process_task = self.loop.run_in_executor(self.executor, func, *args)
        result = await self._process_task
        self._process_task = None

        return result

    async def run_subprocess(self, command, error_test=None, stdout_handler=None, stderr_handler=None, env=None):
        await self.add_log("Command: {}".format(" ".join(command)))

        stdout = asyncio.subprocess.PIPE if stdout_handler else asyncio.subprocess.DEVNULL
        stderr = asyncio.subprocess.PIPE if stderr_handler else asyncio.subprocess.DEVNULL

        proc = await asyncio.create_subprocess_exec(
            *command,
            stdout=stdout,
            stderr=stderr,
            loop=self.loop,
            env=env
        )

        waits = []

        if stdout_handler:
            waits.append(read_stream(proc.stdout, stdout_handler))

        if stderr_handler:
            waits.append(read_stream(proc.stderr, stderr_handler))

        if len(waits):
            await asyncio.wait(waits)
        else:
            await proc.communicate()

        await proc.wait()

        if proc.returncode != 0: # or (error_test and error_test(out, err)):
            raise SubprocessError("Command failed: {}. Check job log.".format(" ".join(command)))

    async def add_status(self, state=None, stage=None):
        self._state = state or self._state
        self._stage = stage or self._stage

        if self._progress != 1:
            stage_index = [m.__name__ for m in self._stage_list].index(self._stage)
            self._progress = round((stage_index + 1) / (len(self._stage_list) + 1), 2)

        document = await self.db.jobs.find_one_and_update({"_id": self.id}, {
            "$push": {
                "status": {
                    "state": self._state,
                    "stage": self._stage,
                    "error": self._error,
                    "progress": self._progress,
                    "timestamp": virtool.utils.timestamp()
                }
            }
        }, return_document=pymongo.ReturnDocument.AFTER, projection=LIST_PROJECTION)

        await self.dispatch("jobs", "update", dispatch_processor(document))

    async def add_log(self, line, indent=0):
        timestamp = virtool.utils.timestamp().isoformat()

        self._log_buffer.append("{}{}    {}".format(timestamp, " " * indent * 4, line.rstrip()))

        if len(self._log_buffer) == 15:
            await self.flush_log()
            del self._log_buffer[:]

    async def flush_log(self):
        await self.run_in_executor(flush_log, self._log_path, self._log_buffer)

    async def cancel(self):
        if self.started and not self.finished:
            self._task.cancel()

            while not self.finished:
                await asyncio.sleep(0.1, loop=self.loop)

        await self.cleanup()

        self.finished = True

    async def cleanup(self):
        pass

def stage_method(func):
    func.is_stage_method = True
    return func

async def read_stream(stream, cb):
    while True:
        line = await stream.readline()

        if line:
            cb(line)
        else:
            break

def flush_log(path, buffer):
    with open(path, "a") as handle:
        handle.write("\n".join(buffer))

def handle_exception(max_tb=50):
    exception, value, trace_info = sys.exc_info()

    return {
        "type": exception.__name__,
        "traceback": traceback.format_tb(trace_info, max_tb),
        "details": [str(l) for l in value.args]
    }

class SubprocessError(Exception):
    pass
<commit_msg>Allow for sync and async stdout handlers in run_subprocess<commit_after>import os
import sys
import asyncio
import pymongo
import inspect
import traceback

import virtool.utils

LIST_PROJECTION = [
    "_id",
    "task",
    "status",
    "proc",
    "mem",
    "user"
]

def dispatch_processor(document):
    """
    Removes the ``status`` and ``args`` fields from the job document.
    Adds a ``username`` field, an ``added`` date taken from the first status entry in the job document, and
    ``state`` and ``progress`` fields taken from the most recent status entry in the job document.
    :param document: a document to process.
    :type document: dict

    :return: a processed documents.
    :rtype: dict
    """
    document = virtool.utils.base_processor(document)

    status = document.pop("status")

    last_update = status[-1]

    document.update({
        "state": last_update["state"],
        "stage": last_update["stage"],
        "created_at": status[0]["timestamp"],
        "progress": status[-1]["progress"]
    })

    return document

class Job:

    def __init__(self, loop, executor, db, settings, dispatch, job_id, task_name, task_args, proc, mem):
        self.loop = loop
        self.executor = executor
        self.db = db
        self.settings = settings
        self.dispatch = dispatch
        self.id = job_id
        self.task_name = task_name
        self.task_args = task_args
        self.proc = proc
        self.mem = mem

        self.started = False
        self.finished = False

        self._progress = 0
        self._state = "waiting"
        self._stage = None
        self._error = None
        self._cancelled = False
        self._task = None
        self._process_task = None
        self._stage_list = None
        self._log_path = os.path.join(self.settings.get("data_path"), "logs", "jobs", self.id)
        self._log_buffer = list()

    def start(self):
        self._task = self.loop.create_task(self.run())
        self.started = True

    async def run(self):
        for method in self._stage_list:
            name = method.__name__

            await self.add_status(stage=name, state="running")

            try:
                await self.add_log("Stage: {}".format(name))
                await method()
            except asyncio.CancelledError:
                self._cancelled = True
            except:
                self._error = handle_exception()

            if self._error or self._cancelled:
                break

        self._progress = 1

        if self._error:
            await self.add_status(state="error")
            await self.cleanup()
        elif self._cancelled:
            await self.add_status(state="cancelled")
            await self.cleanup()
        else:
            await self.add_status(state="complete")

        await self.run_in_executor(flush_log, self._log_path, self._log_buffer)

        self.finished = True

    async def run_in_executor(self, func, *args):
        await self.add_log("Process: {}".format(func.__name__))
        self._process_task = self.loop.run_in_executor(self.executor, func, *args)
        result = await self._process_task
        self._process_task = None

        return result

    async def run_subprocess(self, command, error_test=None, stdout_handler=None, stderr_handler=None, env=None):
        await self.add_log("Command: {}".format(" ".join(command)))

        waits = []

        _stdout_handler = None
        _stderr_handler = None

        if stdout_handler:
            stdout = asyncio.subprocess.PIPE

            if not inspect.iscoroutinefunction(stdout_handler):
                def _stdout_handler(*args, **kwargs):
                    return stdout_handler(*args, **kwargs)
            else:
                _stdout_handler = stdout_handler
        else:
            stdout = asyncio.subprocess.DEVNULL

        if stderr_handler:
            stderr = asyncio.subprocess.PIPE

            if not inspect.iscoroutinefunction(stderr_handler):
                def _stderr_handler(*args, **kwargs):
                    return stderr_handler(*args, **kwargs)
            else:
                _stderr_handler = stderr_handler
        else:
            stderr = asyncio.subprocess.DEVNULL

        child_watcher = asyncio.get_child_watcher()
        child_watcher.attach_loop(self.loop)

        proc = await asyncio.create_subprocess_exec(
            *command,
            stdout=stdout,
            stderr=stderr,
            loop=self.loop,
            env=env
        )

        if _stdout_handler:
            waits.append(read_stream(proc.stdout, _stdout_handler))

        if _stderr_handler:
            waits.append(read_stream(proc.stderr, _stderr_handler))

        if len(waits):
            await asyncio.wait(waits)
        else:
            await proc.communicate()

        await proc.wait()

        if proc.returncode != 0: # or (error_test and error_test(out, err)):
            raise SubprocessError("Command failed: {}. Check job log.".format(" ".join(command)))

    async def add_status(self, state=None, stage=None):
        self._state = state or self._state
        self._stage = stage or self._stage

        if self._progress != 1:
            stage_index = [m.__name__ for m in self._stage_list].index(self._stage)
            self._progress = round((stage_index + 1) / (len(self._stage_list) + 1), 2)

        document = await self.db.jobs.find_one_and_update({"_id": self.id}, {
            "$push": {
                "status": {
                    "state": self._state,
                    "stage": self._stage,
                    "error": self._error,
                    "progress": self._progress,
                    "timestamp": virtool.utils.timestamp()
                }
            }
        }, return_document=pymongo.ReturnDocument.AFTER, projection=LIST_PROJECTION)

        await self.dispatch("jobs", "update", dispatch_processor(document))

    async def add_log(self, line, indent=0):
        timestamp = virtool.utils.timestamp().isoformat()

        self._log_buffer.append("{}{}    {}".format(timestamp, " " * indent * 4, line.rstrip()))

        if len(self._log_buffer) == 15:
            await self.flush_log()
            del self._log_buffer[:]

    async def flush_log(self):
        await self.run_in_executor(flush_log, self._log_path, self._log_buffer)

    async def cancel(self):
        if self.started and not self.finished:
            self._task.cancel()

            while not self.finished:
                await asyncio.sleep(0.1, loop=self.loop)

        await self.cleanup()

        self.finished = True

    async def cleanup(self):
        pass

def stage_method(func):
    func.is_stage_method = True
    return func

async def read_stream(stream, cb):
    while True:
        line = await stream.readline()

        if line:
            await cb(line)
        else:
            break

def flush_log(path, buffer):
    with open(path, "a") as handle:
        handle.write("\n".join(buffer))

def handle_exception(max_tb=50):
    exception, value, trace_info = sys.exc_info()

    return {
        "type": exception.__name__,
        "traceback": traceback.format_tb(trace_info, max_tb),
        "details": [str(l) for l in value.args]
    }

class SubprocessError(Exception):
    pass
<|endoftext|>


<commit_before>#!/usr/bin/env python3
#
# Copyright (c) 2015-2016 The Khronos Group Inc.
# Copyright (c) 2015-2016 Valve Corporation
# Copyright (c) 2015-2016 LunarG, Inc.
# Copyright (c) 2015-2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Chia-I Wu <olv@lunarg.com>
# Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
# Author: Jon Ashburn <jon@lunarg.com>
# Author: Gwan-gyeong Mun <kk.moon@samsung.com>
# Author: Mark Lobodzinski <mark@lunarg.com>

import sys

import vulkan

def generate_get_proc_addr_check(name):
    return "    if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
           "        return NULL;" % ((name,) * 3)

class Subcommand(object):
    def __init__(self, argv):
        self.argv = argv
        self.headers = vulkan.headers
        self.protos = vulkan.protos
        self.outfile = None

    def run(self):
        if self.outfile:
            with open(self.outfile, "w") as outfile:
                outfile.write(self.generate())
        else:
            print(self.generate())

    def generate(self):
        copyright = self.generate_copyright()
        header = self.generate_header()
        body = self.generate_body()
        footer = self.generate_footer()

        contents = []
        if copyright:
            contents.append(copyright)
        if header:
            contents.append(header)
        if body:
            contents.append(body)
        if footer:
            contents.append(footer)

        return "\n\n".join(contents)

    def generate_copyright(self):
        return """/* THIS FILE IS GENERATED.  DO NOT EDIT. */

/*
 * Copyright (c) 2015-2016 The Khronos Group Inc.
 * Copyright (c) 2015-2016 Valve Corporation
 * Copyright (c) 2015-2016 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 */"""

    def generate_header(self):
        return "\n".join(["#include <" + h + ">" for h in self.headers])

    def generate_body(self):
        pass

    def generate_footer(self):
        pass

class DispatchTableOpsSubcommand(Subcommand):
    def __init__(self, argv):
        self.argv = argv
        self.headers = vulkan.headers_all
        self.protos = vulkan.protos_all
        self.outfile = None

    def run(self):
        if len(self.argv) < 1:
            print("DispatchTableOpsSubcommand: <prefix> unspecified")
            return

        self.prefix = self.argv[0]

        if len(self.argv) > 2:
            print("DispatchTableOpsSubcommand: <prefix> [outfile]")
            return

        if len(self.argv) == 2:
            self.outfile = self.argv[1]

        super(DispatchTableOpsSubcommand, self).run()

    def generate_header(self):
        return "\n".join(["#include <vulkan/vulkan.h>",
                          "#include <vulkan/vk_layer.h>",
                          "#include <string.h>"])

    def _generate_init_dispatch(self, type):
        stmts = []
        func = []
        if type == "device":
            # GPA has to be first one and uses wrapped object
            stmts.append("    memset(table, 0, sizeof(*table));")
            stmts.append("    // Core device function pointers")
            stmts.append("    table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(device, \"vkGetDeviceProcAddr\");")

            for proto in self.protos:
                if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or \
                  proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or \
                  proto.params[0].ty == "VkPhysicalDevice" or proto.name == "GetDeviceProcAddr":
                    continue
                stmts.append("    table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" % (proto.name, proto.name, proto.name))
            func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
                % self.prefix)
            func.append("%s                                               VkLayerDispatchTable *table,"
                % (" " * len(self.prefix)))
            func.append("%s                                               PFN_vkGetDeviceProcAddr gpa)"
                % (" " * len(self.prefix)))
        else:
            stmts.append("    memset(table, 0, sizeof(*table));")
            stmts.append("    // Core instance function pointers")
            stmts.append("    table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(instance, \"vkGetInstanceProcAddr\");")

            for proto in self.protos:
                if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice" or \
                  proto.name == "CreateDevice" or proto.name == "GetInstanceProcAddr":
                    continue
                # Protect platform-dependent APIs with #ifdef
                if 'KHR' in proto.name and 'Win32' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
                if 'KHR' in proto.name and 'Xlib' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
                if 'KHR' in proto.name and 'Xcb' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
                if 'KHR' in proto.name and 'Mir' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
                if 'KHR' in proto.name and 'Wayland' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
                if 'KHR' in proto.name and 'Android' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
                # Output dispatch table entry
                stmts.append("    table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
                      (proto.name, proto.name, proto.name))
                # If entry was protected by an #ifdef, close with a #endif
                if 'KHR' in proto.name and 'Win32' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
                if 'KHR' in proto.name and 'Xlib' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
                if 'KHR' in proto.name and 'Xcb' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
                if 'KHR' in proto.name and 'Mir' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
                if 'KHR' in proto.name and 'Wayland' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
                if 'KHR' in proto.name and 'Android' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
            func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
            func.append("%s        VkInstance instance," % (" " * len(self.prefix)))
            func.append("%s        VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
            func.append("%s        PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
        func.append("{")
        func.append("%s" % "\n".join(stmts))
        func.append("}")

        return "\n".join(func)

    def generate_body(self):
        body = [self._generate_init_dispatch("device"),
                self._generate_init_dispatch("instance")]

        return "\n\n".join(body)

class WinDefFileSubcommand(Subcommand):
    def run(self):
        library_exports = {
                "all": [],
                "icd": [
                    "vk_icdGetInstanceProcAddr",
                ],
                "layer": [
                    "vkGetInstanceProcAddr",
                    "vkGetDeviceProcAddr",
                    "vkEnumerateInstanceLayerProperties",
                    "vkEnumerateInstanceExtensionProperties"
                ],
                "layer_multi": [
                    "multi2GetInstanceProcAddr",
                    "multi1GetDeviceProcAddr"
                ]
        }

        if len(self.argv) < 2 or len(self.argv) > 3 or self.argv[1] not in library_exports:
            print("WinDefFileSubcommand: <library-name> {%s} [outfile]" %
                    "|".join(library_exports.keys()))
            return

        self.library = self.argv[0]
        if self.library == "VkLayer_multi":
            self.exports = library_exports["layer_multi"]
        else:
            self.exports = library_exports[self.argv[1]]

        if len(self.argv) == 3:
            self.outfile = self.argv[2]

        super(WinDefFileSubcommand, self).run()

    def generate_copyright(self):
        return """; THIS FILE IS GENERATED.  DO NOT EDIT.

;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Vulkan
;
; Copyright (c) 2015-2016 The Khronos Group Inc.
; Copyright (c) 2015-2016 Valve Corporation
; Copyright (c) 2015-2016 LunarG, Inc.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
;  Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
;;;;  End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""

    def generate_header(self):
        return "; The following is required on Windows, for exporting symbols from the DLL"

    def generate_body(self):
        body = []

        body.append("LIBRARY " + self.library)
        body.append("EXPORTS")

        for proto in self.exports:
            if self.library != "VkLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties":
                body.append( proto)

        return "\n".join(body)

def main():
    wsi = {
            "Win32",
            "Android",
            "Xcb",
            "Xlib",
            "Wayland",
            "Mir",
            "Display",
    }
    subcommands = {
            "dispatch-table-ops": DispatchTableOpsSubcommand,
            "win-def-file": WinDefFileSubcommand,
    }

    if len(sys.argv) < 3 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands:
        print("Usage: %s <wsi> <subcommand> [options]" % sys.argv[0])
        print
        print("Available sucommands are: %s" % " ".join(subcommands))
        exit(1)

    subcmd = subcommands[sys.argv[2]](sys.argv[3:])
    subcmd.run()

if __name__ == "__main__":
    main()
<commit_msg>scripts: Re-added AllPlatforms wsi option<commit_after>#!/usr/bin/env python3
#
# Copyright (c) 2015-2016 The Khronos Group Inc.
# Copyright (c) 2015-2016 Valve Corporation
# Copyright (c) 2015-2016 LunarG, Inc.
# Copyright (c) 2015-2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Chia-I Wu <olv@lunarg.com>
# Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
# Author: Jon Ashburn <jon@lunarg.com>
# Author: Gwan-gyeong Mun <kk.moon@samsung.com>
# Author: Mark Lobodzinski <mark@lunarg.com>

import sys

import vulkan

def generate_get_proc_addr_check(name):
    return "    if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
           "        return NULL;" % ((name,) * 3)

class Subcommand(object):
    def __init__(self, argv):
        self.argv = argv
        self.headers = vulkan.headers
        self.protos = vulkan.protos
        self.outfile = None

    def run(self):
        if self.outfile:
            with open(self.outfile, "w") as outfile:
                outfile.write(self.generate())
        else:
            print(self.generate())

    def generate(self):
        copyright = self.generate_copyright()
        header = self.generate_header()
        body = self.generate_body()
        footer = self.generate_footer()

        contents = []
        if copyright:
            contents.append(copyright)
        if header:
            contents.append(header)
        if body:
            contents.append(body)
        if footer:
            contents.append(footer)

        return "\n\n".join(contents)

    def generate_copyright(self):
        return """/* THIS FILE IS GENERATED.  DO NOT EDIT. */

/*
 * Copyright (c) 2015-2016 The Khronos Group Inc.
 * Copyright (c) 2015-2016 Valve Corporation
 * Copyright (c) 2015-2016 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 */"""

    def generate_header(self):
        return "\n".join(["#include <" + h + ">" for h in self.headers])

    def generate_body(self):
        pass

    def generate_footer(self):
        pass

class DispatchTableOpsSubcommand(Subcommand):
    def __init__(self, argv):
        self.argv = argv
        self.headers = vulkan.headers_all
        self.protos = vulkan.protos_all
        self.outfile = None

    def run(self):
        if len(self.argv) < 1:
            print("DispatchTableOpsSubcommand: <prefix> unspecified")
            return

        self.prefix = self.argv[0]

        if len(self.argv) > 2:
            print("DispatchTableOpsSubcommand: <prefix> [outfile]")
            return

        if len(self.argv) == 2:
            self.outfile = self.argv[1]

        super(DispatchTableOpsSubcommand, self).run()

    def generate_header(self):
        return "\n".join(["#include <vulkan/vulkan.h>",
                          "#include <vulkan/vk_layer.h>",
                          "#include <string.h>"])

    def _generate_init_dispatch(self, type):
        stmts = []
        func = []
        if type == "device":
            # GPA has to be first one and uses wrapped object
            stmts.append("    memset(table, 0, sizeof(*table));")
            stmts.append("    // Core device function pointers")
            stmts.append("    table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(device, \"vkGetDeviceProcAddr\");")

            for proto in self.protos:
                if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or \
                  proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or \
                  proto.params[0].ty == "VkPhysicalDevice" or proto.name == "GetDeviceProcAddr":
                    continue
                stmts.append("    table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" % (proto.name, proto.name, proto.name))
            func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
                % self.prefix)
            func.append("%s                                               VkLayerDispatchTable *table,"
                % (" " * len(self.prefix)))
            func.append("%s                                               PFN_vkGetDeviceProcAddr gpa)"
                % (" " * len(self.prefix)))
        else:
            stmts.append("    memset(table, 0, sizeof(*table));")
            stmts.append("    // Core instance function pointers")
            stmts.append("    table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(instance, \"vkGetInstanceProcAddr\");")

            for proto in self.protos:
                if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice" or \
                  proto.name == "CreateDevice" or proto.name == "GetInstanceProcAddr":
                    continue
                # Protect platform-dependent APIs with #ifdef
                if 'KHR' in proto.name and 'Win32' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
                if 'KHR' in proto.name and 'Xlib' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
                if 'KHR' in proto.name and 'Xcb' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
                if 'KHR' in proto.name and 'Mir' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
                if 'KHR' in proto.name and 'Wayland' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
                if 'KHR' in proto.name and 'Android' in proto.name:
                    stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
                # Output dispatch table entry
                stmts.append("    table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
                      (proto.name, proto.name, proto.name))
                # If entry was protected by an #ifdef, close with a #endif
                if 'KHR' in proto.name and 'Win32' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
                if 'KHR' in proto.name and 'Xlib' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
                if 'KHR' in proto.name and 'Xcb' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
                if 'KHR' in proto.name and 'Mir' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
                if 'KHR' in proto.name and 'Wayland' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
                if 'KHR' in proto.name and 'Android' in proto.name:
                    stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
            func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
            func.append("%s        VkInstance instance," % (" " * len(self.prefix)))
            func.append("%s        VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
            func.append("%s        PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
        func.append("{")
        func.append("%s" % "\n".join(stmts))
        func.append("}")

        return "\n".join(func)

    def generate_body(self):
        body = [self._generate_init_dispatch("device"),
                self._generate_init_dispatch("instance")]

        return "\n\n".join(body)

class WinDefFileSubcommand(Subcommand):
    def run(self):
        library_exports = {
                "all": [],
                "icd": [
                    "vk_icdGetInstanceProcAddr",
                ],
                "layer": [
                    "vkGetInstanceProcAddr",
                    "vkGetDeviceProcAddr",
                    "vkEnumerateInstanceLayerProperties",
                    "vkEnumerateInstanceExtensionProperties"
                ],
                "layer_multi": [
                    "multi2GetInstanceProcAddr",
                    "multi1GetDeviceProcAddr"
                ]
        }

        if len(self.argv) < 2 or len(self.argv) > 3 or self.argv[1] not in library_exports:
            print("WinDefFileSubcommand: <library-name> {%s} [outfile]" %
                    "|".join(library_exports.keys()))
            return

        self.library = self.argv[0]
        if self.library == "VkLayer_multi":
            self.exports = library_exports["layer_multi"]
        else:
            self.exports = library_exports[self.argv[1]]

        if len(self.argv) == 3:
            self.outfile = self.argv[2]

        super(WinDefFileSubcommand, self).run()

    def generate_copyright(self):
        return """; THIS FILE IS GENERATED.  DO NOT EDIT.

;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Vulkan
;
; Copyright (c) 2015-2016 The Khronos Group Inc.
; Copyright (c) 2015-2016 Valve Corporation
; Copyright (c) 2015-2016 LunarG, Inc.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
;  Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
;;;;  End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""

    def generate_header(self):
        return "; The following is required on Windows, for exporting symbols from the DLL"

    def generate_body(self):
        body = []

        body.append("LIBRARY " + self.library)
        body.append("EXPORTS")

        for proto in self.exports:
            if self.library != "VkLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties":
                body.append( proto)

        return "\n".join(body)

def main():
    wsi = {
            "Win32",
            "Android",
            "Xcb",
            "Xlib",
            "Wayland",
            "Mir",
            "Display",
            "AllPlatforms",
    }
    subcommands = {
            "dispatch-table-ops": DispatchTableOpsSubcommand,
            "win-def-file": WinDefFileSubcommand,
    }

    if len(sys.argv) < 3 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands:
        print("Usage: %s <wsi> <subcommand> <option>" % sys.argv[0])
        print
        print("Available wsi are: %s" % " ".join(wsi))
        print("Available subcommands are: %s" % " ".join(subcommands))
        exit(1)

    subcmd = subcommands[sys.argv[2]](sys.argv[3:])
    subcmd.run()

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


<commit_before>import random
from operator import itemgetter, attrgetter

from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Count
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin
from django.views.generic import View, TemplateView, ListView, DetailView, RedirectView, CreateView, UpdateView
from django.shortcuts import get_object_or_404, HttpResponseRedirect, reverse

from users.permissions import PERMS
from .forms import ElectionForm, CandidateForm
from .models import Election, STVVote, STVPreference, FPTPVote, APRVVote, Candidate, Ticket, Vote, STVResult
from .stv import Election as StvCalculator

# Create your views here.
class HomeView(ListView):
    template_name = "votes/home.html"
    model = Election
    context_object_name = "elections"

    def get_queryset(self):
        tickets = self.request.user.member.ticket_set.filter(spent=False)
        return Election.objects.filter(ticket__in=tickets, open=True)

class AdminView(PermissionRequiredMixin, ListView):
    permission_required = PERMS.votes.view_election
    template_name = "votes/home.html"
    model = Election
    context_object_name = "elections"

    def get_queryset(self):
        return Election.objects.all()

class CreateElection(PermissionRequiredMixin, CreateView):
    permission_required = PERMS.votes.add_election
    model = Election
    template_name = "votes/create_election.html"
    form_class = ElectionForm

class UpdateElection(PermissionRequiredMixin, UpdateView):
    permission_required = PERMS.votes.edit_election
    model = Election
    template_name = "votes/create_election.html"
    form_class = ElectionForm

class CreateCandidate(PermissionRequiredMixin, CreateView):
    permission_required = PERMS.votes.add_candidate
    model = Candidate
    template_name = "votes/create_candidate.html"
    form_class = CandidateForm

    def form_valid(self, form):
        form.instance.inventory = get_object_or_404(Election, id=self.kwargs['election'])
        return super().form_valid(form)

class UpdateCandidate(PermissionRequiredMixin, UpdateView):
    permission_required = PERMS.votes.edit_candidate
    model = Candidate
    template_name = "votes/create_candidate.html"
    form_class = CandidateForm

class DoneView(LoginRequiredMixin, DetailView):
    model = Vote
    slug_field = "uuid"

    def get_template_names(self):
        if self.election.vote_type == Election.Types.APRV:
            return "votes/approval_done.html"
        elif self.election.vote_type == Election.Types.FPTP:
            return "votes/fptp_done.html"
        elif self.election.vote_type == Election.Types.STV:
            return "votes/stv_done.html"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'])
        return self.election.votes()

class VoteView(LoginRequiredMixin, RedirectView):
    def get_object(self):
        return get_object_or_404(Election, id=self.kwargs['election'])

    def get_redirect_url(self, *args, **kwargs):
        election = self.get_object()
        if election.vote_type == Election.Types.APRV:
            return reverse('votes:approval_vote', args=[self.kwargs['election']])
        elif election.vote_type == Election.Types.FPTP:
            return reverse('votes:fptp_vote', args=[self.kwargs['election']])
        elif election.vote_type == Election.Types.STV:
            return reverse('votes:stv_vote', args=[self.kwargs['election']])
        else:
            raise NotImplementedError()

class ApprovalResultView(PermissionRequiredMixin, ListView):
    model = Candidate
    permission_required = PERMS.votes.view_aprvvote
    template_name = "votes/approval_results.html"
    ordering = [Count("aprvvotes_set")]
    context_object_name = "choices"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], vote_type=Election.Types.APRV,
                                          open=False)
        return self.election.candidate_set.all()

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        ctxt['election'] = self.election
        ctxt['choices'] = sorted(ctxt['choices'], key=lambda x: -x.votes().count())
        return ctxt

class ApprovalVoteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
    template_name = "votes/approval_votescreen.html"

    def test_func(self):
        return self.request.user.member.ticket_set.filter(election=self.election, spent=False).exists()

    def post(self, request, **kwargs):
        self.get_context_data(**kwargs)
        ticket = get_object_or_404(request.user.member.ticket_set.all(), election=self.election, spent=False)
        print(request.POST)
        errors = []
        if "selection" not in request.POST:
            errors.append("Please select at least one option")
            selection = []
        else:
            selection = request.POST.getlist("selection")
        if 0 < self.election.max_votes < len(selection):
            errors.append("Too many options selected")
        try:
            selection = [int(s) for s in selection]
        except ValueError:
            errors.append("Invalid option submitted")
        allowed = [a.id for a in self.election.candidate_set.all()]
        for i in selection:
            if i not in allowed:
                errors.append("Unknown option selected")

        if errors:
            return self.get(request, errors=errors)
        else:
            vote = APRVVote(
                uuid=ticket.uuid,
                election=self.election,
            )
            vote.save()
            vote.selection.add(*selection)

            ticket.spent = True
            ticket.save()

            return HttpResponseRedirect(
                reverse("votes:vote_done", kwargs={'election': self.election.id, 'slug': vote.uuid}))

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.APRV)
        ctxt['election'] = self.election
        ctxt['choices'] = list(self.election.candidate_set.all())
        random.shuffle(ctxt['choices'])
        return ctxt

class FPTPResultView(PermissionRequiredMixin, ListView):
    model = Candidate
    permission_required = PERMS.votes.view_fptpvote
    template_name = "votes/fptp_results.html"
    ordering = [Count("fptpvotes_set")]
    context_object_name = "choices"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], vote_type=Election.Types.FPTP,
                                          open=False)
        return self.election.candidate_set.all()

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        ctxt['election'] = self.election
        ctxt['choices'] = sorted(ctxt['choices'], key=lambda x: -x.votes().count())
        return ctxt

class FPTPVoteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
    template_name = "votes/fptp_votescreen.html"

    def test_func(self):
        return self.request.user.member.ticket_set.filter(election=self.election, spent=False).exists()

    def post(self, request, **kwargs):
        self.get_context_data(**kwargs)
        ticket = get_object_or_404(request.user.member.ticket_set.all(), election=self.election, spent=False)
        print(request.POST)
        errors = []
        if "selection" not in request.POST:
            errors.append("Please select one option")
            selection = []
        else:
            selection = request.POST.get("selection")
        try:
            selection = int(selection)
        except ValueError:
            errors.append("Invalid option submitted")
        allowed = [a.id for a in self.election.candidate_set.all()]
        if selection not in allowed:
            errors.append("Unknown option selected")

        if errors:
            return self.get(request, errors=errors)
        else:
            vote = FPTPVote(
                uuid=ticket.uuid,
                election=self.election,
                selection_id=selection
            )
            vote.save()

            ticket.spent = True
            ticket.save()

            return HttpResponseRedirect(
                reverse("votes:vote_done", kwargs={'election': self.election.id, 'slug': vote.uuid}))

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.FPTP)
        ctxt['election'] = self.election
        ctxt['choices'] = list(self.election.candidate_set.all())
        random.shuffle(ctxt['choices'])
        return ctxt

class STVResultView(PermissionRequiredMixin, ListView):
    model = Candidate
    permission_required = PERMS.votes.view_stvvote
    template_name = "votes/stv_results.html"
    context_object_name = "choices"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], vote_type=Election.Types.STV,
                                          open=False)
        return self.election.candidate_set.all()

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        ctxt['election'] = self.election
        try:
            res = self.election.stvresult
        except STVResult.DoesNotExist:
            candidates = set(map(attrgetter('id'), self.election.candidate_set.all()))
            withdrawn = set(map(attrgetter('id'), self.election.candidate_set.filter(state=Candidate.State.WITHDRAWN)))
            votes = []
            for i in self.election.stvvote_set.all():
                vote = []
                for j in STVPreference.objects.filter(stvvote=i).order_by('order'):
                    vote.append(int(j.candidate_id))
                votes.append(tuple(vote))

            calc = StvCalculator(candidates, votes, self.election.seats)
            calc.withdraw(withdrawn)
            calc.full_election()
            res = STVResult.objects.create(election=self.election, full_log="\n".join(calc.fulllog))
            res.save()
            res.winners.add(*Candidate.objects.filter(id__in=calc.winners()))
        ctxt['result'] = res
        return ctxt

class STVVoteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
    template_name = "votes/stv_votescreen.html"

    def test_func(self):
        return self.request.user.member.ticket_set.filter(election=self.election, spent=False).exists()

    def post(self, request, **kwargs):
        self.get_context_data(**kwargs)
        ticket = get_object_or_404(request.user.member.ticket_set.all(), election=self.election, spent=False)
        print(request.POST)
        errors = []
        allowed = set(a.id for a in self.election.candidate_set.all())

        # Almost all of these errors should never be seen (unless someone is bypassing the js)
        submitted_candidates = set(request.POST.keys())
        submitted_candidates.remove('csrfmiddlewaretoken')  # remove csrf token (the only valid non-vote value)
        try:
            submitted_candidates = set(map(int, submitted_candidates))
        except ValueError:
            errors.append("Unknown option submitted (non integer key)")
        if submitted_candidates.difference(allowed):
            errors.append("Unknown option submitted (unknown candidate)")
        if allowed.difference(submitted_candidates):
            errors.append("Missing option")

        selection = []
        for i in submitted_candidates:
            selection.append((i, request.POST.get(str(i))))

        print(selection)
        try:
            selection = [(s, int(v)) for s, v in selection if v != ""]
        except ValueError:
            errors.append("Invalid preference (non-integer)")
        for k, v in selection:
            if v not in range(1, len(selection) + 1):
                errors.append("Invalid preference (out of range)")
        if len(selection) != len(set(map(itemgetter(1), selection))):
            errors.append("Invalid preference (repeated)")
        if len(selection) == 0:
            errors.append("Please select at least one candidate")  # This one is actually possible

        if errors:
            return self.get(request, errors=set(errors), previous=request.POST)
        else:
            vote = STVVote(
                uuid=ticket.uuid,
                election=self.election,
            )
            vote.save()
            for i in selection:
                STVPreference.objects.create(stvvote=vote, candidate_id=i[0], order=i[1])

            ticket.spent = True
            ticket.save()

            return HttpResponseRedirect(
                reverse("votes:vote_done", kwargs={'election': self.election.id, 'slug': vote.uuid}))

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.STV)
        ctxt['election'] = self.election
        ctxt['choices'] = list(self.election.candidate_set.all())
        random.shuffle(ctxt['choices'])
        return ctxt

def maybeint(string):
    try:
        return int(string)
    except ValueError:
        return None
<commit_msg>Fix view perms (again)<commit_after>import random
from operator import itemgetter, attrgetter

from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Count
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin
from django.views.generic import View, TemplateView, ListView, DetailView, RedirectView, CreateView, UpdateView
from django.shortcuts import get_object_or_404, HttpResponseRedirect, reverse

from users.permissions import PERMS
from .forms import ElectionForm, CandidateForm
from .models import Election, STVVote, STVPreference, FPTPVote, APRVVote, Candidate, Ticket, Vote, STVResult
from .stv import Election as StvCalculator

# Create your views here.
class HomeView(ListView):
    template_name = "votes/home.html"
    model = Election
    context_object_name = "elections"

    def get_queryset(self):
        tickets = self.request.user.member.ticket_set.filter(spent=False)
        return Election.objects.filter(ticket__in=tickets, open=True)

class AdminView(PermissionRequiredMixin, ListView):
    permission_required = PERMS.votes.view_election
    template_name = "votes/home.html"
    model = Election
    context_object_name = "elections"

    def get_queryset(self):
        return Election.objects.all()

class CreateElection(PermissionRequiredMixin, CreateView):
    permission_required = PERMS.votes.add_election
    model = Election
    template_name = "votes/create_election.html"
    form_class = ElectionForm

class UpdateElection(PermissionRequiredMixin, UpdateView):
    permission_required = PERMS.votes.edit_election
    model = Election
    template_name = "votes/create_election.html"
    form_class = ElectionForm

class CreateCandidate(PermissionRequiredMixin, CreateView):
    permission_required = PERMS.votes.add_candidate
    model = Candidate
    template_name = "votes/create_candidate.html"
    form_class = CandidateForm

    def form_valid(self, form):
        form.instance.inventory = get_object_or_404(Election, id=self.kwargs['election'])
        return super().form_valid(form)

class UpdateCandidate(PermissionRequiredMixin, UpdateView):
    permission_required = PERMS.votes.edit_candidate
    model = Candidate
    template_name = "votes/create_candidate.html"
    form_class = CandidateForm

class DoneView(LoginRequiredMixin, DetailView):
    model = Vote
    slug_field = "uuid"

    def get_template_names(self):
        if self.election.vote_type == Election.Types.APRV:
            return "votes/approval_done.html"
        elif self.election.vote_type == Election.Types.FPTP:
            return "votes/fptp_done.html"
        elif self.election.vote_type == Election.Types.STV:
            return "votes/stv_done.html"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'])
        return self.election.votes()

class VoteView(LoginRequiredMixin, RedirectView):
    def get_object(self):
        return get_object_or_404(Election, id=self.kwargs['election'])

    def get_redirect_url(self, *args, **kwargs):
        election = self.get_object()
        if election.vote_type == Election.Types.APRV:
            return reverse('votes:approval_vote', args=[self.kwargs['election']])
        elif election.vote_type == Election.Types.FPTP:
            return reverse('votes:fptp_vote', args=[self.kwargs['election']])
        elif election.vote_type == Election.Types.STV:
            return reverse('votes:stv_vote', args=[self.kwargs['election']])
        else:
            raise NotImplementedError()

class ApprovalResultView(PermissionRequiredMixin, ListView):
    model = Candidate
    permission_required = PERMS.votes.view_aprvvote
    template_name = "votes/approval_results.html"
    ordering = [Count("aprvvotes_set")]
    context_object_name = "choices"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], vote_type=Election.Types.APRV,
                                          open=False)
        return self.election.candidate_set.all()

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        ctxt['election'] = self.election
        ctxt['choices'] = sorted(ctxt['choices'], key=lambda x: -x.votes().count())
        return ctxt

class ApprovalVoteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
    template_name = "votes/approval_votescreen.html"

    def test_func(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.APRV)
        return self.request.user.member.ticket_set.filter(election=self.election, spent=False).exists()

    def post(self, request, **kwargs):
        self.get_context_data(**kwargs)
        ticket = get_object_or_404(request.user.member.ticket_set.all(), election=self.election, spent=False)
        print(request.POST)
        errors = []
        if "selection" not in request.POST:
            errors.append("Please select at least one option")
            selection = []
        else:
            selection = request.POST.getlist("selection")
        if 0 < self.election.max_votes < len(selection):
            errors.append("Too many options selected")
        try:
            selection = [int(s) for s in selection]
        except ValueError:
            errors.append("Invalid option submitted")
        allowed = [a.id for a in self.election.candidate_set.all()]
        for i in selection:
            if i not in allowed:
                errors.append("Unknown option selected")

        if errors:
            return self.get(request, errors=errors)
        else:
            vote = APRVVote(
                uuid=ticket.uuid,
                election=self.election,
            )
            vote.save()
            vote.selection.add(*selection)

            ticket.spent = True
            ticket.save()

            return HttpResponseRedirect(
                reverse("votes:vote_done", kwargs={'election': self.election.id, 'slug': vote.uuid}))

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.APRV)
        ctxt['election'] = self.election
        ctxt['choices'] = list(self.election.candidate_set.all())
        random.shuffle(ctxt['choices'])
        return ctxt

class FPTPResultView(PermissionRequiredMixin, ListView):
    model = Candidate
    permission_required = PERMS.votes.view_fptpvote
    template_name = "votes/fptp_results.html"
    ordering = [Count("fptpvotes_set")]
    context_object_name = "choices"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], vote_type=Election.Types.FPTP,
                                          open=False)
        return self.election.candidate_set.all()

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        ctxt['election'] = self.election
        ctxt['choices'] = sorted(ctxt['choices'], key=lambda x: -x.votes().count())
        return ctxt

class FPTPVoteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
    template_name = "votes/fptp_votescreen.html"

    def test_func(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.FPTP)
        return self.request.user.member.ticket_set.filter(election=self.election, spent=False).exists()

    def post(self, request, **kwargs):
        self.get_context_data(**kwargs)
        ticket = get_object_or_404(request.user.member.ticket_set.all(), election=self.election, spent=False)
        print(request.POST)
        errors = []
        if "selection" not in request.POST:
            errors.append("Please select one option")
            selection = []
        else:
            selection = request.POST.get("selection")
        try:
            selection = int(selection)
        except ValueError:
            errors.append("Invalid option submitted")
        allowed = [a.id for a in self.election.candidate_set.all()]
        if selection not in allowed:
            errors.append("Unknown option selected")

        if errors:
            return self.get(request, errors=errors)
        else:
            vote = FPTPVote(
                uuid=ticket.uuid,
                election=self.election,
                selection_id=selection
            )
            vote.save()

            ticket.spent = True
            ticket.save()

            return HttpResponseRedirect(
                reverse("votes:vote_done", kwargs={'election': self.election.id, 'slug': vote.uuid}))

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.FPTP)
        ctxt['election'] = self.election
        ctxt['choices'] = list(self.election.candidate_set.all())
        random.shuffle(ctxt['choices'])
        return ctxt

class STVResultView(PermissionRequiredMixin, ListView):
    model = Candidate
    permission_required = PERMS.votes.view_stvvote
    template_name = "votes/stv_results.html"
    context_object_name = "choices"

    def get_queryset(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], vote_type=Election.Types.STV,
                                          open=False)
        return self.election.candidate_set.all()

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        ctxt['election'] = self.election
        try:
            res = self.election.stvresult
        except STVResult.DoesNotExist:
            candidates = set(map(attrgetter('id'), self.election.candidate_set.all()))
            withdrawn = set(map(attrgetter('id'), self.election.candidate_set.filter(state=Candidate.State.WITHDRAWN)))
            votes = []
            for i in self.election.stvvote_set.all():
                vote = []
                for j in STVPreference.objects.filter(stvvote=i).order_by('order'):
                    vote.append(int(j.candidate_id))
                votes.append(tuple(vote))

            calc = StvCalculator(candidates, votes, self.election.seats)
            calc.withdraw(withdrawn)
            calc.full_election()
            res = STVResult.objects.create(election=self.election, full_log="\n".join(calc.fulllog))
            res.save()
            res.winners.add(*Candidate.objects.filter(id__in=calc.winners()))
        ctxt['result'] = res
        return ctxt

class STVVoteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
    template_name = "votes/stv_votescreen.html"

    def test_func(self):
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.STV)
        return self.request.user.member.ticket_set.filter(election=self.election, spent=False).exists()

    def post(self, request, **kwargs):
        self.get_context_data(**kwargs)
        ticket = get_object_or_404(request.user.member.ticket_set.all(), election=self.election, spent=False)
        print(request.POST)
        errors = []
        allowed = set(a.id for a in self.election.candidate_set.all())

        # Almost all of these errors should never be seen (unless someone is bypassing the js)
        submitted_candidates = set(request.POST.keys())
        submitted_candidates.remove('csrfmiddlewaretoken')  # remove csrf token (the only valid non-vote value)
        try:
            submitted_candidates = set(map(int, submitted_candidates))
        except ValueError:
            errors.append("Unknown option submitted (non integer key)")
        if submitted_candidates.difference(allowed):
            errors.append("Unknown option submitted (unknown candidate)")
        if allowed.difference(submitted_candidates):
            errors.append("Missing option")

        selection = []
        for i in submitted_candidates:
            selection.append((i, request.POST.get(str(i))))

        print(selection)
        try:
            selection = [(s, int(v)) for s, v in selection if v != ""]
        except ValueError:
            errors.append("Invalid preference (non-integer)")
        for k, v in selection:
            if v not in range(1, len(selection) + 1):
                errors.append("Invalid preference (out of range)")
        if len(selection) != len(set(map(itemgetter(1), selection))):
            errors.append("Invalid preference (repeated)")
        if len(selection) == 0:
            errors.append("Please select at least one candidate")  # This one is actually possible

        if errors:
            return self.get(request, errors=set(errors), previous=request.POST)
        else:
            vote = STVVote(
                uuid=ticket.uuid,
                election=self.election,
            )
            vote.save()
            for i in selection:
                STVPreference.objects.create(stvvote=vote, candidate_id=i[0], order=i[1])

            ticket.spent = True
            ticket.save()

            return HttpResponseRedirect(
                reverse("votes:vote_done", kwargs={'election': self.election.id, 'slug': vote.uuid}))

    def get_context_data(self, **kwargs):
        ctxt = super().get_context_data(**kwargs)
        self.election = get_object_or_404(Election, id=self.kwargs['election'], open=True, vote_type=Election.Types.STV)
        ctxt['election'] = self.election
        ctxt['choices'] = list(self.election.candidate_set.all())
        random.shuffle(ctxt['choices'])
        return ctxt

def maybeint(string):
    try:
        return int(string)
    except ValueError:
        return None
<|endoftext|>


<commit_before>#!/usr/bin/env python2
# coding: utf-8
"""Test register."""

import unittest

from triton import (ARCH, REG, OPERAND, TritonContext)

class TestRAXRegister(unittest.TestCase):

    """Testing the Register class with RAX."""

    def setUp(self):
        """Define arch and register to check."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)
        self.reg = self.Triton.Register(REG.RAX)

    def test_name(self):
        """Check register name."""
        self.assertEqual(self.reg.getName(), "rax")

    def test_size(self):
        """Check register size."""
        self.assertEqual(self.reg.getSize(), 8)

    def test_bit_size(self):
        """Check register bit size."""
        self.assertEqual(self.reg.getBitSize(), 64)

    def test_concrete_value(self):
        """Check concrete value modification."""
        self.assertEqual(self.reg.getConcreteValue(), 0)

        value = 0x1122334455667788
        self.reg.setConcreteValue(value)
        self.assertEqual(self.reg.getConcreteValue(), value)

    def test_parent(self):
        """Check parent register."""
        self.assertEqual(self.Triton.getParentRegister(self.reg).getName(), "rax")

    def test_type(self):
        """Check operand type."""
        self.assertEqual(self.reg.getType(), OPERAND.REG)

    def test_is_valid(self):
        """Check register validity."""
        self.assertTrue(self.Triton.isRegisterValid(self.reg))

    def test_is_flag(self):
        """Check register flag."""
        self.assertFalse(self.Triton.isFlag(self.reg))

    def test_is_register(self):
        """Check register detect."""
        self.assertTrue(self.Triton.isRegister(self.reg))

class TestAHRegister(unittest.TestCase):

    """Testing the Register class with AH."""

    def setUp(self):
        """Define arch and register to check."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)
        self.reg = self.Triton.Register(REG.AH)

    def test_size(self):
        """Check register size."""
        self.assertEqual(self.reg.getSize(), 1)

    def test_bitvector(self):
        """Check bitvector information."""
        self.assertEqual(self.reg.getBitvector().getHigh(), 15)
        self.assertEqual(self.reg.getBitvector().getLow(), 8)
        self.assertEqual(self.reg.getBitvector().getVectorSize(), 8)

    def test_parent(self):
        """Check parent register on multiple arch."""
        self.assertEqual(self.Triton.getParentRegister(self.reg).getName(), "rax")

        self.Triton.setArchitecture(ARCH.X86)
        self.reg = self.Triton.Register(REG.AH)
        self.assertEqual(self.Triton.getParentRegister(self.reg).getName(), "eax")
        self.assertEqual(self.Triton.getParentRegister(self.reg).getBitSize(), 32)

class TestXmmRegister(unittest.TestCase):

    """Testing the Register class with FP/SIMD registers."""

    def setUp(self):
        """Define the arch."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)

    def test_xmm_on_x86(self):
        """Check xmm on 32 bits arch."""
        self.Triton.setArchitecture(ARCH.X86)
        xmm = self.Triton.Register(REG.XMM1, 0x112233445566778899aabbccddeeff00)
        self.assertEqual(xmm.getBitSize(), 128)
        self.assertEqual(xmm.getConcreteValue(),
                         0x112233445566778899aabbccddeeff00)

    def test_ymm(self):
        """Check ymm on 64 bits arch."""
        ymm = self.Triton.Register(REG.YMM1, 0x112233445566778899aabbccddeeff00)
        self.assertEqual(ymm.getBitSize(), 256)
        ymm.setConcreteValue(0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)
        self.assertEqual(ymm.getConcreteValue(), 0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)

    def test_zmm(self):
        """Check zmm on 64 bits arch."""
        zmm = self.Triton.Register(REG.ZMM2, 0)
        self.assertEqual(zmm.getBitSize(), 512)
        zmm.setConcreteValue(0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)
        self.assertEqual(zmm.getConcreteValue(), 0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)

class TestRegisterValues(unittest.TestCase):

    """Check register values with hierarchies."""

    def setUp(self):
        """Define the arch."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)

    def test_register_create(self):
        """Check register creation with value."""
        for reg in (REG.AH, REG.AL):
            # OK
            self.Triton.Register(reg, 0xff)
            # Not OK
            # TODO : Be more specific on the raise exception type
            with self.assertRaises(Exception):
                self.Triton.Register(reg, 0xff + 1)

        self.Triton.Register(REG.ZF, 1)
        with self.assertRaises(Exception):
            self.Triton.Register(REG.ZF, 2)

    def test_set_concrete_value(self):
        """Check register value modification."""
        for reg in (REG.AH, REG.AL):
            # OK
            reg = self.Triton.Register(reg)
            reg.setConcreteValue(0xff)
            # Not OK
            # TODO : Be more specific on the raise exception type
            with self.assertRaises(Exception):
                reg.setConcreteValue(0xff + 1)

        reg = self.Triton.Register(REG.ZF)
        reg.setConcreteValue(1)
        with self.assertRaises(Exception):
            reg.setConcreteValue(2)

    def test_overlap(self):
        """Check register overlapping."""
        self.assertTrue(self.Triton.Register(REG.AX).isOverlapWith(self.Triton.Register(REG.EAX)), "overlap with upper")
        self.assertTrue(self.Triton.Register(REG.AX).isOverlapWith(self.Triton.Register(REG.RAX)), "overlap with parent")
        self.assertTrue(self.Triton.Register(REG.RAX).isOverlapWith(self.Triton.Register(REG.AX)), "overlap with lower")
        self.assertFalse(self.Triton.Register(REG.AH).isOverlapWith(self.Triton.Register(REG.AL)))
        self.assertTrue(self.Triton.Register(REG.AX).isOverlapWith(self.Triton.Register(REG.AL)))
        self.assertTrue(self.Triton.Register(REG.AL).isOverlapWith(self.Triton.Register(REG.AX)))
        self.assertFalse(self.Triton.Register(REG.EAX).isOverlapWith(self.Triton.Register(REG.EDX)))

<commit_msg>Add test for "contains" in overlaping registers<commit_after>#!/usr/bin/env python2
# coding: utf-8
"""Test register."""

import unittest

from triton import (ARCH, REG, OPERAND, TritonContext)

class TestRAXRegister(unittest.TestCase):

    """Testing the Register class with RAX."""

    def setUp(self):
        """Define arch and register to check."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)
        self.reg = self.Triton.Register(REG.RAX)

    def test_name(self):
        """Check register name."""
        self.assertEqual(self.reg.getName(), "rax")

    def test_size(self):
        """Check register size."""
        self.assertEqual(self.reg.getSize(), 8)

    def test_bit_size(self):
        """Check register bit size."""
        self.assertEqual(self.reg.getBitSize(), 64)

    def test_concrete_value(self):
        """Check concrete value modification."""
        self.assertEqual(self.reg.getConcreteValue(), 0)

        value = 0x1122334455667788
        self.reg.setConcreteValue(value)
        self.assertEqual(self.reg.getConcreteValue(), value)

    def test_parent(self):
        """Check parent register."""
        self.assertEqual(self.Triton.getParentRegister(self.reg).getName(), "rax")

    def test_type(self):
        """Check operand type."""
        self.assertEqual(self.reg.getType(), OPERAND.REG)

    def test_is_valid(self):
        """Check register validity."""
        self.assertTrue(self.Triton.isRegisterValid(self.reg))

    def test_is_flag(self):
        """Check register flag."""
        self.assertFalse(self.Triton.isFlag(self.reg))

    def test_is_register(self):
        """Check register detect."""
        self.assertTrue(self.Triton.isRegister(self.reg))

class TestAHRegister(unittest.TestCase):

    """Testing the Register class with AH."""

    def setUp(self):
        """Define arch and register to check."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)
        self.reg = self.Triton.Register(REG.AH)

    def test_size(self):
        """Check register size."""
        self.assertEqual(self.reg.getSize(), 1)

    def test_bitvector(self):
        """Check bitvector information."""
        self.assertEqual(self.reg.getBitvector().getHigh(), 15)
        self.assertEqual(self.reg.getBitvector().getLow(), 8)
        self.assertEqual(self.reg.getBitvector().getVectorSize(), 8)

    def test_parent(self):
        """Check parent register on multiple arch."""
        self.assertEqual(self.Triton.getParentRegister(self.reg).getName(), "rax")

        self.Triton.setArchitecture(ARCH.X86)
        self.reg = self.Triton.Register(REG.AH)
        self.assertEqual(self.Triton.getParentRegister(self.reg).getName(), "eax")
        self.assertEqual(self.Triton.getParentRegister(self.reg).getBitSize(), 32)

class TestXmmRegister(unittest.TestCase):

    """Testing the Register class with FP/SIMD registers."""

    def setUp(self):
        """Define the arch."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)

    def test_xmm_on_x86(self):
        """Check xmm on 32 bits arch."""
        self.Triton.setArchitecture(ARCH.X86)
        xmm = self.Triton.Register(REG.XMM1, 0x112233445566778899aabbccddeeff00)
        self.assertEqual(xmm.getBitSize(), 128)
        self.assertEqual(xmm.getConcreteValue(),
                         0x112233445566778899aabbccddeeff00)

    def test_ymm(self):
        """Check ymm on 64 bits arch."""
        ymm = self.Triton.Register(REG.YMM1, 0x112233445566778899aabbccddeeff00)
        self.assertEqual(ymm.getBitSize(), 256)
        ymm.setConcreteValue(0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)
        self.assertEqual(ymm.getConcreteValue(), 0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)

    def test_zmm(self):
        """Check zmm on 64 bits arch."""
        zmm = self.Triton.Register(REG.ZMM2, 0)
        self.assertEqual(zmm.getBitSize(), 512)
        zmm.setConcreteValue(0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)
        self.assertEqual(zmm.getConcreteValue(), 0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00)

class TestRegisterValues(unittest.TestCase):

    """Check register values with hierarchies."""

    def setUp(self):
        """Define the arch."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)

    def test_register_create(self):
        """Check register creation with value."""
        for reg in (REG.AH, REG.AL):
            # OK
            self.Triton.Register(reg, 0xff)
            # Not OK
            # TODO : Be more specific on the raise exception type
            with self.assertRaises(Exception):
                self.Triton.Register(reg, 0xff + 1)

        self.Triton.Register(REG.ZF, 1)
        with self.assertRaises(Exception):
            self.Triton.Register(REG.ZF, 2)

    def test_set_concrete_value(self):
        """Check register value modification."""
        for reg in (REG.AH, REG.AL):
            # OK
            reg = self.Triton.Register(reg)
            reg.setConcreteValue(0xff)
            # Not OK
            # TODO : Be more specific on the raise exception type
            with self.assertRaises(Exception):
                reg.setConcreteValue(0xff + 1)

        reg = self.Triton.Register(REG.ZF)
        reg.setConcreteValue(1)
        with self.assertRaises(Exception):
            reg.setConcreteValue(2)

    def test_overlap(self):
        """Check register overlapping."""
        self.assertTrue(self.Triton.Register(REG.AX).isOverlapWith(self.Triton.Register(REG.EAX)), "overlap with upper")
        self.assertTrue(self.Triton.Register(REG.AX).isOverlapWith(self.Triton.Register(REG.RAX)), "overlap with parent")
        self.assertTrue(self.Triton.Register(REG.RAX).isOverlapWith(self.Triton.Register(REG.AX)), "overlap with lower")
        self.assertFalse(self.Triton.Register(REG.AH).isOverlapWith(self.Triton.Register(REG.AL)))
        self.assertTrue(self.Triton.Register(REG.AH).isOverlapWith(self.Triton.Register(REG.EAX)))
        self.assertTrue(self.Triton.Register(REG.EAX).isOverlapWith(self.Triton.Register(REG.AH)))
        self.assertTrue(self.Triton.Register(REG.AX).isOverlapWith(self.Triton.Register(REG.AL)))
        self.assertTrue(self.Triton.Register(REG.AL).isOverlapWith(self.Triton.Register(REG.AX)))
        self.assertFalse(self.Triton.Register(REG.EAX).isOverlapWith(self.Triton.Register(REG.EDX)))

<|endoftext|>


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

TaskData = namedtuple('TaskData', (
    # Time when the task was started
    'startTime',
    # Mesos' ID of the slave where task is being run
    'slaveID',
    # Mesos' ID of the executor running the task
    'executorID',
    # Memory requirement of the task
    'memory',
    # CPU requirement of the task
    'cores'))

class ResourceRequirement( namedtuple('_ResourceRequirement', (
    # Number of bytes (!) needed for a task
    'memory',
    # Number of CPU cores needed for a task
    'cores',
    # Number of bytes (!) needed for task on disk
    'disk',
    # True, if job can be run on a preemptable node, False otherwise
    'preemptable'))):
    def size(self):
        """
        The scalar size of an offer. Can be used to compare offers.
        """
        return self.cores

ToilJob = namedtuple('ToilJob', (
    # A job ID specific to this batch system implementation
    'jobID',
    # What string to display in the mesos UI
    'name',
    # A ResourceRequirement tuple describing the resources needed by this job
    'resources',
    # The command to be run on the worker node
    'command',
    # The resource object representing the user script
    'userScript',
    # A dictionary with additional environment variables to be set on the worker process
    'environment',
    # A named tuple containing all the required info for cleaning up the worker node
    'workerCleanupInfo'))
<commit_msg>Fix missing element in constructor<commit_after># Copyright (C) 2015-2016 Regents of the University of California
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from collections import namedtuple

TaskData = namedtuple('TaskData', (
    # Time when the task was started
    'startTime',
    # Mesos' ID of the slave where task is being run
    'slaveID',
    # IP of slave where task is being run
    'slaveIP',
    # Mesos' ID of the executor running the task
    'executorID',
    # Memory requirement of the task
    'memory',
    # CPU requirement of the task
    'cores'))

class ResourceRequirement( namedtuple('_ResourceRequirement', (
    # Number of bytes (!) needed for a task
    'memory',
    # Number of CPU cores needed for a task
    'cores',
    # Number of bytes (!) needed for task on disk
    'disk',
    # True, if job can be run on a preemptable node, False otherwise
    'preemptable'))):
    def size(self):
        """
        The scalar size of an offer. Can be used to compare offers.
        """
        return self.cores

ToilJob = namedtuple('ToilJob', (
    # A job ID specific to this batch system implementation
    'jobID',
    # What string to display in the mesos UI
    'name',
    # A ResourceRequirement tuple describing the resources needed by this job
    'resources',
    # The command to be run on the worker node
    'command',
    # The resource object representing the user script
    'userScript',
    # A dictionary with additional environment variables to be set on the worker process
    'environment',
    # A named tuple containing all the required info for cleaning up the worker node
    'workerCleanupInfo'))
<|endoftext|>


<commit_before>from wa.framework import pluginloader, signal
from wa.framework.command import Command, ComplexCommand, SubCommand
from wa.framework.configuration import settings
from wa.framework.configuration.core import Status
from wa.framework.exception import HostError, JobError, InstrumentError, ConfigError
from wa.framework.exception import (OutputProcessorError, ResourceError,
                                    CommandError, ToolError)
from wa.framework.exception import (WAError, NotFoundError, ValidationError,
                                    WorkloadError)
from wa.framework.exception import WorkerThreadError, PluginLoaderError
from wa.framework.instrument import (Instrument, very_slow, slow, normal, fast,
                                     very_fast)
from wa.framework.output import RunOutput, discover_wa_outputs
from wa.framework.plugin import Plugin, Parameter
from wa.framework.output_processor import OutputProcessor
from wa.framework.resource import (NO_ONE, JarFile, ApkFile, ReventFile, File,
                                   Executable)
from wa.framework.workload import (Workload, ApkWorkload, ApkUiautoWorkload,
                                   ApkReventWorkload, UIWorkload, UiautoWorkload,
                                   ReventWorkload)
<commit_msg>wa: fix exception exports<commit_after>from wa.framework import pluginloader, signal
from wa.framework.command import Command, ComplexCommand, SubCommand
from wa.framework.configuration import settings
from wa.framework.configuration.core import Status
from wa.framework.exception import (CommandError, ConfigError, HostError, InstrumentError,
                                    JobError, NotFoundError, OutputProcessorError,
                                    PluginLoaderError, ResourceError, TargetError,
                                    TargetNotRespondingError, TimeoutError, ToolError,
                                    ValidationError, WAError, WorkloadError, WorkerThreadError)
from wa.framework.instrument import (Instrument, very_slow, slow, normal, fast,
                                     very_fast)
from wa.framework.output import RunOutput, discover_wa_outputs
from wa.framework.plugin import Plugin, Parameter
from wa.framework.output_processor import OutputProcessor
from wa.framework.resource import (NO_ONE, JarFile, ApkFile, ReventFile, File,
                                   Executable)
from wa.framework.workload import (Workload, ApkWorkload, ApkUiautoWorkload,
                                   ApkReventWorkload, UIWorkload, UiautoWorkload,
                                   ReventWorkload)
<|endoftext|>


<commit_before>from flask import Flask, request, json, Response
import experiments
import agents
import db
import models

app = Flask(__name__)
session = db.init_db(drop_all=True)

experiment = experiments.Demo1

@app.route('/')
def index():
    return 'Index page'

@app.route("/agents", methods=["POST", "GET"])
def api_agent_create():

    exp = experiment(session)

    if request.method == 'POST':

        # Create the newcomer and insert into the network
        newcomer = agents.Agent()
        exp.network.add_agent(newcomer)

        # Trigger experiment-specific behavior that happens on arrival
        exp.newcomer_arrival_trigger(newcomer)

        # Return a response
        data = {'agents': {'uuid': newcomer.uuid}}
        js = json.dumps(data)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

    if request.method == "GET":
        data_agents = [agent.uuid for agent in exp.network.agents]
        data = {"agents": data_agents}
        js = json.dumps(data)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

@app.route("/transmissions", defaults={"transmission_uuid": None}, methods=["POST", "GET"])
@app.route("/transmissions/<transmission_uuid>", methods=["GET"])
def api_transmission(transmission_uuid):

    if request.method == 'GET':

        # Given a receiving agent, get its pending transmissions
        if transmission_uuid is None:
            print "no transmission uuid specified"
            pending_transmissions = models.Transmission\
                .query\
                .filter_by(destination_uuid=request.args['receiving_agent_uuid'])\
                .filter_by(receive_time=None)\
                .order_by(models.Transmission.transmit_time)\
                .all()

        # Or given a uuid, get the transmission with the given id
        else:
            transmission = models.Transmission\
                .query\
                .filter_by(uuid=transmission_uuid)\
                .one()
            pending_transmissions = [transmission]

        # Build a dict with info about the transmissions
        data_transmissions = []
        for i in xrange(len(pending_transmissions)):
            t = pending_transmissions[i]
            data_transmissions.append({
                "uuid": t.uuid,
                "info_uuid": t.info_uuid,
                "origin_uuid": t.origin_uuid,
                "destination_uuid": t.destination_uuid,
                "transmit_time": t.transmit_time,
                "receive_time": t.receive_time
            })
            data = {"transmissions": data_transmissions}

        js = json.dumps(data)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

    if request.method == "POST":

        info = models.Info\
            .query\
            .filter_by(uuid=request.args['info_uuid'])\
            .one()

        destination = agents.Agent\
            .query\
            .filter_by(uuid=request.args['destination_uuid'])\
            .one()

        transmission = models.Transmission(info=info, destination=destination)

        data = {'uuid': transmission.uuid}
        js = json.dumps(data)

        resp = Response(js, status=200, mimetype='application/json')
        return resp

@app.route("/information", defaults={"info_uuid": None}, methods=["POST"])
@app.route("/information/<info_uuid>", methods=["GET"])
def api_info(info_uuid):

    if request.method == 'GET':

        if info_uuid is not None:
            info = models.Info.query.filter_by(uuid=info_uuid).one()

            data = {
                'info_uuid': info_uuid,
                'contents': info.contents,
                'origin_uuid': info.origin_uuid,
                'creation_time': info.creation_time,
                'type': info.type
            }
            js = json.dumps(data)

            resp = Response(js, status=200, mimetype='application/json')
            return resp

    if request.method == "POST":

        if 'origin_uuid' in request.args:

            # models
            node = models.Node\
                .query\
                .filter_by(uuid=request.args['origin_uuid'])\
                .one()

            info = models.Info(
                origin=node,
                contents=request.args['contents'])

            data = {'uuid': info.uuid}
            js = json.dumps(data)

            resp = Response(js, status=200, mimetype='application/json')
            return resp

if __name__ == "__main__":
    app.debug = True
    app.run()
<commit_msg>Commit posted transmissions and info to db<commit_after>from flask import Flask, request, json, Response
import experiments
import agents
import db
import models

app = Flask(__name__)
session = db.init_db(drop_all=True)

experiment = experiments.Demo1

@app.route('/')
def index():
    return 'Index page'

@app.route("/agents", methods=["POST", "GET"])
def api_agent_create():

    exp = experiment(session)

    if request.method == 'POST':

        # Create the newcomer and insert into the network
        newcomer = agents.Agent()
        exp.network.add_agent(newcomer)

        # Trigger experiment-specific behavior that happens on arrival
        exp.newcomer_arrival_trigger(newcomer)

        # Return a response
        data = {'agents': {'uuid': newcomer.uuid}}
        js = json.dumps(data)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

    if request.method == "GET":
        data_agents = [agent.uuid for agent in exp.network.agents]
        data = {"agents": data_agents}
        js = json.dumps(data)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

@app.route("/transmissions", defaults={"transmission_uuid": None}, methods=["POST", "GET"])
@app.route("/transmissions/<transmission_uuid>", methods=["GET"])
def api_transmission(transmission_uuid):

    exp = experiment(session)

    if request.method == 'GET':

        # Given a receiving agent, get its pending transmissions
        if transmission_uuid is None:
            print "no transmission uuid specified"
            pending_transmissions = models.Transmission\
                .query\
                .filter_by(destination_uuid=request.args['receiving_agent_uuid'])\
                .filter_by(receive_time=None)\
                .order_by(models.Transmission.transmit_time)\
                .all()

        # Or given a uuid, get the transmission with the given id
        else:
            transmission = models.Transmission\
                .query\
                .filter_by(uuid=transmission_uuid)\
                .one()
            pending_transmissions = [transmission]

        # Build a dict with info about the transmissions
        data_transmissions = []
        for i in xrange(len(pending_transmissions)):
            t = pending_transmissions[i]
            data_transmissions.append({
                "uuid": t.uuid,
                "info_uuid": t.info_uuid,
                "origin_uuid": t.origin_uuid,
                "destination_uuid": t.destination_uuid,
                "transmit_time": t.transmit_time,
                "receive_time": t.receive_time
            })
            data = {"transmissions": data_transmissions}

        js = json.dumps(data)
        resp = Response(js, status=200, mimetype='application/json')
        return resp

    if request.method == "POST":

        info = models.Info\
            .query\
            .filter_by(uuid=request.args['info_uuid'])\
            .one()

        destination = agents.Agent\
            .query\
            .filter_by(uuid=request.args['destination_uuid'])\
            .one()

        transmission = models.Transmission(info=info, destination=destination)

        exp.session.add(transmission)
        exp.session.commit()

        data = {'uuid': transmission.uuid}
        js = json.dumps(data)

        resp = Response(js, status=200, mimetype='application/json')
        return resp

@app.route("/information", defaults={"info_uuid": None}, methods=["POST"])
@app.route("/information/<info_uuid>", methods=["GET"])
def api_info(info_uuid):

    exp = experiment(session)

    if request.method == 'GET':

        if info_uuid is not None:
            info = models.Info.query.filter_by(uuid=info_uuid).one()

            data = {
                'info_uuid': info_uuid,
                'contents': info.contents,
                'origin_uuid': info.origin_uuid,
                'creation_time': info.creation_time,
                'type': info.type
            }
            js = json.dumps(data)

            resp = Response(js, status=200, mimetype='application/json')
            return resp

    if request.method == "POST":

        if 'origin_uuid' in request.args:

            # models
            node = models.Node\
                .query\
                .filter_by(uuid=request.args['origin_uuid'])\
                .one()

            info = models.Info(
                origin=node,
                contents=request.args['contents'])

            exp.session.add(info)
            exp.session.commit()

            data = {'uuid': info.uuid}
            js = json.dumps(data)

            resp = Response(js, status=200, mimetype='application/json')
            return resp

if __name__ == "__main__":
    app.debug = True
    app.run()
<|endoftext|>