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

# Hive Netius System
# Copyright (C) 2008-2012 Hive Solutions Lda.
#
# This file is part of Hive Netius System.
#
# Hive Netius System is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hive Netius System is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hive Netius System. If not, see <http://www.gnu.org/licenses/>.

__author__ = "João Magalhães joamag@hive.pt>"
""" The author(s) of the module """

__version__ = "1.0.0"
""" The version of the module """

__revision__ = "$LastChangedRevision$"
""" The revision number of the module """

__date__ = "$LastChangedDate$"
""" The last change date of the module """

__copyright__ = "Copyright (c) 2008-2012 Hive Solutions Lda."
""" The copyright for the module """

__license__ = "GNU General Public License (GPL), Version 3"
""" The license for the module """

import math
import uuid
import time
import types
import struct
import hashlib

import netius.common
import netius.clients

BLOCK_SIZE = 16384
""" The typical size of block that is going to be retrieved
using the current torrent infra-structure, this value conditions
most of the torrent operations and should be defined carefully """

class Pieces(netius.Observable):
    """
    Class that represents the logical structure of a file that is
    divided into pieces and blocks as a hierarchy, this class is
    responsible for the management of the data structures of such
    data storage model.
    """

    def __init__(self, owner, number_pieces, number_blocks):
        netius.Observable.__init__(self)

        self.owner = owner
        self.number_pieces = number_pieces
        self.number_blocks = number_blocks
        self.bitfield = [True for _index in xrange(number_pieces)]
        self.mask = [True for _index in xrange(number_pieces * number_blocks)]

    def pop_block(self, bitfield):
        index = 0
        result = self._and(bitfield, self.bitfield)
        for bit in result:
            if bit == True: break
            index += 1

        if index == len(result): return None

        begin = self.update_block(index)
        return (index, begin)

    def mark_block(self, index, begin):
        base = index * self.number_blocks
        block_index = begin / BLOCK_SIZE
        self.mask[base + block_index] = False
        self.trigger("block", self, index, begin)
        self.update_piece(index)

    def update_block(self, index):
        base = index * self.number_blocks

        for block_index in xrange(self.number_blocks):
            state = self.mask[base + block_index]
            if state == True: break

        begin = block_index * BLOCK_SIZE
        self.mark_block(index, begin)
        return begin

    def update_piece(self, index):
        base = index * self.number_blocks
        piece_state = False

        for block_index in xrange(self.number_blocks):
            state = self.mask[base + block_index]
            if state == False: continue
            piece_state = True
            break

        self.bitfield[index] = piece_state
        if piece_state == False: self.trigger("piece", self, index)

    def _and(self, first, second):
        result = []
        for _first, _second in zip(first, second):
            if _first and _second: value = True
            else: value = False
            result.append(value)
        return result

class TorrentTask(netius.Observable):
    """
    Describes a task (operation) that is going to be performed
    using the peer to peer mesh network of the torrent protocol.

    Each of the download operations should be able to be described
    by this task object (for latter reference).
    """

    def __init__(self, owner, target_path, torrent_path = None, info_hash = None):
        netius.Observable.__init__(self)

        self.owner = owner
        self.target_path = target_path
        self.start = time.time()
        self.uploaded = 0
        self.downloaded = 0
        self.left = 0
        self.peers = []

        if torrent_path: self.info = self.load_info(torrent_path)
        else: self.info = dict(info_hash = info_hash)

        self.pieces_tracker()
        self.peers_tracker()

        self.load_file()
        self.load_pieces()

    def load_info(self, torrent_path):
        file = open(torrent_path, "rb")
        try: data = file.read()
        finally: file.close()

        struct = netius.common.bdecode(data)
        struct["info_hash"] = netius.common.info_hash(struct)
        return struct

    def on_block(self, task, index, begin):
        self.trigger("block", self, index, begin)

    def on_piece(self, task, index):
        self.verify_piece(index)
        self.trigger("piece", self, index)

    def load_file(self):
        self.file = open(self.target_path, "wb")
        self.file.seek(780140544 - 1)
        self.file.write("\0")
        self.file.flush()

    def load_pieces(self):
        number_pieces = self.info["number_pieces"]
        number_blocks = self.info["number_blocks"]
        self.requested = Pieces(self, number_pieces, number_blocks)
        self.stored = Pieces(self, number_pieces, number_blocks)
        self.stored.bind("block", self.on_block)
        self.stored.bind("piece", self.on_piece)

    def pieces_tracker(self):
        info = self.info.get("info", {})
        pieces = info.get("pieces", "")
        piece_length = info.get("piece length", 1)
        number_blocks = math.ceil(float(piece_length) / float(BLOCK_SIZE))
        number_blocks = int(number_blocks)
        self.info["pieces"] = [piece for piece in netius.common.chunks(pieces, 20)]
        self.info["number_pieces"] = len(self.info["pieces"])
        self.info["number_blocks"] = number_blocks

    def set_data(self, data, index, begin):
        piece_length = self.info["info"]["piece length"]
        self.file.seek(index * piece_length + begin)
        self.file.write(data)
        self.file.flush()
        self.stored.mark_block(index, begin)
        self.downloaded += len(data)

    def peers_tracker(self):
        """
        Tries to retrieve as much information as possible about the
        peers from the currently loaded tracker information.

        It's possible that no tracker information exits for the current
        task and for such situations no state change will occur.
        """

        # retrieves both the announce and the announce list structure from
        # the current info dictionary and uses both of them to create the
        # final list containing the various addresses of trackers, then
        # iterates over each of the trackers to retrieve the information
        # about the various peers associated with the torrent file
        announce = self.info.get("announce", None)
        announce_list = self.info.get("announce-list", [[announce]])
        for tracker in announce_list:
            tracker_url = tracker[0]
            result = netius.clients.HTTPClient.get_s(
                tracker_url,
                params = dict(
                    info_hash = self.info["info_hash"],
                    peer_id = self.owner.peer_id,
                    port = "1000",
                    uploaded = self.uploaded,
                    downloaded = self.downloaded,
                    left = self.left,
                    compact = "0"
                ),
                async = False
            )

            data = result["data"]
            if not data: continue

            response = netius.common.bdecode(data)
            peers = response["peers"]

            if type(peers) == types.DictType:
                self.peers = peers
                continue

            peers = [peer for peer in netius.common.chunks(peers, 6)]
            for peer in peers:
                address, port = struct.unpack("!LH", peer)
                ip = netius.common.addr_to_ip4(address)
                peer = dict(
                    ip = ip,
                    port = port
                )
                self.peers.append(peer)

    def connect_peers(self):
        for peer in self.peers: self.connect_peer(peer)

    def connect_peer(self, peer):
        self.owner.client.peer(self, peer["ip"], peer["port"])

    def speed(self):
        """
        Retrieves a float number representing the global speed
        of the task in bytes per second, this value is computed
        using the original creation time of the task and so it
        may not represent the most accurate speedup.

        @rtype: float
        @return: The current speed of download, defined as bytes
        per second from the original task creation time.
        """

        current = time.time()
        delta = current - self.start
        bytes_second = self.downloaded / delta
        return bytes_second

    def pop_block(self, bitfield):
        return self.requested.pop_block(bitfield)

    def verify_piece(self, index):
        file = open(self.target_path, "rb")
        try: self._verify_piece(index, file)
        finally: file.close()

    def _verify_piece(self, index, file):
        piece = self.info["pieces"][index]
        piece_length = self.info["info"]["piece length"]
        file = open(self.target_path, "rb")
        file.seek(index * piece_length)
        pending = piece_length
        hash = hashlib.sha1()
        while True:
            if pending == 0: break
            count = BLOCK_SIZE if pending > BLOCK_SIZE else pending
            data = file.read(count)
            hash.update(data)
            pending -= count
        digest = hash.digest()
        if not digest ==  piece:
            raise RuntimeError("error verifying piece index '%d'" % index)

class TorrentServer(netius.StreamServer):

    def __init__(self, *args, **kwargs):
        netius.StreamServer.__init__(self, *args, **kwargs)
        self.peer_id = self._generate_id()
        self.client = netius.clients.TorrentClient(*args, **kwargs)

    def download(self, target_path, torrent_path = None, info_hash = None):
        """
        Starts the "downloading" process of a torrent associated file
        using the defined peer to peer torrent strategy suing either
        the provided torrent path as reference or just the info hash
        of the file that is going to be downloaded.

        Note that if only the info hash is provided a DHT bases strategy
        is going to be used to retrieve the peers list.

        The returned value is the task entity representing the newly created
        task for the downloading of the requested file, this object may be
        used for the operations and listening of events.

        @type target_path: String
        @param target_path: The path to the file that will be used to store
        the binary information resulting from the download, this file may also
        be used to store some temporary information on state of download.
        @type torrent_path: String
        @param torrent_path: The path to the file that contains the torrent
        information that is going to be used for file processing.
        @type info_hash: String
        @param info_hash: The info hash value of the file that is going
        to be downloaded, may be used for magnet torrents (DHT).
        @rtype: TorrentTask
        @return: The torrent task object that represents the task that has been
        created for downloading of the requested file.
        """

        task = TorrentTask(
            self,
            target_path,
            torrent_path = torrent_path,
            info_hash = info_hash
        )
        task.connect_peers()
        return task

    def _generate_id(self):
        random = str(uuid.uuid4())
        hash = hashlib.sha1(random)
        digest = hash.hexdigest()
        id = "-NE1000-%s" % digest[:12]
        return id

if __name__ == "__main__":
    def on_piece(task, index):
        speed = task.speed()
        speed_s = netius.common.size_round_unit(speed)
        print "%s/s" % speed_s

    torrent_server = TorrentServer()
    task = torrent_server.download("C:/tobias.download", "C:\ubuntu.torrent")
    task.bind("piece", on_piece)
    torrent_server.serve(env = True)
<commit_msg>tiny refactor<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

# Hive Netius System
# Copyright (C) 2008-2012 Hive Solutions Lda.
#
# This file is part of Hive Netius System.
#
# Hive Netius System is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hive Netius System is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hive Netius System. If not, see <http://www.gnu.org/licenses/>.

__author__ = "João Magalhães joamag@hive.pt>"
""" The author(s) of the module """

__version__ = "1.0.0"
""" The version of the module """

__revision__ = "$LastChangedRevision$"
""" The revision number of the module """

__date__ = "$LastChangedDate$"
""" The last change date of the module """

__copyright__ = "Copyright (c) 2008-2012 Hive Solutions Lda."
""" The copyright for the module """

__license__ = "GNU General Public License (GPL), Version 3"
""" The license for the module """

import math
import uuid
import time
import types
import struct
import hashlib

import netius.common
import netius.clients

ID_STRING = "NE1000"
""" Text value that is going to be used to identify the agent
of torrent against the other peers, should be a join of both
the abbreviation of the agent name and version """

BLOCK_SIZE = 16384
""" The typical size of block that is going to be retrieved
using the current torrent infra-structure, this value conditions
most of the torrent operations and should be defined carefully """

class Pieces(netius.Observable):
    """
    Class that represents the logical structure of a file that is
    divided into pieces and blocks as a hierarchy, this class is
    responsible for the management of the data structures of such
    data storage model.
    """

    def __init__(self, owner, number_pieces, number_blocks):
        netius.Observable.__init__(self)

        self.owner = owner
        self.number_pieces = number_pieces
        self.number_blocks = number_blocks
        self.bitfield = [True for _index in xrange(number_pieces)]
        self.mask = [True for _index in xrange(number_pieces * number_blocks)]

    def pop_block(self, bitfield):
        index = 0
        result = self._and(bitfield, self.bitfield)
        for bit in result:
            if bit == True: break
            index += 1

        if index == len(result): return None

        begin = self.update_block(index)
        return (index, begin)

    def mark_block(self, index, begin):
        base = index * self.number_blocks
        block_index = begin / BLOCK_SIZE
        self.mask[base + block_index] = False
        self.trigger("block", self, index, begin)
        self.update_piece(index)

    def update_block(self, index):
        base = index * self.number_blocks

        for block_index in xrange(self.number_blocks):
            state = self.mask[base + block_index]
            if state == True: break

        begin = block_index * BLOCK_SIZE
        self.mark_block(index, begin)
        return begin

    def update_piece(self, index):
        base = index * self.number_blocks
        piece_state = False

        for block_index in xrange(self.number_blocks):
            state = self.mask[base + block_index]
            if state == False: continue
            piece_state = True
            break

        self.bitfield[index] = piece_state
        if piece_state == False: self.trigger("piece", self, index)

    def _and(self, first, second):
        result = []
        for _first, _second in zip(first, second):
            if _first and _second: value = True
            else: value = False
            result.append(value)
        return result

class TorrentTask(netius.Observable):
    """
    Describes a task (operation) that is going to be performed
    using the peer to peer mesh network of the torrent protocol.

    Each of the download operations should be able to be described
    by this task object (for latter reference).
    """

    def __init__(self, owner, target_path, torrent_path = None, info_hash = None):
        netius.Observable.__init__(self)

        self.owner = owner
        self.target_path = target_path
        self.start = time.time()
        self.uploaded = 0
        self.downloaded = 0
        self.left = 0
        self.peers = []

        if torrent_path: self.info = self.load_info(torrent_path)
        else: self.info = dict(info_hash = info_hash)

        self.pieces_tracker()
        self.peers_tracker()

        self.load_file()
        self.load_pieces()

    def load_info(self, torrent_path):
        file = open(torrent_path, "rb")
        try: data = file.read()
        finally: file.close()

        struct = netius.common.bdecode(data)
        struct["info_hash"] = netius.common.info_hash(struct)
        return struct

    def on_block(self, task, index, begin):
        self.trigger("block", self, index, begin)

    def on_piece(self, task, index):
        self.verify_piece(index)
        self.trigger("piece", self, index)

    def load_file(self):
        self.file = open(self.target_path, "wb")
        self.file.seek(780140544 - 1)
        self.file.write("\0")
        self.file.flush()

    def load_pieces(self):
        number_pieces = self.info["number_pieces"]
        number_blocks = self.info["number_blocks"]
        self.requested = Pieces(self, number_pieces, number_blocks)
        self.stored = Pieces(self, number_pieces, number_blocks)
        self.stored.bind("block", self.on_block)
        self.stored.bind("piece", self.on_piece)

    def pieces_tracker(self):
        info = self.info.get("info", {})
        pieces = info.get("pieces", "")
        piece_length = info.get("piece length", 1)
        number_blocks = math.ceil(float(piece_length) / float(BLOCK_SIZE))
        number_blocks = int(number_blocks)
        self.info["pieces"] = [piece for piece in netius.common.chunks(pieces, 20)]
        self.info["number_pieces"] = len(self.info["pieces"])
        self.info["number_blocks"] = number_blocks

    def set_data(self, data, index, begin):
        piece_length = self.info["info"]["piece length"]
        self.file.seek(index * piece_length + begin)
        self.file.write(data)
        self.file.flush()
        self.stored.mark_block(index, begin)
        self.downloaded += len(data)

    def peers_tracker(self):
        """
        Tries to retrieve as much information as possible about the
        peers from the currently loaded tracker information.

        It's possible that no tracker information exits for the current
        task and for such situations no state change will occur.
        """

        # retrieves both the announce and the announce list structure from
        # the current info dictionary and uses both of them to create the
        # final list containing the various addresses of trackers, then
        # iterates over each of the trackers to retrieve the information
        # about the various peers associated with the torrent file
        announce = self.info.get("announce", None)
        announce_list = self.info.get("announce-list", [[announce]])
        for tracker in announce_list:
            tracker_url = tracker[0]
            result = netius.clients.HTTPClient.get_s(
                tracker_url,
                params = dict(
                    info_hash = self.info["info_hash"],
                    peer_id = self.owner.peer_id,
                    port = "1000",
                    uploaded = self.uploaded,
                    downloaded = self.downloaded,
                    left = self.left,
                    compact = "0"
                ),
                async = False
            )

            data = result["data"]
            if not data: continue

            response = netius.common.bdecode(data)
            peers = response["peers"]

            if type(peers) == types.DictType:
                self.peers = peers
                continue

            peers = [peer for peer in netius.common.chunks(peers, 6)]
            for peer in peers:
                address, port = struct.unpack("!LH", peer)
                ip = netius.common.addr_to_ip4(address)
                peer = dict(
                    ip = ip,
                    port = port
                )
                self.peers.append(peer)

    def connect_peers(self):
        for peer in self.peers: self.connect_peer(peer)

    def connect_peer(self, peer):
        self.owner.client.peer(self, peer["ip"], peer["port"])

    def speed(self):
        """
        Retrieves a float number representing the global speed
        of the task in bytes per second, this value is computed
        using the original creation time of the task and so it
        may not represent the most accurate speedup.

        @rtype: float
        @return: The current speed of download, defined as bytes
        per second from the original task creation time.
        """

        current = time.time()
        delta = current - self.start
        bytes_second = self.downloaded / delta
        return bytes_second

    def pop_block(self, bitfield):
        return self.requested.pop_block(bitfield)

    def verify_piece(self, index):
        file = open(self.target_path, "rb")
        try: self._verify_piece(index, file)
        finally: file.close()

    def _verify_piece(self, index, file):
        piece = self.info["pieces"][index]
        piece_length = self.info["info"]["piece length"]
        file = open(self.target_path, "rb")
        file.seek(index * piece_length)
        pending = piece_length
        hash = hashlib.sha1()
        while True:
            if pending == 0: break
            count = BLOCK_SIZE if pending > BLOCK_SIZE else pending
            data = file.read(count)
            hash.update(data)
            pending -= count
        digest = hash.digest()
        if digest ==  piece: return
        raise netius.DataError("Verifying piece index '%d'" % index)

class TorrentServer(netius.StreamServer):

    def __init__(self, *args, **kwargs):
        netius.StreamServer.__init__(self, *args, **kwargs)
        self.peer_id = self._generate_id()
        self.client = netius.clients.TorrentClient(*args, **kwargs)

    def download(self, target_path, torrent_path = None, info_hash = None):
        """
        Starts the "downloading" process of a torrent associated file
        using the defined peer to peer torrent strategy suing either
        the provided torrent path as reference or just the info hash
        of the file that is going to be downloaded.

        Note that if only the info hash is provided a DHT bases strategy
        is going to be used to retrieve the peers list.

        The returned value is the task entity representing the newly created
        task for the downloading of the requested file, this object may be
        used for the operations and listening of events.

        @type target_path: String
        @param target_path: The path to the file that will be used to store
        the binary information resulting from the download, this file may also
        be used to store some temporary information on state of download.
        @type torrent_path: String
        @param torrent_path: The path to the file that contains the torrent
        information that is going to be used for file processing.
        @type info_hash: String
        @param info_hash: The info hash value of the file that is going
        to be downloaded, may be used for magnet torrents (DHT).
        @rtype: TorrentTask
        @return: The torrent task object that represents the task that has been
        created for downloading of the requested file.
        """

        task = TorrentTask(
            self,
            target_path,
            torrent_path = torrent_path,
            info_hash = info_hash
        )
        task.connect_peers()
        return task

    def _generate_id(self):
        random = str(uuid.uuid4())
        hash = hashlib.sha1(random)
        digest = hash.hexdigest()
        id = "-%s-%s" % (ID_STRING, digest[:12])
        return id

if __name__ == "__main__":
    def on_piece(task, index):
        speed = task.speed()
        speed_s = netius.common.size_round_unit(speed)
        print "%s/s" % speed_s

    torrent_server = TorrentServer()
    task = torrent_server.download("C:/tobias.download", "C:\ubuntu.torrent")
    task.bind("piece", on_piece)
    torrent_server.serve(env = True)
<|endoftext|>


<commit_before>"""
Module for rover events.

"""
__author__ = 'Salman Hashmi'
__license__ = 'BSD License'

import numpy as np

def velocity_exceeded(Rover):
    """Check if velocity is under max_vel."""
    return Rover.vel < Rover.max_vel

def front_path_clear(Rover):
    """Check if sufficient room ahead."""
    return len(Rover.nav_angles) >= Rover.go_forward

def can_pickup_sample(Rover):
    """Check if Rover ready to pickup sample."""
    return Rover.near_sample and Rover.vel <= 0.1
<commit_msg>define obstacle-detecting events<commit_after>"""
Module for rover events.

"""

__author__ = 'Salman Hashmi'
__license__ = 'BSD License'

import numpy as np

def velocity_exceeded(Rover):
    """Check if velocity is under max_vel."""
    return Rover.vel < Rover.max_vel

def front_path_clear(Rover):
    """Check if sufficient room ahead."""
    return len(Rover.nav_angles) >= Rover.go_forward

def at_front_obstacle(Rover):
    """Check if rover is up against some obstacle."""
    front_stop_forward = 600
    return len(Rover.nav_angles) < front_stop_forward

def at_left_obstacle(Rover):
    """Check if obstacle is left of rover."""
    return len(Rover.nav_angles_left) < Rover.stop_forward

def can_pickup_sample(Rover):
    """Check if Rover ready to pickup sample."""
    return Rover.near_sample and Rover.vel <= 0.1
<|endoftext|>


<commit_before>"""The system {x(t+1) = a x(t) + w(t) + u(t); y(t) = x(t) + v(t)}."""
class Plant:
    def __init__(self, a, draw_x0, draw_w, draw_v):
        self.a = a
        self.draw_x0 = draw_x0
        self.draw_w = draw_w
        self.draw_v = draw_v

        self.x = draw_x0()
        self.y = self.x + self.draw_v()

    def step(self, u):
        self.x = self.a * self.x + self.draw_w() + u
        self.y = self.x + self.draw_v()

class Channel:
    def __init__(self, draw_n):
        self.draw_n = draw_n

    def transmit(self, a):
        return a + self.draw_n()

"""A cost function of the form
    J(T) = 1/T (F x(T+1)² + Σ{t = 1..t}(Q x(t)² + R u(t)²))."""
class LQGCost:
    def __init__(self, plant, Q, R, F):
        self.plant = plant
        self.Q = Q
        self.R = R
        self.F = F

        self.x_sum = 0.0
        self.u_sum = 0.0
        self.last_x = plant.x

    """To be called immediately after plant.step()"""
    def step(self, u):
        self.x_sum += self.Q * self.last_x * self.last_x
        self.u_sum += self.R * u * u
        self.last_x = self.plant.x

    def evaluate(self):
        return self.x_sum + self.u_sum + self.F * self.last_x
<commit_msg>Corrected docstring positions<commit_after>class Plant:
    """The system {x(t+1) = a x(t) + w(t) + u(t); y(t) = x(t) + v(t)}."""
    def __init__(self, a, draw_x0, draw_w, draw_v):
        self.a = a
        self.draw_x0 = draw_x0
        self.draw_w = draw_w
        self.draw_v = draw_v

        self.x = draw_x0()
        self.y = self.x + self.draw_v()

    def step(self, u):
        self.x = self.a * self.x + self.draw_w() + u
        self.y = self.x + self.draw_v()

class Channel:
    def __init__(self, draw_n):
        self.draw_n = draw_n

    def transmit(self, a):
        return a + self.draw_n()

class LQGCost:
    """A cost function of the form
    J(T) = 1/T (F x(T+1)² + Σ{t = 1..t}(Q x(t)² + R u(t)²))."""
    def __init__(self, plant, Q, R, F):
        self.plant = plant
        self.Q = Q
        self.R = R
        self.F = F

        self.x_sum = 0.0
        self.u_sum = 0.0
        self.last_x = plant.x

    def step(self, u):
        """To be called immediately after plant.step()"""
        self.x_sum += self.Q * self.last_x * self.last_x
        self.u_sum += self.R * u * u
        self.last_x = self.plant.x

    def evaluate(self):
        """If called after T steps (i.e. at time T+1), will return J(T)."""
        return self.x_sum + self.u_sum + self.F * self.last_x
<|endoftext|>


<commit_before>from flask import Flask, session, g
from flaskext.redis import Redis

def create_app():
    from codebox.apps.snippets.views import frontend
    from codebox.apps.auth.views import auth
    from codebox.apps.auth.models import User

    app = Flask(__name__)
    app.config.from_object('codebox.conf.Config')

    app.register_module(frontend)
    app.register_module(auth)
    #app.register_module(yammer)

    db = Redis(app)
    db.init_app(app)

    app.db = db

    @app.before_request
    def before_request():
        if 'userid' in session:
            try:
                g.user = User.objects.get(session['userid'])
            except User.DoesNotExist:
                pass

    from codebox.utils.syntax import colorize
    app.jinja_env.filters['colorize'] = colorize

    return app

<commit_msg>Ensure g.user always exists<commit_after>from flask import Flask, session, g
from flaskext.redis import Redis

def create_app():
    from codebox.apps.snippets.views import frontend
    from codebox.apps.auth.views import auth
    from codebox.apps.auth.models import User

    app = Flask(__name__)
    app.config.from_object('codebox.conf.Config')

    app.register_module(frontend)
    app.register_module(auth)
    #app.register_module(yammer)

    db = Redis(app)
    db.init_app(app)

    app.db = db

    @app.before_request
    def before_request():
        g.user = None

        if 'userid' in session:
            try:
                g.user = User.objects.get(session['userid'])
            except User.DoesNotExist:
                pass

    from codebox.utils.syntax import colorize
    app.jinja_env.filters['colorize'] = colorize

    return app

<|endoftext|>


<commit_before>import numpy as np
from mock import MagicMock, patch

from glue.qt.tests.test_mouse_mode import TestMouseMode, Event

from ..contour_selection import ContourMode, contour_to_roi

class TestContourMode(TestMouseMode):

    def mode_factory(self):
        return ContourMode

    def test_roi_before_event(self):
        data = MagicMock()
        roi = self.mode.roi(data)
        assert roi is None

    def test_roi(self):
        with patch('glue.qt.mouse_mode.contour_to_roi') as cntr:
            data = MagicMock()
            e = Event(1, 2)
            self.mode.press(e)
            self.mode.roi(data)
            cntr.assert_called_once_with(1, 2, data)

class TestContourToRoi(object):

    def test_roi(self):
        with patch('glue.core.util.point_contour') as point_contour:
            point_contour.return_value = np.array([[1, 2], [2, 3]])
            p = contour_to_roi(1, 2, None)
            np.testing.assert_array_almost_equal(p.vx, [1, 2])
            np.testing.assert_array_almost_equal(p.vy, [2, 3])

    def test_roi_null_result(self):
        with patch('glue.core.util.point_contour') as point_contour:
            point_contour.return_value = None
            p = contour_to_roi(1, 2, None)
            assert p is None
<commit_msg>Fixed module name in test<commit_after>import numpy as np
from mock import MagicMock, patch

from glue.qt.tests.test_mouse_mode import TestMouseMode, Event

from ..contour_selection import ContourMode, contour_to_roi

class TestContourMode(TestMouseMode):

    def mode_factory(self):
        return ContourMode

    def test_roi_before_event(self):
        data = MagicMock()
        roi = self.mode.roi(data)
        assert roi is None

    def test_roi(self):
        with patch('glue_exp.tools.contour_selection.contour_selection.contour_to_roi') as cntr:
            data = MagicMock()
            e = Event(1, 2)
            self.mode.press(e)
            self.mode.roi(data)
            cntr.assert_called_once_with(1, 2, data)

class TestContourToRoi(object):

    def test_roi(self):
        with patch('glue.utils.matplotlib.point_contour') as point_contour:
            point_contour.return_value = np.array([[1, 2], [2, 3]])
            p = contour_to_roi(1, 2, None)
            np.testing.assert_array_almost_equal(p.vx, [1, 2])
            np.testing.assert_array_almost_equal(p.vy, [2, 3])

    def test_roi_null_result(self):
        with patch('glue.utils.matplotlib.point_contour') as point_contour:
            point_contour.return_value = None
            p = contour_to_roi(1, 2, None)
            assert p is None
<|endoftext|>


<commit_before>from django.core.management.base import BaseCommand, CommandError
from django.core.mail import EmailMessage
import os
import requests
import shutil
from subprocess import call
from django.core.mail import EmailMessage

def sorted_ls(path):
    '''
    takes {
        path : Path to the folder location
    }
    returns {
        list of file-names sorted based on time
    }
    '''
    mtime = lambda f: os.stat(os.path.join(path, f)).st_mtime
    return list(sorted(os.listdir(path), key=mtime))

def connected_to_internet(url='http://www.google.com/', timeout=5):
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
    	print "Error occurred in : ", str(__file__)
        print("No internet connection available.")
    return False

class Command(BaseCommand):
	help = 'Will call the script to send the captured json and data files.'

	def handle(self, *args, **kwargs):
		if connected_to_internet() is False:
			return None

		syncdata_folder_path = os.path.dirname(__file__).split('/management')[0] + '/syncdata'
		list_of_syncdata_folders = []
		sent_folder_path = os.path.dirname(__file__).split('/management')[0] + '/sent_syncdata_files'

		if not os.path.exists(sent_folder_path):
			os.makedirs(sent_folder_path)

		try:
			# we take list of directories sorted by 'last modified time' so that changes captured first are sent first
			list_of_syncdata_folders = sorted_ls(syncdata_folder_path)
			print list_of_syncdata_folders
		except Exception as error:
			print 'File name and location is: ', str(__file__)
			print 'Error is : ', error

		for folder_name in list_of_syncdata_folders:
			print '**'*30
			path = syncdata_folder_path + '/' + folder_name
			list_of_syncdata_files = os.listdir(path)
			if connected_to_internet() is True:
				mail = EmailMessage()
				tstamp = folder_name
				mail.subject= "SYNCDATA_"+tstamp

				for filename in list_of_syncdata_files:
					file_path = path + '/' + filename
					mail.attach_file(file_path)
					print file_path

				mail.from_email = "Gstudio <t.metastudio@gmail.com>"
				mail.to = ['djangotest94@gmail.com']
				mail.send()
				shutil.move(path,sent_folder_path)<commit_msg>empty mails will not be sent<commit_after>from django.core.management.base import BaseCommand, CommandError
from django.core.mail import EmailMessage
import os
import requests
import shutil
from subprocess import call
from django.core.mail import EmailMessage

def sorted_ls(path):
    '''
    takes {
        path : Path to the folder location
    }
    returns {
        list of file-names sorted based on time
    }
    '''
    mtime = lambda f: os.stat(os.path.join(path, f)).st_mtime
    return list(sorted(os.listdir(path), key=mtime))

def connected_to_internet(url='http://www.google.com/', timeout=5):
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
    	print "Error occurred in : ", str(__file__)
        print("No internet connection available.")
    return False

class Command(BaseCommand):
	help = 'Will call the script to send the captured json and data files.'

	def handle(self, *args, **kwargs):
		if connected_to_internet() is False:
			return None

		syncdata_folder_path = os.path.dirname(__file__).split('/management')[0] + '/syncdata'
		list_of_syncdata_folders = []
		sent_folder_path = os.path.dirname(__file__).split('/management')[0] + '/sent_syncdata_files'

		if not os.path.exists(sent_folder_path):
			os.makedirs(sent_folder_path)

		try:
			# we take list of directories sorted by 'last modified time' so that changes captured first are sent first
			list_of_syncdata_folders = sorted_ls(syncdata_folder_path)
			print list_of_syncdata_folders
		except Exception as error:
			print 'File name and location is: ', str(__file__)
			print 'Error is : ', error

		for folder_name in list_of_syncdata_folders:
			print '**'*30
			path = syncdata_folder_path + '/' + folder_name
			list_of_syncdata_files = os.listdir(path)
			if connected_to_internet() is True:
				mail = EmailMessage()
				tstamp = folder_name
				mail.subject= "SYNCDATA_"+tstamp

				folder_empty = 1
				for filename in list_of_syncdata_files:
					file_path = path + '/' + filename
					mail.attach_file(file_path)
					folder_empty = 0
					print file_path

				mail.from_email = "Gstudio <t.metastudio@gmail.com>"
				mail.to = ['djangotest94@gmail.com']
				if folder_empty == 0:
					mail.send()

				shutil.move(path,sent_folder_path)<|endoftext|>


<commit_before>from __future__ import absolute_import, unicode_literals

import re
from datetime import datetime

from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.template.defaultfilters import slugify
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from modelcluster.models import ClusterableModel
from modelcluster.fields import ParentalKey
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel

from polymorphic.models import PolymorphicModel

@python_2_unicode_compatible
class Segment(ClusterableModel):
    """Model for a new segment"""
    name = models.CharField(max_length=255)
    create_date = models.DateTimeField(auto_now_add=True)
    edit_date = models.DateTimeField(auto_now=True)
    enable_date = models.DateTimeField(null=True, editable=False)
    disable_date = models.DateTimeField(null=True, editable=False)
    visit_count = models.PositiveIntegerField(default=0, editable=False)
    STATUS_CHOICES = (
        ('enabled', 'Enabled'),
        ('disabled', 'Disabled'),
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="enabled")

    panels = [
        FieldPanel('name'),
        FieldPanel('status'),
    ]

    def __str__(self):
        return self.name

    def encoded_name(self):
        """Returns a string with a slug for the segment"""
        return slugify(self.name.lower())

def check_status_change(sender, instance, *args, **kwargs):
    """Check if the status has changed. Alter dates accordingly."""
    try:
        original_status = sender.objects.get(pk=instance.id).status
    except sender.DoesNotExist:
        original_status = ""

    if original_status != instance.status:
        if instance.status == "enabled":
            instance.enable_date = datetime.now()
            instance.visit_count = 0
            return instance
        if instance.status == "disabled":
            instance.disable_date = datetime.now()

pre_save.connect(check_status_change, sender=Segment)

@python_2_unicode_compatible
class AbstractBaseRule(PolymorphicModel):
    """Base for creating rules to segment users with"""
    segment = ParentalKey('Segment', related_name="rules")

    def test_user(self, request):
        """Test if the user matches this rule"""
        return True

    def __str__(self):
        return "Segmentation rule"

@python_2_unicode_compatible
class TimeRule(AbstractBaseRule):
    """Time rule to segment users based on a start and end time"""
    start_time = models.TimeField(_("Starting time"))
    end_time = models.TimeField(_("Ending time"))

    panels = [
        FieldPanel('start_time'),
        FieldPanel('end_time'),
    ]

    def __init__(self, *args, **kwargs):
        super(TimeRule, self).__init__(*args, **kwargs)

    def test_user(self, request):
        current_time = self.get_current_time()
        starting_time = self.start_time
        ending_time = self.end_time

        return starting_time <= current_time <= ending_time

    def get_current_time(self):
        """Mockable function for testing purposes"""
        return datetime.now().time()

    def __str__(self):
        return '{} - {}'.format(self.start_time, self.end_time)

@python_2_unicode_compatible
class ReferralRule(AbstractBaseRule):
    """Referral rule to segment users based on a regex test"""
    regex_string = models.TextField(_("Regex string to match the referer with"))

    panels = [
        FieldPanel('regex_string'),
    ]

    def __init__(self, *args, **kwargs):
        super(ReferralRule, self).__init__(*args, **kwargs)

    def test_user(self, request):
        pattern = re.compile(self.regex_string)

        if 'HTTP_REFERER' in request.META:
            referer = request.META['HTTP_REFERER']
            if pattern.search(referer):
                return True
        return False

    def __str__(self):
        return '{}'.format(self.regex_string)

@python_2_unicode_compatible
class VisitCountRule(AbstractBaseRule):
    """Visit count rule to segment users based on amount of visits"""
    OPERATOR_CHOICES = (
        ('more_than', 'More than'),
        ('less_than', 'Less than'),
        ('equal_to', 'Equal to'),
    )
    operator = models.CharField(max_length=20, choices=OPERATOR_CHOICES, default="ht")
    count = models.PositiveSmallIntegerField(default=0, null=True)
    counted_page = models.ForeignKey(
        'wagtailcore.Page',
        null=False,
        blank=False,
        on_delete=models.CASCADE,
        related_name='+',
    )

    panels = [
        FieldPanel('operator'),
        FieldPanel('count'),
        PageChooserPanel('counted_page'),
    ]

    def __init__(self, *args, **kwargs):
        super(VisitCountRule, self).__init__(*args, **kwargs)

    def test_user(self, request):
        operator = self.operator
        segment_count = self.count

        # TODO: Figure out a way to have a correct count before the middleware
        # initiates the test function

        def get_visit_count(request):
            """Search through the sessions to get the page visit count
            corresponding to the request."""
            for page in request.session['visit_count']:
                if page['path'] == request.path:
                    return page['count']

        visit_count = get_visit_count(request)

        if visit_count and operator == "more_than":
            if visit_count > segment_count:
                return True
        elif visit_count and operator == "less_than":
            if visit_count < segment_count:
                return True
        elif visit_count and operator == "equal_to":
            if visit_count == segment_count:
                return True
        return False

    def __str__(self):
        operator_display = self.get_operator_display()
        return '{} {}'.format(operator_display, self.count)
<commit_msg>adds TranslatablePage model<commit_after>from __future__ import absolute_import, unicode_literals

import re
from datetime import datetime

from django.db import models
from django.db.models import Q
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.template.defaultfilters import slugify
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from modelcluster.models import ClusterableModel
from modelcluster.fields import ParentalKey
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel
from wagtail.wagtailcore.models import Page

from polymorphic.models import PolymorphicModel

@python_2_unicode_compatible
class Segment(ClusterableModel):
    """Model for a new segment"""
    name = models.CharField(max_length=255)
    create_date = models.DateTimeField(auto_now_add=True)
    edit_date = models.DateTimeField(auto_now=True)
    enable_date = models.DateTimeField(null=True, editable=False)
    disable_date = models.DateTimeField(null=True, editable=False)
    visit_count = models.PositiveIntegerField(default=0, editable=False)
    STATUS_CHOICES = (
        ('enabled', 'Enabled'),
        ('disabled', 'Disabled'),
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="enabled")

    panels = [
        FieldPanel('name'),
        FieldPanel('status'),
    ]

    def __str__(self):
        return self.name

    def encoded_name(self):
        """Returns a string with a slug for the segment"""
        return slugify(self.name.lower())

def check_status_change(sender, instance, *args, **kwargs):
    """Check if the status has changed. Alter dates accordingly."""
    try:
        original_status = sender.objects.get(pk=instance.id).status
    except sender.DoesNotExist:
        original_status = ""

    if original_status != instance.status:
        if instance.status == "enabled":
            instance.enable_date = datetime.now()
            instance.visit_count = 0
            return instance
        if instance.status == "disabled":
            instance.disable_date = datetime.now()

pre_save.connect(check_status_change, sender=Segment)

@python_2_unicode_compatible
class AbstractBaseRule(PolymorphicModel):
    """Base for creating rules to segment users with"""
    segment = ParentalKey('Segment', related_name="rules")

    def test_user(self, request):
        """Test if the user matches this rule"""
        return True

    def __str__(self):
        return "Segmentation rule"

@python_2_unicode_compatible
class TimeRule(AbstractBaseRule):
    """Time rule to segment users based on a start and end time"""
    start_time = models.TimeField(_("Starting time"))
    end_time = models.TimeField(_("Ending time"))

    panels = [
        FieldPanel('start_time'),
        FieldPanel('end_time'),
    ]

    def __init__(self, *args, **kwargs):
        super(TimeRule, self).__init__(*args, **kwargs)

    def test_user(self, request):
        current_time = self.get_current_time()
        starting_time = self.start_time
        ending_time = self.end_time

        return starting_time <= current_time <= ending_time

    def get_current_time(self):
        """Mockable function for testing purposes"""
        return datetime.now().time()

    def __str__(self):
        return '{} - {}'.format(self.start_time, self.end_time)

@python_2_unicode_compatible
class ReferralRule(AbstractBaseRule):
    """Referral rule to segment users based on a regex test"""
    regex_string = models.TextField(_("Regex string to match the referer with"))

    panels = [
        FieldPanel('regex_string'),
    ]

    def __init__(self, *args, **kwargs):
        super(ReferralRule, self).__init__(*args, **kwargs)

    def test_user(self, request):
        pattern = re.compile(self.regex_string)

        if 'HTTP_REFERER' in request.META:
            referer = request.META['HTTP_REFERER']
            if pattern.search(referer):
                return True
        return False

    def __str__(self):
        return '{}'.format(self.regex_string)

@python_2_unicode_compatible
class VisitCountRule(AbstractBaseRule):
    """Visit count rule to segment users based on amount of visits"""
    OPERATOR_CHOICES = (
        ('more_than', 'More than'),
        ('less_than', 'Less than'),
        ('equal_to', 'Equal to'),
    )
    operator = models.CharField(max_length=20, choices=OPERATOR_CHOICES, default="ht")
    count = models.PositiveSmallIntegerField(default=0, null=True)
    counted_page = models.ForeignKey(
        'wagtailcore.Page',
        null=False,
        blank=False,
        on_delete=models.CASCADE,
        related_name='+',
    )

    panels = [
        FieldPanel('operator'),
        FieldPanel('count'),
        PageChooserPanel('counted_page'),
    ]

    def __init__(self, *args, **kwargs):
        super(VisitCountRule, self).__init__(*args, **kwargs)

    def test_user(self, request):
        operator = self.operator
        segment_count = self.count

        # TODO: Figure out a way to have a correct count before the middleware
        # initiates the test function

        def get_visit_count(request):
            """Search through the sessions to get the page visit count
            corresponding to the request."""
            for page in request.session['visit_count']:
                if page['path'] == request.path:
                    return page['count']

        visit_count = get_visit_count(request)

        if visit_count and operator == "more_than":
            if visit_count > segment_count:
                return True
        elif visit_count and operator == "less_than":
            if visit_count < segment_count:
                return True
        elif visit_count and operator == "equal_to":
            if visit_count == segment_count:
                return True
        return False

    def __str__(self):
        operator_display = self.get_operator_display()
        return '{} {}'.format(operator_display, self.count)

class PersonalisablePage(Page):
    canonical_page = models.ForeignKey(
        'self', related_name='variations', blank=True,
        null=True, on_delete=models.SET_NULL
    )

    segment = models.ForeignKey(
        Segment, related_name='segments', on_delete=models.PROTECT
    )

    def __str__(self):
        return "{} ({})".format(self.title, self.segment)

    def get_variations(self, only_live=True):
        canonical_page = self.canonical_page or self
        variations = PersonalisablePage.objects.filter(
            Q(canonical_page=canonical_page) |
            Q(pk=canonical_page.pk)
        ).exclude(pk=self.pk)

        if only_live:
            variations = variations.live()

        return variations

    def get_variation_parent(self, segment):
        site = self.get_site()

        variation_parent = (
            PersonalisablePage.objects
            .filter(
                canonical_page=self.get_parent()
                segment=segment,
                path__startswith=site.root_page.path
            ).first()
        )
        return variation_parent

    def create_variation(self, segment, parent=None):
        slug = "{}-{}".format(self.slug, segment.encoded_name())

        if not parent:
            parent = self.get_variation_parent(segment)

        update_attrs = {
            'title': self.title,
            'slug': slug,
            'segment': segment,
            'live': False,
            'canonical_page': self,
        }

        model_class = self.content_type.model_class()
        new_page = model_class(**update_attrs)
        parent.add_child()

<|endoftext|>


<commit_before>#!/usr/bin/python
# Copyright 2013 Google Inc. All Rights Reserved.
#
# 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.

"""Get the accounts desired to be present on the VM."""

import ast
import logging
import time
import urllib2

ATTRIBUTES_URL = (
    'http://metadata/computeMetadata/v1/project/attributes/?recursive=true&%s')
ACCOUNTS_URL = (
    'http://metadata/computeMetadata/v1/project/attributes/sshKeys?%s')
WAIT_FOR_CHANGE = 'wait_for_change=true&last_etag=%s&timeout_sec=%s'

def AccountDataToDictionary(data):
  """Given sshKeys attribute data, construct a usermap.

  Args:
    data: The data returned from the metadata server's sshKeys attribute.

  Returns:
    A map of {'username': ssh_keys_list}.
  """
  lines = [line for line in data.splitlines() if line]
  usermap = {}
  for line in lines:
    split_line = line.split(':', 1)
    if len(split_line) != 2:
      logging.warning(
          'sshKey is not a complete entry: %s', split_line)
      continue
    user, key = split_line
    if not user in usermap:
      usermap[user] = []
    usermap[user].append(key)
  logging.debug('User accounts: {0}'.format(usermap))
  return usermap

class DesiredAccounts(object):
  """Interface to determine the accounts desired on this instance."""

  def __init__(self, time_module=time, urllib2_module=urllib2):
    self.urllib2 = urllib2_module
    self.time = time_module
    self.ssh_keys_etag = 0

  def _MakeHangingGetRequest(self, url, etag=0, timeout_secs=300):
    """Makes a get request for the url and specifies wait_for_change.
    """
    wait_for_change_query = WAIT_FOR_CHANGE % (etag, timeout_secs)
    request_url = url % wait_for_change_query
    logging.debug('Getting url: %s', request_url)
    request = urllib2.Request(request_url)
    request.add_header('X-Google-Metadata-Request', 'True')
    return self.urllib2.urlopen(request)

  def _WaitForSshKeysAttribute(self, timeout_secs=600):
    """Waits for sshKeys attribute to be created.

    Returns:
      true if the sshKeys attribute exists, or else false.
    """
    logging.debug('Checking if sshKeys attribute exists.')
    etag = 0
    start_time = self.time.time()
    while self.time.time() - start_time < timeout_secs:
      try:
        response = self._MakeHangingGetRequest(
            ATTRIBUTES_URL, etag=0)
        response_info = response.info()
        if response_info and response_info.has_key('etag'):
          etag = response_info.getheader('etag')
        attributes_string = response.read()
        logging.debug('project attributes: %s', attributes_string)
        attributes = ast.literal_eval(attributes_string)
        if attributes and attributes.has_key('sshKeys'):
          return True
      except (urllib2.URLError, ValueError) as e:
        logging.warning(
            'Error while trying to fetch attributes list: %s',
            e)
    logging.debug('Unable to find sshKeys attribute')
    return False

  def GetDesiredAccounts(self):
    """Get a list of the accounts desired on the system.

    Returns:
      A dict of the form: {'username': ['sshkey1, 'sshkey2', ...]}.
    """
    logging.debug('Getting desired accounts from metadata.')
    try:
      self._WaitForSshKeysAttribute()
      response = self._MakeHangingGetRequest(
          ACCOUNTS_URL,
          etag=self.ssh_keys_etag)
      account_data = response.read()
      if response.info() and response.info().has_key('etag'):
        self.ssh_keys_etag = response.info().getheader('etag')
      if not account_data:
        return {}
      return AccountDataToDictionary(account_data)
    except urllib2.URLError as e:
      logging.debug('error while trying to fetch accounts: %s', e)
    return {}  # No desired accounts at this time.
<commit_msg>use the etag value from previous call when fetching attributes<commit_after>#!/usr/bin/python
# Copyright 2013 Google Inc. All Rights Reserved.
#
# 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.

"""Get the accounts desired to be present on the VM."""

import ast
import logging
import time
import urllib2

ATTRIBUTES_URL = (
    'http://metadata/computeMetadata/v1/project/attributes/?recursive=true&%s')
ACCOUNTS_URL = (
    'http://metadata/computeMetadata/v1/project/attributes/sshKeys?%s')
WAIT_FOR_CHANGE = 'wait_for_change=true&last_etag=%s&timeout_sec=%s'

def AccountDataToDictionary(data):
  """Given sshKeys attribute data, construct a usermap.

  Args:
    data: The data returned from the metadata server's sshKeys attribute.

  Returns:
    A map of {'username': ssh_keys_list}.
  """
  lines = [line for line in data.splitlines() if line]
  usermap = {}
  for line in lines:
    split_line = line.split(':', 1)
    if len(split_line) != 2:
      logging.warning(
          'sshKey is not a complete entry: %s', split_line)
      continue
    user, key = split_line
    if not user in usermap:
      usermap[user] = []
    usermap[user].append(key)
  logging.debug('User accounts: {0}'.format(usermap))
  return usermap

class DesiredAccounts(object):
  """Interface to determine the accounts desired on this instance."""

  def __init__(self, time_module=time, urllib2_module=urllib2):
    self.urllib2 = urllib2_module
    self.time = time_module
    self.ssh_keys_etag = 0

  def _MakeHangingGetRequest(self, url, etag=0, timeout_secs=300):
    """Makes a get request for the url and specifies wait_for_change.
    """
    wait_for_change_query = WAIT_FOR_CHANGE % (etag, timeout_secs)
    request_url = url % wait_for_change_query
    logging.debug('Getting url: %s', request_url)
    request = urllib2.Request(request_url)
    request.add_header('X-Google-Metadata-Request', 'True')
    return self.urllib2.urlopen(request)

  def _WaitForSshKeysAttribute(self, timeout_secs=600):
    """Waits for sshKeys attribute to be created.

    Returns:
      true if the sshKeys attribute exists, or else false.
    """
    logging.debug('Checking if sshKeys attribute exists.')
    etag = 0
    start_time = self.time.time()
    while self.time.time() - start_time < timeout_secs:
      try:
        response = self._MakeHangingGetRequest(
            ATTRIBUTES_URL, etag=etag)
        response_info = response.info()
        if response_info and response_info.has_key('etag'):
          etag = response_info.getheader('etag')
        attributes_string = response.read()
        logging.debug('project attributes: %s', attributes_string)
        attributes = ast.literal_eval(attributes_string)
        if attributes and attributes.has_key('sshKeys'):
          return True
      except (urllib2.URLError, ValueError) as e:
        logging.warning(
            'Error while trying to fetch attributes list: %s',
            e)
    logging.debug('Unable to find sshKeys attribute')
    return False

  def GetDesiredAccounts(self):
    """Get a list of the accounts desired on the system.

    Returns:
      A dict of the form: {'username': ['sshkey1, 'sshkey2', ...]}.
    """
    logging.debug('Getting desired accounts from metadata.')
    try:
      self._WaitForSshKeysAttribute()
      response = self._MakeHangingGetRequest(
          ACCOUNTS_URL,
          etag=self.ssh_keys_etag)
      account_data = response.read()
      if response.info() and response.info().has_key('etag'):
        self.ssh_keys_etag = response.info().getheader('etag')
      if not account_data:
        return {}
      return AccountDataToDictionary(account_data)
    except urllib2.URLError as e:
      logging.debug('error while trying to fetch accounts: %s', e)
    return {}  # No desired accounts at this time.
<|endoftext|>


<commit_before>import os
from discord.ext import commands
from discord.ext.commands import Bot
from datetime import datetime
import discord
from .utils import checks
from .utils.data import Data

import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web.settings')
django.setup()
from django.utils import timezone
from django.db import models
from squidbot.models import DiscordUser, Game, GameUser, Server, Role, GameSearch

DISCORD_MSG_CHAR_LIMIT = 2000

def paginate(content, *, length=DISCORD_MSG_CHAR_LIMIT, reserve=0):
    """
    Split up a large string or list of strings into chunks for sending to discord.
    """
    if type(content) == str:
        contentlist = content.split('\n')
    elif type(content) == list:
        contentlist = content
    else:
        raise ValueError("Content must be str or list, not %s" % type(content))

    chunks = []
    currentchunk = ''

    for line in contentlist:
        if len(currentchunk) + len(line) < length - reserve:
            currentchunk += line + '\n'
        else:
            chunks.append(currentchunk)
            currentchunk = ''

    if currentchunk:
        chunks.append(currentchunk)

    return chunks

class GamingUtils:
    def __init__(self):
        pass

    async def game_beautify(self, games, reserve=0):
        """
        Return a message of all games ready for displaying all pretty like
        """
        formatted_message = '**No games are currently in the database!\nStart playing some games to make the database better**'
        try:
            if len(games) == 0:
                games = Game.objects.all()

            formatted_message = '\n**Available games**\n'
            for game in games:
                if isinstance(game, GameSearch):
                    game = Game.objects.get(pk=game.pk)
                formatted_message += '`{0}:` {1}\n'.format(game.pk, game.name)
        except Exception as e:
            pass
        return paginate(formatted_message, reserve=reserve)[0]

    ####################
    # Search Utilities #
    ####################
    async def search_beautify(self, user, game, reserve=0):
        """
        Return a message of all user searches ready for displaying all pretty like
        """
        # Todo: How to filter all users and games people are searching based on params passed in
        if users:
            users = await self.search_user(users)
        elif games:
            if len(game) > 1:
                active_searches = GameSearch.objects.filter(cancelled=False, expire_date__gte=timezone.now())
                users = active_searches.filter(game__in=[game.pk])
            else:
                users = active_searches.filter(game=game, cancelled=False, expire_date__gte=timezone.now())

        if formatted is False:
            return users

        if len(users) >= 1:
            formatted_message = '' #'**The following users are looking for games:**\n'
            for user in users:
                formatted_message += '{}\n'.format(user.name)
        else:
            formatted_message = '**There are currently no users looking for games**'
        return paginate(formatted_message, reserve=reserve)[0]

class Gaming(GamingUtils):
    def __init__(self, bot):
        self.bot = bot
        for server in self.bot.servers:
            Server.objects.get_or_create(server_id=server.id, defaults={'name': server.name})
            for user in server.members:
                DiscordUser.objects.get_or_create(user_id=user.id, defaults={'name': user.name})
        super().__init__()

    def __unload(self):
        """Called when the cog is unloaded"""
        pass

    # Class methods
    def create_user(self, member):
        return DiscordUser.objects.get_or_create(user_id=member.id, defaults={'name': member.name})

    def create_game_search(self, user, game):
        created = False
        game_searches = GameSearch.objects.filter(user=user, game=game, expire_date__gte=timezone.now(), cancelled=False)
        if game_searches.count() >= 1:
            game_search = game_searches[0]
        else:
            game_search = GameSearch.objects.create(user=user, game=game)
            created = True
        return (game_search, created)

    # Events
    async def on_member_join(self, member):
        self.create_user(member)

    async def on_member_remove(self, member):
        GameSearch.objects.filter(user=user, cancelled=False, expire_date__gte=timezone.now()).update(cancelled=True)

    async def on_member_update(self, before, after):
        """This is to populate games and users automatically"""
        user, created = self.create_user(after)
        if before.game:
            member = before
        else:
            member = after
        game = member.game
        possible_games = Game.objects.filter(name=game.name.strip())
        if possible_games.count() == 0:
            game = Game.objects.create(name=game.name.strip(), url=game.url)
            GameUser.objects.get_or_create(user=user, game=game)
        elif possible_games.count() == 1:
            game = possible_games[0]
            GameUser.objects.get_or_create(user=user, game=game, defaults={'user': user, 'game': game})
    # End Events

    # Commands
    @commands.command(name='games', pass_context=True)
    async def list_games(self, ctx, *, game_search_key: str = None):
        """Get a list of all the games"""
        if game_search_key:
            try:
                game_search_key = int(game_search_key)
                games = Game.objects.get(pk=game_search_key)
            except:
                games = Game.objects.filter(name__icontains=game_search_key)
        else:
            games = Game.objects.all()
        want_to_play_message = 'Want to play a game with people? Type `{}lfg <game_number OR game_name>` to start looking.'.format(ctx.prefix)
        message_to_send = '{}'.format(await self.game_beautify(games))
        if len(games) >= 1:
            message_to_send += '{}'.format(want_to_play_message)
        await self.bot.say(message_to_send)

    @commands.command(name='lfg', pass_context=True)
    async def looking_for_game(self, ctx, *, game_search_key: str = None):
        """Used when users want to play a game with others"""
        user = self.create_user(ctx.message.author)[0]
        games = [game for game in Game.objects.all()]

        game_search = False
        created = False

        if game_search_key:
            current_searches = GameSearch.objects.filter(user=user, cancelled=False, expire_date__gte=timezone.now())
            current_searches_games = [search.game for search in current_searches]
            games = []
            try:
                possible_games = Game.objects.filter(pk=int(game_search_key))
            except:
                possible_games = Game.objects.filter(name__icontains=game_search_key)
            for game in possible_games:
                if game not in current_searches_games:
                    if game not in games:
                        games.append(game)
        if len(games) == 1:
            game = games[0]
            game_search, created = self.create_game_search(user, game)
        else:
            msg = False
            temp_message = 'Which game did you want to search for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'
            formatted_games = await self.game_beautify(games, reserve=len(temp_message))
            final_message = '{}{}'.format(temp_message, formatted_games)
            await self.bot.say(final_message, delete_after=30)
            time_ran_out = False
            gameIDs = [game.pk for game in games]
            def check(msg):
                try:
                    return int(msg.content.strip()) in gameIDs
                except:
                    return False
            msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
            if msg:
                try:
                    content = msg.content.strip()
                    try:
                        game_pk = int(content)
                        possible_game = Game.objects.filter(pk=game_pk)
                    except:
                        possible_game = Game.objects.filter(name__icontains=content)
                    if possible_game.count() == 1:
                        game = possible_game[0]
                        game_search, created = self.create_game_search(user, game)
                except Exception as e:
                    print(e)

        if created and game_search:
            await self.bot.say("You've been added to the search queue for `{0.name}`!".format(game))
        elif game_search:
            await self.bot.say("You're already in the queue for `{0.name}`. If you would like to stop looking for this game, type {1.prefix}lfgstop {0.pk}".format(game, ctx))
        elif time_ran_out:
            await self.bot.say('Whoops... looks like your time ran out `{}`. Please re-run the command and try again.'.format(ctx.message.author.mention), delete_after=30)
        else:
            await self.bot.say("I didn't quite understand your response, please run the command again.")

    @commands.command(name='lfgstop', pass_context=True)
    async def looking_for_game_remove(self, ctx, *, game_search_key: str = None):
        """Starts searching for a game to play with others"""
        user = self.create_user(ctx.message.author)[0]
        games_removed = []

        game_search_cancelled = False
        time_ran_out = False
        no_game_searches = False

        if game_search_key:
            try:
                games = Game.objects.filter(pk=int(game_search_key))
            except:
                games = Game.objects.filter(name__icontains=game_search_key)
        game_removed = 'All Games'

        if games.count() == 1:
            game = games[0]
            game_search = GameSearch.objects.filter(user=user, game=game, cancelled=False, expire_date__gte=timezone.now())
            games_removed = [search.game for search in game_search]
            game_search.update(cancelled=True)
            game_search_cancelled = True
        else:
            game_searches = GameSearch.objects.filter(user=user, cancelled=False, expire_date__gte=timezone.now())
            games = []
            for game in game_searches:
                if game.game not in games:
                    games.append(game.game)
            if len(games) >= 1:
                temp_message = 'Which game would you like to stop searching for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'
                formatted_games = await self.game_beautify(games)
                final_message = '{}{}'.format(temp_message, formatted_games)
                await self.bot.say(final_message, delete_after=30)
                gameIDs = [game.pk for game in games]
                def check(msg):
                    try:
                        return int(msg.content.strip()) in gameIDs
                    except:
                        return False
                msg = False
                msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
                if msg:
                    try:
                        content = msg.content.strip()
                        try:
                            game_pk = int(content)
                            possible_game = Game.objects.filter(pk=game_pk)
                        except:
                            possible_game = Game.objects.filter(name__icontains=game_pk)
                        if possible_game.count() == 1:
                            game = possible_game[0]
                            game_searches = GameSearch.objects.filter(user=user, game=game, cancelled=False, expire_date__gte=timezone.now())
                            game_searches.update(cancelled=True)
                            games_removed = [game]
                            game_search_cancelled = True
                    except Exception as e:
                        print(e)
            else:
                no_game_searches = True

        if game_search_cancelled:
            await self.bot.say("You've stopped searching for the selected games!")
        elif time_ran_out:
            await self.bot.say('Whoops... looks like your time ran out {}. Please re-run the command and try again.'.format(ctx.message.author.mention), delete_after=30)
        elif no_game_searches:
            await self.bot.say('It doesn\t look like you\'re currently searching for any games.\nIf you would like to start, type {0.prefix}lfg'.format(ctx))
        else:
            await self.bot.say("I didn't quite understand your response, please run the command again.")

    @commands.command(name='lfgpurge', pass_context=True, hidden=True)
    @checks.is_owner()
    async def looking_for_game_purge(self, ctx, *args):
        game_searches = GameSearch.objects.filter(cancelled=False, expire_date__gte=timezone.now())
        await self.bot.say('\n**Are you sure you want to cancel all active game searches?**\n```There are currently `{}` active searches.```'.format(game_searches.count()), delete_after=30)
        def check(msg):
            try:
                return msg.content.strip().lower() == "yes"
            except:
                return False
        msg = False
        msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
        if msg:
            game_searches.update(cancelled=True)
            for server in self.bot.servers:
                purged_message = ':exclamation: **All active Searches have been purged by {} at {}**'.format(ctx.message.author.name, timezone.now())
                await self.bot.send_message(server.default_channel, purged_message)

    @commands.command(name='halp', pass_context=True, hidden=True)
    @checks.is_owner()
    async def halp_command(self, ctx, *args):
        """
        Halp is my testing command
        """
        print("Rawr")
        await self.bot.say('Please type something that starts with "hello"')
        def check(msg):
            return msg.content.lower().startswith('hello')
        msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
        if msg:
            content = msg.content.strip()
            await self.bot.send_message(msg.channel, 'You said:\n{}'.format(content))
        else:
            await self.bot.say('Whoops... looks like your time ran out {}. Please re-run the command and try again.'.format(ctx.message.author.mention))
    # End Commands

    # Errors
    @looking_for_game.error
    async def looking_for_game_error(self, error, ctx):
        if type(error) is commands.BadArgument:
            await self.bot.say(error)
    # End Errors

def setup(bot):
    bot.add_cog(Gaming(bot))
<commit_msg>Replaced the word "purged" with "cancelled"<commit_after>import os
from discord.ext import commands
from discord.ext.commands import Bot
from datetime import datetime
import discord
from .utils import checks
from .utils.data import Data

import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web.settings')
django.setup()
from django.utils import timezone
from django.db import models
from squidbot.models import DiscordUser, Game, GameUser, Server, Role, GameSearch

DISCORD_MSG_CHAR_LIMIT = 2000

def paginate(content, *, length=DISCORD_MSG_CHAR_LIMIT, reserve=0):
    """
    Split up a large string or list of strings into chunks for sending to discord.
    """
    if type(content) == str:
        contentlist = content.split('\n')
    elif type(content) == list:
        contentlist = content
    else:
        raise ValueError("Content must be str or list, not %s" % type(content))

    chunks = []
    currentchunk = ''

    for line in contentlist:
        if len(currentchunk) + len(line) < length - reserve:
            currentchunk += line + '\n'
        else:
            chunks.append(currentchunk)
            currentchunk = ''

    if currentchunk:
        chunks.append(currentchunk)

    return chunks

class GamingUtils:
    def __init__(self):
        pass

    async def game_beautify(self, games, reserve=0):
        """
        Return a message of all games ready for displaying all pretty like
        """
        formatted_message = '**No games are currently in the database!\nStart playing some games to make the database better**'
        try:
            if len(games) == 0:
                games = Game.objects.all()

            formatted_message = '\n**Available games**\n'
            for game in games:
                if isinstance(game, GameSearch):
                    game = Game.objects.get(pk=game.pk)
                formatted_message += '`{0}:` {1}\n'.format(game.pk, game.name)
        except Exception as e:
            pass
        return paginate(formatted_message, reserve=reserve)[0]

    ####################
    # Search Utilities #
    ####################
    async def search_beautify(self, user, game, reserve=0):
        """
        Return a message of all user searches ready for displaying all pretty like
        """
        # Todo: How to filter all users and games people are searching based on params passed in
        if users:
            users = await self.search_user(users)
        elif games:
            if len(game) > 1:
                active_searches = GameSearch.objects.filter(cancelled=False, expire_date__gte=timezone.now())
                users = active_searches.filter(game__in=[game.pk])
            else:
                users = active_searches.filter(game=game, cancelled=False, expire_date__gte=timezone.now())

        if formatted is False:
            return users

        if len(users) >= 1:
            formatted_message = '' #'**The following users are looking for games:**\n'
            for user in users:
                formatted_message += '{}\n'.format(user.name)
        else:
            formatted_message = '**There are currently no users looking for games**'
        return paginate(formatted_message, reserve=reserve)[0]

class Gaming(GamingUtils):
    def __init__(self, bot):
        self.bot = bot
        for server in self.bot.servers:
            Server.objects.get_or_create(server_id=server.id, defaults={'name': server.name})
            for user in server.members:
                DiscordUser.objects.get_or_create(user_id=user.id, defaults={'name': user.name})
        super().__init__()

    def __unload(self):
        """Called when the cog is unloaded"""
        pass

    # Class methods
    def create_user(self, member):
        return DiscordUser.objects.get_or_create(user_id=member.id, defaults={'name': member.name})

    def create_game_search(self, user, game):
        created = False
        game_searches = GameSearch.objects.filter(user=user, game=game, expire_date__gte=timezone.now(), cancelled=False)
        if game_searches.count() >= 1:
            game_search = game_searches[0]
        else:
            game_search = GameSearch.objects.create(user=user, game=game)
            created = True
        return (game_search, created)

    # Events
    async def on_member_join(self, member):
        self.create_user(member)

    async def on_member_remove(self, member):
        GameSearch.objects.filter(user=user, cancelled=False, expire_date__gte=timezone.now()).update(cancelled=True)

    async def on_member_update(self, before, after):
        """This is to populate games and users automatically"""
        user, created = self.create_user(after)
        if before.game:
            member = before
        else:
            member = after
        game = member.game
        possible_games = Game.objects.filter(name=game.name.strip())
        if possible_games.count() == 0:
            game = Game.objects.create(name=game.name.strip(), url=game.url)
            GameUser.objects.get_or_create(user=user, game=game)
        elif possible_games.count() == 1:
            game = possible_games[0]
            GameUser.objects.get_or_create(user=user, game=game, defaults={'user': user, 'game': game})
    # End Events

    # Commands
    @commands.command(name='games', pass_context=True)
    async def list_games(self, ctx, *, game_search_key: str = None):
        """Get a list of all the games"""
        if game_search_key:
            try:
                game_search_key = int(game_search_key)
                games = Game.objects.get(pk=game_search_key)
            except:
                games = Game.objects.filter(name__icontains=game_search_key)
        else:
            games = Game.objects.all()
        want_to_play_message = 'Want to play a game with people? Type `{}lfg <game_number OR game_name>` to start looking.'.format(ctx.prefix)
        message_to_send = '{}'.format(await self.game_beautify(games))
        if len(games) >= 1:
            message_to_send += '{}'.format(want_to_play_message)
        await self.bot.say(message_to_send)

    @commands.command(name='lfg', pass_context=True)
    async def looking_for_game(self, ctx, *, game_search_key: str = None):
        """Used when users want to play a game with others"""
        user = self.create_user(ctx.message.author)[0]
        games = [game for game in Game.objects.all()]

        game_search = False
        created = False

        if game_search_key:
            current_searches = GameSearch.objects.filter(user=user, cancelled=False, expire_date__gte=timezone.now())
            current_searches_games = [search.game for search in current_searches]
            games = []
            try:
                possible_games = Game.objects.filter(pk=int(game_search_key))
            except:
                possible_games = Game.objects.filter(name__icontains=game_search_key)
            for game in possible_games:
                if game not in current_searches_games:
                    if game not in games:
                        games.append(game)
        if len(games) == 1:
            game = games[0]
            game_search, created = self.create_game_search(user, game)
        else:
            msg = False
            temp_message = 'Which game did you want to search for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'
            formatted_games = await self.game_beautify(games, reserve=len(temp_message))
            final_message = '{}{}'.format(temp_message, formatted_games)
            await self.bot.say(final_message, delete_after=30)
            time_ran_out = False
            gameIDs = [game.pk for game in games]
            def check(msg):
                try:
                    return int(msg.content.strip()) in gameIDs
                except:
                    return False
            msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
            if msg:
                try:
                    content = msg.content.strip()
                    try:
                        game_pk = int(content)
                        possible_game = Game.objects.filter(pk=game_pk)
                    except:
                        possible_game = Game.objects.filter(name__icontains=content)
                    if possible_game.count() == 1:
                        game = possible_game[0]
                        game_search, created = self.create_game_search(user, game)
                except Exception as e:
                    print(e)

        if created and game_search:
            await self.bot.say("You've been added to the search queue for `{0.name}`!".format(game))
        elif game_search:
            await self.bot.say("You're already in the queue for `{0.name}`. If you would like to stop looking for this game, type {1.prefix}lfgstop {0.pk}".format(game, ctx))
        elif time_ran_out:
            await self.bot.say('Whoops... looks like your time ran out `{}`. Please re-run the command and try again.'.format(ctx.message.author.mention), delete_after=30)
        else:
            await self.bot.say("I didn't quite understand your response, please run the command again.")

    @commands.command(name='lfgstop', pass_context=True)
    async def looking_for_game_remove(self, ctx, *, game_search_key: str = None):
        """Starts searching for a game to play with others"""
        user = self.create_user(ctx.message.author)[0]
        games_removed = []

        game_search_cancelled = False
        time_ran_out = False
        no_game_searches = False

        if game_search_key:
            try:
                games = Game.objects.filter(pk=int(game_search_key))
            except:
                games = Game.objects.filter(name__icontains=game_search_key)
        game_removed = 'All Games'

        if games.count() == 1:
            game = games[0]
            game_search = GameSearch.objects.filter(user=user, game=game, cancelled=False, expire_date__gte=timezone.now())
            games_removed = [search.game for search in game_search]
            game_search.update(cancelled=True)
            game_search_cancelled = True
        else:
            game_searches = GameSearch.objects.filter(user=user, cancelled=False, expire_date__gte=timezone.now())
            games = []
            for game in game_searches:
                if game.game not in games:
                    games.append(game.game)
            if len(games) >= 1:
                temp_message = 'Which game would you like to stop searching for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'
                formatted_games = await self.game_beautify(games)
                final_message = '{}{}'.format(temp_message, formatted_games)
                await self.bot.say(final_message, delete_after=30)
                gameIDs = [game.pk for game in games]
                def check(msg):
                    try:
                        return int(msg.content.strip()) in gameIDs
                    except:
                        return False
                msg = False
                msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
                if msg:
                    try:
                        content = msg.content.strip()
                        try:
                            game_pk = int(content)
                            possible_game = Game.objects.filter(pk=game_pk)
                        except:
                            possible_game = Game.objects.filter(name__icontains=game_pk)
                        if possible_game.count() == 1:
                            game = possible_game[0]
                            game_searches = GameSearch.objects.filter(user=user, game=game, cancelled=False, expire_date__gte=timezone.now())
                            game_searches.update(cancelled=True)
                            games_removed = [game]
                            game_search_cancelled = True
                    except Exception as e:
                        print(e)
            else:
                no_game_searches = True

        if game_search_cancelled:
            await self.bot.say("You've stopped searching for the selected games!")
        elif time_ran_out:
            await self.bot.say('Whoops... looks like your time ran out {}. Please re-run the command and try again.'.format(ctx.message.author.mention), delete_after=30)
        elif no_game_searches:
            await self.bot.say('It doesn\t look like you\'re currently searching for any games.\nIf you would like to start, type {0.prefix}lfg'.format(ctx))
        else:
            await self.bot.say("I didn't quite understand your response, please run the command again.")

    @commands.command(name='lfgpurge', pass_context=True, hidden=True)
    @checks.is_owner()
    async def looking_for_game_purge(self, ctx, *args):
        game_searches = GameSearch.objects.filter(cancelled=False, expire_date__gte=timezone.now())
        await self.bot.say('\n**Are you sure you want to cancel all active game searches?**\n```There are currently `{}` active searches.```'.format(game_searches.count()), delete_after=30)
        def check(msg):
            try:
                return msg.content.strip().lower() == "yes"
            except:
                return False
        msg = False
        msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
        if msg:
            game_searches.update(cancelled=True)
            for server in self.bot.servers:
                cancelled_message = ':exclamation: **All active Searches have been cancelled by {} at {}**'.format(ctx.message.author.name, timezone.now())
                await self.bot.send_message(server.default_channel, cancelled_message)

    @commands.command(name='halp', pass_context=True, hidden=True)
    @checks.is_owner()
    async def halp_command(self, ctx, *args):
        """
        Halp is my testing command
        """
        print("Rawr")
        await self.bot.say('Please type something that starts with "hello"')
        def check(msg):
            return msg.content.lower().startswith('hello')
        msg = await self.bot.wait_for_message(author=ctx.message.author, check=check, timeout=30)
        if msg:
            content = msg.content.strip()
            await self.bot.send_message(msg.channel, 'You said:\n{}'.format(content))
        else:
            await self.bot.say('Whoops... looks like your time ran out {}. Please re-run the command and try again.'.format(ctx.message.author.mention))
    # End Commands

    # Errors
    @looking_for_game.error
    async def looking_for_game_error(self, error, ctx):
        if type(error) is commands.BadArgument:
            await self.bot.say(error)
    # End Errors

def setup(bot):
    bot.add_cog(Gaming(bot))
<|endoftext|>