<commit_before>from .utils import config, checks, formats
import discord
from discord.ext import commands
import discord.utils
import random, json, asyncio
from urllib.parse import unquote

class Radio:
    """The radio-bot related commands."""

    def __init__(self, bot):
        self.bot = bot
        if not discord.opus.is_loaded():
            discord.opus.load_opus('/usr/local/lib/libopus.so') #FreeBSD path

        self.player = None
        self.stopped = True
        self.break_loop = asyncio.Event()
        #self.break_loop.clear()
        self.q = asyncio.Queue()
        self.play_next_song = asyncio.Event()
        self.current_song = None
        self.songs_dir = 'radio/'
        self.songs = []
        self.update_song_list()

    @property
    def is_playing(self):
        return self.player is not None and self.player.is_playing() and not self.stopped

    def toggle_next_song(self):
        if not self.stopped:
            self.bot.loop.call_soon_threadsafe(self.play_next_song.set)

    def update_song_list(self):
        self.songs = self.bot.pycopy.list_files(self.songs_dir)

    @commands.command(pass_context=True)
    async def join(self, ctx, *, channel_name : str):
        """Зайти на указанный голосовой канал."""
        if self.bot.is_voice_connected():
            await ctx.invoke(self.leave)

        check = lambda c: c.name == channel_name and c.type == discord.ChannelType.voice
        channel = discord.utils.find(check, ctx.message.server.channels)
        if channel is None:
            await self.bot.say('Нет такого голосового канала.')
        await self.bot.join_voice_channel(channel)

    @commands.command(pass_context=True)
    async def leave(self, ctx):
        """Покинуть текущий голосовой канал."""
        await ctx.invoke(self.stop)
        await self.bot.voice.disconnect()

    @commands.command()
    async def pause(self):
        """Приостановить воспроизведение."""
        if self.player is not None:
            self.player.pause()

    @commands.command()
    async def resume(self):
        """Продолжить воспроизведение."""
        if self.player is not None and not self.is_playing:
            self.player.resume()

    @commands.command()
    async def skip(self):
        """Перейти к следующей песне в очереди."""
        if self.player is not None and self.is_playing:
            self.player.stop()
            self.toggle_next_song()

    @commands.command()
    async def stop(self):
        """Остановить воспроизведение."""
        if self.is_playing:
            self.break_loop.set()
            self.play_next_song.set()
            self.stopped = True
            self.player.stop()

    @commands.command(pass_context=True)
    async def play(self, ctx):
        """Начать воспроизведение песен из очереди."""
        if self.player is not None and not self.stopped:
            if not self.is_playing:
                await ctx.invoke(self.resume)
                return
            else:
                await self.bot.say('Уже играю песенку.')
                return

        while True:
            if not self.bot.is_voice_connected():
                author_channel = ctx.message.author.voice_channel
                if author_channel is not None:
                    print('Joining {}.'.format(author_channel.name))
                    await ctx.invoke(self.join, channel_name=author_channel.name)
                else:
                    await self.bot.say('Не выбран голосовой канал.')
                    return

            if self.q.empty():
                await self.q.put(random.choice(self.songs))
            self.play_next_song.clear()
            self.current = await self.q.get()
            self.player = self.bot.voice.create_ffmpeg_player(
                self.bot.pycopy.direct_link(self.songs_dir + self.current),
                after=self.toggle_next_song)
                #options="-loglevel debug -report",
                #headers = dict(self.bot.pycopy.session.headers)
            self.stopped = False
            self.player.start()
            song_name = unquote(self.current.split('/')[-1])
            await self.bot.change_status(discord.Game(name=song_name))

            await self.play_next_song.wait()
            if self.break_loop.is_set():
                self.break_loop.clear()
                return
        await self.bot.say('Leaving play loop')

    @commands.command(aliases=['c'])
    async def current(self):
        """Что там играет?"""
        if self.is_playing:
            song_name = unquote(self.current.split('/')[-1])
            await self.bot.say(song_name)

    @commands.command()
    async def update(self):
        """Обновить список песен."""
        self.update_song_list()
        await self.bot.say("Найдено {} песенок".format(len(self.songs)))

    @commands.command()
    async def list(self):
        """Вывести список всех доступных песен."""
        song_list = ""
        id = 1
        for song in self.songs:
            song_list += "{}. {}\n".format(id, song)
            id += 1
            if len(song_list) > 1800:
                await self.bot.say(song_list)
                song_list = ''
        await self.bot.say(song_list)

    @commands.command()
    async def add(self, song_num : int):
        """Добавить в конец очереди песню с данным номером."""
        await self.q.put(self.songs[song_num-1])
        await self.bot.say("{} будет следующей песенкой".format(self.songs[song_num-1]))

def setup(bot):
    bot.add_cog(Radio(bot))
<commit_msg>Update radio.py<commit_after>from .utils import config, checks, formats
import discord
from discord.ext import commands
import discord.utils
import random, json, asyncio
from urllib.parse import unquote

class Radio:
    """The radio-bot related commands."""

    def __init__(self, bot):
        self.bot = bot
        if not discord.opus.is_loaded():
            discord.opus.load_opus('/usr/local/lib/libopus.so') #FreeBSD path

        self.player = None
        self.stopped = True
        self.break_loop = asyncio.Event()
        #self.break_loop.clear()
        self.q = asyncio.Queue()
        self.play_next_song = asyncio.Event()
        self.current_song = None
        self.songs_dir = 'radio/'
        self.songs = []
        self.update_song_list()

    @property
    def is_playing(self):
        return self.player is not None and self.player.is_playing() and not self.stopped

    def toggle_next_song(self):
        if not self.stopped:
            self.bot.loop.call_soon_threadsafe(self.play_next_song.set)

    def update_song_list(self):
        self.songs = self.bot.yadisk.list_files(self.songs_dir)

    @commands.command(pass_context=True)
    async def join(self, ctx, *, channel_name : str):
        """Зайти на указанный голосовой канал."""
        if self.bot.is_voice_connected():
            await ctx.invoke(self.leave)

        check = lambda c: c.name == channel_name and c.type == discord.ChannelType.voice
        channel = discord.utils.find(check, ctx.message.server.channels)
        if channel is None:
            await self.bot.say('Нет такого голосового канала.')
        await self.bot.join_voice_channel(channel)

    @commands.command(pass_context=True)
    async def leave(self, ctx):
        """Покинуть текущий голосовой канал."""
        await ctx.invoke(self.stop)
        await self.bot.voice.disconnect()

    @commands.command()
    async def pause(self):
        """Приостановить воспроизведение."""
        if self.player is not None:
            self.player.pause()

    @commands.command()
    async def resume(self):
        """Продолжить воспроизведение."""
        if self.player is not None and not self.is_playing:
            self.player.resume()

    @commands.command()
    async def skip(self):
        """Перейти к следующей песне в очереди."""
        if self.player is not None and self.is_playing:
            self.player.stop()
            self.toggle_next_song()

    @commands.command()
    async def stop(self):
        """Остановить воспроизведение."""
        if self.is_playing:
            self.break_loop.set()
            self.play_next_song.set()
            self.stopped = True
            self.player.stop()

    @commands.command(pass_context=True)
    async def play(self, ctx):
        """Начать воспроизведение песен из очереди."""
        if self.player is not None and not self.stopped:
            if not self.is_playing:
                await ctx.invoke(self.resume)
                return
            else:
                await self.bot.say('Уже играю песенку.')
                return

        while True:
            if not self.bot.is_voice_connected():
                author_channel = ctx.message.author.voice_channel
                if author_channel is not None:
                    print('Joining {}.'.format(author_channel.name))
                    await ctx.invoke(self.join, channel_name=author_channel.name)
                else:
                    await self.bot.say('Не выбран голосовой канал.')
                    return

            if self.q.empty():
                await self.q.put(random.choice(self.songs))
            self.play_next_song.clear()
            self.current = await self.q.get()
            self.player = self.bot.voice.create_ffmpeg_player(
                self.bot.yadisk.direct_link(self.songs_dir + self.current),
                after=self.toggle_next_song)
                #options="-loglevel debug -report",
                #headers = dict(self.bot.pycopy.session.headers)
            self.stopped = False
            self.player.start()
            song_name = unquote(self.current.split('/')[-1])
            await self.bot.change_status(discord.Game(name=song_name))

            await self.play_next_song.wait()
            if self.break_loop.is_set():
                self.break_loop.clear()
                return
        await self.bot.say('Leaving play loop')

    @commands.command(aliases=['c'])
    async def current(self):
        """Что там играет?"""
        if self.is_playing:
            song_name = unquote(self.current.split('/')[-1])
            await self.bot.say(song_name)

    @commands.command()
    async def update(self):
        """Обновить список песен."""
        self.update_song_list()
        await self.bot.say("Найдено {} песенок".format(len(self.songs)))

    @commands.command()
    async def list(self):
        """Вывести список всех доступных песен."""
        song_list = ""
        id = 1
        for song in self.songs:
            song_list += "{}. {}\n".format(id, song)
            id += 1
            if len(song_list) > 1800:
                await self.bot.say(song_list)
                song_list = ''
        await self.bot.say(song_list)

    @commands.command()
    async def add(self, song_num : int):
        """Добавить в конец очереди песню с данным номером."""
        await self.q.put(self.songs[song_num-1])
        await self.bot.say("{} будет следующей песенкой".format(self.songs[song_num-1]))

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


<commit_before>from bpy import data, types, context
from .. import logger

def _camera(func):
    """

    :param func:

    """

    def inner(name, *args, **kwargs):
        """

        :param name:
        :param *args:
        :param **kwargs:

        """

        if isinstance(name, types.Camera):
            camera = name
        else:
            camera = data.cameras[name]

        return func(camera, *args, **kwargs)

    return inner

@_camera
def aspect(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.aspect(%s)", camera)
    render = context.scene.render
    return render.resolution_x/render.resolution_y

@_camera
def bottom(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.bottom(%s)", camera)
    return -(camera.angle_y * camera.ortho_scale)

@_camera
def far(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.far(%s)", camera)
    return camera.clip_end

@_camera
def fov(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.fov(%s)", camera)
    return camera.lens

@_camera
def left(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.left(%s)", camera)
    return -(camera.angle_x * camera.ortho_scale)

@_camera
def near(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.near(%s)", camera)
    return camera.clip_start

@_camera
def right(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.right(%s)", camera)
    return camera.angle_x * camera.ortho_scale

@_camera
def top(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.top(%s)", camera)
    return camera.angle_y * camera.ortho_scale
<commit_msg>#8820 -Fixed exporter using the focal length of the camera, instead of the FOV-angle (#9328)<commit_after>from bpy import data, types, context
from .. import logger

def _camera(func):
    """

    :param func:

    """

    def inner(name, *args, **kwargs):
        """

        :param name:
        :param *args:
        :param **kwargs:

        """

        if isinstance(name, types.Camera):
            camera = name
        else:
            camera = data.cameras[name]

        return func(camera, *args, **kwargs)

    return inner

@_camera
def aspect(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.aspect(%s)", camera)
    render = context.scene.render
    return render.resolution_x/render.resolution_y

@_camera
def bottom(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.bottom(%s)", camera)
    return -(camera.angle_y * camera.ortho_scale)

@_camera
def far(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.far(%s)", camera)
    return camera.clip_end

@_camera
def fov(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.fov(%s)", camera)
    return camera.angle

@_camera
def left(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.left(%s)", camera)
    return -(camera.angle_x * camera.ortho_scale)

@_camera
def near(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.near(%s)", camera)
    return camera.clip_start

@_camera
def right(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.right(%s)", camera)
    return camera.angle_x * camera.ortho_scale

@_camera
def top(camera):
    """

    :param camera:
    :rtype: float

    """
    logger.debug("camera.top(%s)", camera)
    return camera.angle_y * camera.ortho_scale
<|endoftext|>


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

import linuxcnc
import hal
import time
import sys
import os
import math

# this is how long we wait for linuxcnc to do our bidding
timeout = 1.0

class LinuxcncError(Exception):
    pass
#    def __init__(self, value):
#        self.value = value
#    def __str__(self):
#        return repr(self.value)

class LinuxcncControl:
    '''
    issue G-Code commands
    make sure important modes are saved and restored
    mode is saved only once, and can be restored only once

    usage example:
        e = emc_control()
        e.prepare_for_mdi()
            any internal sub using e.g("G0.....")
        e.finish_mdi()

    '''

    def __init__(self):
        self.c = linuxcnc.command()
        self.e = linuxcnc.error_channel()
        self.s = linuxcnc.stat()

    def running(self, do_poll=True):
        '''
        check wether interpreter is running.
        If so, cant switch to MDI mode.
        '''
        if do_poll:
            self.s.poll()
        return (self.s.task_mode == linuxcnc.MODE_AUTO and
                self.s.interp_state != linuxcnc.INTERP_IDLE)

    def set_mode(self,m):
        '''
        set EMC mode if possible, else throw LinuxcncError
        return current mode
        '''
        self.s.poll()
        if self.s.task_mode == m :
            return m
        if self.running(do_poll=False):
            raise LinuxcncError("interpreter running - cant change mode")
        self.c.mode(m)
        self.c.wait_complete()
        return m

    def set_state(self,m):
        '''
        set EMC mode if possible, else throw LinuxcncError
        return current mode
        '''
        self.s.poll()
        if self.s.task_mode == m :
            return m
        self.c.state(m)
        self.c.wait_complete()
        return m

    def do_home(self,axismask):
        self.s.poll()
        self.c.home(axismask)
        self.c.wait_complete()

    def ok_for_mdi(self):
        '''
        check wether ok to run MDI commands.
        '''
        self.s.poll()
        return not self.s.estop and self.s.enabled and self.s.homed

    def prepare_for_mdi(self):
        '''
        check wether ok to run MDI commands.
        throw  LinuxcncError if told so.
        return current mode
        '''

        self.s.poll()
        if self.s.estop:
            raise LinuxcncError("machine in ESTOP")

        if not self.s.enabled:
            raise LinuxcncError("machine not enabled")

        if not self.s.homed:
            raise LinuxcncError("machine not homed")

        if self.running():
            raise LinuxcncError("interpreter not idle")

        return self.set_mode(linuxcnc.MODE_MDI)

    g_raise_except = True

    def g(self,code,wait=False):
        '''
        issue G-Code as MDI command.
        wait for completion if reqested
        '''

        self.c.mdi(code)
        if wait:
            try:
                while self.c.wait_complete() == -1:
                    pass
                return True
            except KeyboardInterrupt:
                print "interrupted by keyboard in c.wait_complete()"
                return False

        self.error = self.e.poll()
        if self.error:
            kind, text = self.error
            if kind in (linuxcnc.NML_ERROR, linuxcnc.OPERATOR_ERROR):
                if LinuxcncControl.g_raise_except:
                    raise LinuxcncError(text)
                else:
                    print ("error " + text)
            else:
                print ("info " + text)
        return False

    def get_current_tool(self):
        self.e.poll()
        return self.e.tool_in_spindle

    def active_codes(self):
        self.e.poll()
        return self.s.gcodes

    def get_current_system(self):
        g = self.active_codes()
        for i in g:
                if i >= 540 and i <= 590:
                        return i/10 - 53
                elif i >= 590 and i <= 593:
                        return i - 584
        return 1

def introspect():
    #print "joint.0.select =", h['joint-0-select']
    #print "joint.0.selected =", h['joint-0-selected']
    #print "joint.0.position =", h['joint-0-position']
    os.system("halcmd show pin halui")
    os.system("halcmd show pin python-ui")
    os.system("halcmd show sig")

def wait_for_joint_to_stop_at(joint, target):
    timeout = 5.0
    tolerance = 0.0001

    start = time.time()

    curr_pos = 0;
    while ((time.time() - start) < timeout):
        prev_pos = curr_pos
        curr_pos = h['joint-%d-position' % joint]
        vel = curr_pos - prev_pos
        error = math.fabs(curr_pos - target)
        if (error < tolerance) and (vel == 0):
            print "joint %d stopped at %.3f" % (joint, target)
            return
        time.sleep(0.1)
    print "timeout waiting for joint %d to stop at %.3f (pos=%.3f, vel=%.3f)" % (joint, target, curr_pos, vel)
    sys.exit(1)

#
# set up pins
# shell out to halcmd to make nets to halui and motion
#

h = hal.component("python-ui")

h.newpin("mdi-0", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("mdi-1", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("mdi-2", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("mdi-3", hal.HAL_BIT, hal.HAL_OUT)

h.newpin("joint-0-position", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("joint-1-position", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("joint-2-position", hal.HAL_FLOAT, hal.HAL_IN)

h.ready() # mark the component as 'ready'

os.system("halcmd source ./postgui.hal")

#
# connect to LinuxCNC
#

e = LinuxcncControl()
e.set_state(linuxcnc.STATE_ESTOP_RESET)
e.set_state(linuxcnc.STATE_ON)

#
# run the test
#
# These functions will exit with a return value of 1 if something goes
# wrong.
#

e.set_mode(linuxcnc.MODE_MANUAL)
print "running MDI command 0"
h['mdi-0'] = 1
wait_for_joint_to_stop_at(0, 0);
wait_for_joint_to_stop_at(1, 0);
wait_for_joint_to_stop_at(2, 0);
h['mdi-0'] = 0
e.s.poll()
if e.s.task_mode != linuxcnc.MODE_MANUAL:
    print "finished mdi, but didn't restore task mode to Manual (got %d)" % e.s.task_mode;
    sys.exit(1)

e.set_mode(linuxcnc.MODE_AUTO)
print "running MDI command 1"
h['mdi-1'] = 1
wait_for_joint_to_stop_at(0, 1);
wait_for_joint_to_stop_at(1, 0);
wait_for_joint_to_stop_at(2, 0);
h['mdi-1'] = 0
e.s.poll()
if e.s.task_mode != linuxcnc.MODE_AUTO:
    print "finished mdi, but didn't restore task mode to Auto (got %d)" % e.s.task_mode;
    sys.exit(1)

e.set_mode(linuxcnc.MODE_MDI)
print "running MDI command 2"
h['mdi-2'] = 1
wait_for_joint_to_stop_at(0, 1);
wait_for_joint_to_stop_at(1, 2);
wait_for_joint_to_stop_at(2, 0);
h['mdi-2'] = 0
e.s.poll()
if e.s.task_mode != linuxcnc.MODE_MDI:
    print "finished mdi, but didn't restore task mode to MDI (got %d)" % e.s.task_mode;
    sys.exit(1)

print "running MDI command 3"
h['mdi-3'] = 1
wait_for_joint_to_stop_at(0, 1);
wait_for_joint_to_stop_at(1, 2);
wait_for_joint_to_stop_at(2, 3);
h['mdi-3'] = 0

print "running MDI command 0"
h['mdi-0'] = 1
wait_for_joint_to_stop_at(0, 0);
wait_for_joint_to_stop_at(1, 0);
wait_for_joint_to_stop_at(2, 0);
h['mdi-0'] = 0

sys.exit(0)

<commit_msg>halui test: give halui a few seconds to switch the task mode back<commit_after>#!/usr/bin/env python

import linuxcnc
import hal
import time
import sys
import os
import math

# this is how long we wait for linuxcnc to do our bidding
timeout = 1.0

class LinuxcncError(Exception):
    pass
#    def __init__(self, value):
#        self.value = value
#    def __str__(self):
#        return repr(self.value)

class LinuxcncControl:
    '''
    issue G-Code commands
    make sure important modes are saved and restored
    mode is saved only once, and can be restored only once

    usage example:
        e = emc_control()
        e.prepare_for_mdi()
            any internal sub using e.g("G0.....")
        e.finish_mdi()

    '''

    def __init__(self):
        self.c = linuxcnc.command()
        self.e = linuxcnc.error_channel()
        self.s = linuxcnc.stat()

    def running(self, do_poll=True):
        '''
        check wether interpreter is running.
        If so, cant switch to MDI mode.
        '''
        if do_poll:
            self.s.poll()
        return (self.s.task_mode == linuxcnc.MODE_AUTO and
                self.s.interp_state != linuxcnc.INTERP_IDLE)

    def set_mode(self,m):
        '''
        set EMC mode if possible, else throw LinuxcncError
        return current mode
        '''
        self.s.poll()
        if self.s.task_mode == m :
            return m
        if self.running(do_poll=False):
            raise LinuxcncError("interpreter running - cant change mode")
        self.c.mode(m)
        self.c.wait_complete()
        return m

    def set_state(self,m):
        '''
        set EMC mode if possible, else throw LinuxcncError
        return current mode
        '''
        self.s.poll()
        if self.s.task_mode == m :
            return m
        self.c.state(m)
        self.c.wait_complete()
        return m

    def do_home(self,axismask):
        self.s.poll()
        self.c.home(axismask)
        self.c.wait_complete()

    def ok_for_mdi(self):
        '''
        check wether ok to run MDI commands.
        '''
        self.s.poll()
        return not self.s.estop and self.s.enabled and self.s.homed

    def prepare_for_mdi(self):
        '''
        check wether ok to run MDI commands.
        throw  LinuxcncError if told so.
        return current mode
        '''

        self.s.poll()
        if self.s.estop:
            raise LinuxcncError("machine in ESTOP")

        if not self.s.enabled:
            raise LinuxcncError("machine not enabled")

        if not self.s.homed:
            raise LinuxcncError("machine not homed")

        if self.running():
            raise LinuxcncError("interpreter not idle")

        return self.set_mode(linuxcnc.MODE_MDI)

    g_raise_except = True

    def g(self,code,wait=False):
        '''
        issue G-Code as MDI command.
        wait for completion if reqested
        '''

        self.c.mdi(code)
        if wait:
            try:
                while self.c.wait_complete() == -1:
                    pass
                return True
            except KeyboardInterrupt:
                print "interrupted by keyboard in c.wait_complete()"
                return False

        self.error = self.e.poll()
        if self.error:
            kind, text = self.error
            if kind in (linuxcnc.NML_ERROR, linuxcnc.OPERATOR_ERROR):
                if LinuxcncControl.g_raise_except:
                    raise LinuxcncError(text)
                else:
                    print ("error " + text)
            else:
                print ("info " + text)
        return False

    def get_current_tool(self):
        self.e.poll()
        return self.e.tool_in_spindle

    def active_codes(self):
        self.e.poll()
        return self.s.gcodes

    def get_current_system(self):
        g = self.active_codes()
        for i in g:
                if i >= 540 and i <= 590:
                        return i/10 - 53
                elif i >= 590 and i <= 593:
                        return i - 584
        return 1

def introspect():
    #print "joint.0.select =", h['joint-0-select']
    #print "joint.0.selected =", h['joint-0-selected']
    #print "joint.0.position =", h['joint-0-position']
    os.system("halcmd show pin halui")
    os.system("halcmd show pin python-ui")
    os.system("halcmd show sig")

def wait_for_joint_to_stop_at(joint, target):
    timeout = 5.0
    tolerance = 0.0001

    start = time.time()

    curr_pos = 0;
    while ((time.time() - start) < timeout):
        prev_pos = curr_pos
        curr_pos = h['joint-%d-position' % joint]
        vel = curr_pos - prev_pos
        error = math.fabs(curr_pos - target)
        if (error < tolerance) and (vel == 0):
            print "joint %d stopped at %.3f" % (joint, target)
            return
        time.sleep(0.1)
    print "timeout waiting for joint %d to stop at %.3f (pos=%.3f, vel=%.3f)" % (joint, target, curr_pos, vel)
    sys.exit(1)

def wait_for_task_mode(target):
    timeout = 5.0
    start = time.time()

    while ((time.time() - start) < timeout):
        e.s.poll()
        if e.s.task_mode == target:
            return
        time.sleep(0.1)

    print "timeout waiting for task mode to get to  %d (it's %d)" % (target, e.s.task_mode)
    sys.exit(1)

#
# set up pins
# shell out to halcmd to make nets to halui and motion
#

h = hal.component("python-ui")

h.newpin("mdi-0", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("mdi-1", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("mdi-2", hal.HAL_BIT, hal.HAL_OUT)
h.newpin("mdi-3", hal.HAL_BIT, hal.HAL_OUT)

h.newpin("joint-0-position", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("joint-1-position", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("joint-2-position", hal.HAL_FLOAT, hal.HAL_IN)

h.ready() # mark the component as 'ready'

os.system("halcmd source ./postgui.hal")

#
# connect to LinuxCNC
#

e = LinuxcncControl()
e.set_state(linuxcnc.STATE_ESTOP_RESET)
e.set_state(linuxcnc.STATE_ON)

#
# run the test
#
# These functions will exit with a return value of 1 if something goes
# wrong.
#

e.set_mode(linuxcnc.MODE_MANUAL)
print "running MDI command 0"
h['mdi-0'] = 1
wait_for_joint_to_stop_at(0, 0);
wait_for_joint_to_stop_at(1, 0);
wait_for_joint_to_stop_at(2, 0);
h['mdi-0'] = 0
wait_for_task_mode(linuxcnc.MODE_MANUAL)

e.set_mode(linuxcnc.MODE_AUTO)
print "running MDI command 1"
h['mdi-1'] = 1
wait_for_joint_to_stop_at(0, 1);
wait_for_joint_to_stop_at(1, 0);
wait_for_joint_to_stop_at(2, 0);
h['mdi-1'] = 0
wait_for_task_mode(linuxcnc.MODE_AUTO)

e.set_mode(linuxcnc.MODE_MDI)
print "running MDI command 2"
h['mdi-2'] = 1
wait_for_joint_to_stop_at(0, 1);
wait_for_joint_to_stop_at(1, 2);
wait_for_joint_to_stop_at(2, 0);
h['mdi-2'] = 0
e.s.poll()
wait_for_task_mode(linuxcnc.MODE_MDI)

print "running MDI command 3"
h['mdi-3'] = 1
wait_for_joint_to_stop_at(0, 1);
wait_for_joint_to_stop_at(1, 2);
wait_for_joint_to_stop_at(2, 3);
h['mdi-3'] = 0
wait_for_task_mode(linuxcnc.MODE_MDI)

print "running MDI command 0"
h['mdi-0'] = 1
wait_for_joint_to_stop_at(0, 0);
wait_for_joint_to_stop_at(1, 0);
wait_for_joint_to_stop_at(2, 0);
h['mdi-0'] = 0
wait_for_task_mode(linuxcnc.MODE_MDI)

sys.exit(0)

<|endoftext|>


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

import tornado.ioloop
import tornado.web
import tornado.gen

from mining.utils import slugfy
from admin.forms import ConnectionForm, CubeForm

class AdminHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('admin/base.html')

class CubeHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self, slug=None):
        form = CubeForm()
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        get_bucket = myBucket.get('cube').data
        if get_bucket is None:
            get_bucket = []

        for bload in get_bucket:
            if bload['slug'] == slug:
                form.sql.data = bload['sql']
                form.conection.data = bload['conection']
                form.name.data = bload['name']

        self.render('admin/cube.html', form=form, cube=get_bucket, slug=slug)

    def post(self, slug=None):
        form = CubeForm(self.request.arguments)
        if not form.validate():
            self.set_status(400)
            self.write(form.errors)

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        data = form.data
        data['slug'] = slugfy(data.get('name'))

        get_bucket = [b for b in myBucket.get('cube').data or []
                      if b['slug'] != data['slug']]
        if get_bucket is None:
            get_bucket = []
        get_bucket.append(data)

        b1 = myBucket.new('cube', data=get_bucket)
        for k in data:
            b1.add_index("{}_bin".format(k), data[k])
        b1.store()

        self.redirect('/admin/cube')

class ConnectionHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        form = ConnectionForm()
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        get_bucket = myBucket.get('connection').data
        if get_bucket is None:
            get_bucket = []

        self.render('admin/connection.html', form=form, connection=get_bucket)

    def post(self):
        form = ConnectionForm(self.request.arguments)
        if not form.validate():
            self.set_status(400)
            self.write(form.errors)

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        data = form.data
        data['slug'] = slugfy(data.get('name'))

        get_bucket = myBucket.get('connection').data
        if get_bucket is None:
            get_bucket = []
        get_bucket.append(data)

        b1 = myBucket.new('connection', data=get_bucket)
        b1.store()

        self.redirect('/admin/connection')
<commit_msg>Create new admin view, ElementHandler create/update element via admin<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
import riak

import tornado.ioloop
import tornado.web
import tornado.gen

from mining.utils import slugfy
from admin.forms import ConnectionForm, CubeForm, ElementForm

class AdminHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('admin/base.html')

class ElementHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self, slug=None):
        form = ElementForm()
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        get_bucket = myBucket.get('element').data
        if get_bucket is None:
            get_bucket = []

        for bload in get_bucket:
            if bload['slug'] == slug:
                for k in form._fields:
                    getattr(form, k).data = bload[k]

        self.render('admin/element.html',
                    form=form,
                    element=get_bucket,
                    slug=slug)

    def post(self, slug=None):
        form = ElementForm(self.request.arguments)
        if not form.validate():
            self.set_status(400)
            self.write(form.errors)

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        data = form.data
        data['slug'] = slugfy(data.get('name'))

        get_bucket = [b for b in myBucket.get('element').data or []
                      if b['slug'] != data['slug']]
        if get_bucket is None:
            get_bucket = []
        get_bucket.append(data)

        b1 = myBucket.new('element', data=get_bucket)
        for k in data:
            b1.add_index("{}_bin".format(k), data[k])
        b1.store()

        self.redirect('/admin/element')

class CubeHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self, slug=None):
        form = CubeForm()
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        get_bucket = myBucket.get('cube').data
        if get_bucket is None:
            get_bucket = []

        for bload in get_bucket:
            if bload['slug'] == slug:
                for k in form._fields:
                    getattr(form, k).data = bload[k]

        self.render('admin/cube.html', form=form, cube=get_bucket, slug=slug)

    def post(self, slug=None):
        form = CubeForm(self.request.arguments)
        if not form.validate():
            self.set_status(400)
            self.write(form.errors)

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        data = form.data
        data['slug'] = slugfy(data.get('name'))

        get_bucket = [b for b in myBucket.get('cube').data or []
                      if b['slug'] != data['slug']]
        if get_bucket is None:
            get_bucket = []
        get_bucket.append(data)

        b1 = myBucket.new('cube', data=get_bucket)
        for k in data:
            b1.add_index("{}_bin".format(k), data[k])
        b1.store()

        self.redirect('/admin/cube')

class ConnectionHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        form = ConnectionForm()
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        get_bucket = myBucket.get('connection').data
        if get_bucket is None:
            get_bucket = []

        self.render('admin/connection.html', form=form, connection=get_bucket)

    def post(self):
        form = ConnectionForm(self.request.arguments)
        if not form.validate():
            self.set_status(400)
            self.write(form.errors)

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')

        data = form.data
        data['slug'] = slugfy(data.get('name'))

        get_bucket = myBucket.get('connection').data
        if get_bucket is None:
            get_bucket = []
        get_bucket.append(data)

        b1 = myBucket.new('connection', data=get_bucket)
        b1.store()

        self.redirect('/admin/connection')
<|endoftext|>


<commit_before>import boto3
import json
import os
import time

session = boto3.session.Session()
ecs = session.client(service_name='ecs')

clusterName = os.environ["CLUSTER_NAME"]

def ciFor(ec2Id):
    listResp = ecs.list_container_instances(cluster=clusterName)
    descResp = ecs.describe_container_instances(cluster=clusterName, containerInstances=listResp['containerInstanceArns'])

    for ci in descResp['containerInstances']:
        if ci['ec2InstanceId'] == ec2Id:
            return ci['containerInstanceArn'], ci['status']

    return None, None

def lambda_handler(event, context):
    msg = json.loads(event['Records'][0]['Sns']['Message'])
    ec2Id = msg['EC2InstanceId']
    asgName = msg['AutoScalingGroupName']
    lifecycleHookName = msg['LifecycleHookName']
    topicArn = event['Records'][0]['Sns']['TopicArn']

    if msg['LifecycleTransition'] != 'autoscaling:EC2_INSTANCE_TERMINATING':
        return

    ciId, status = ciFor(ec2Id)
    if ciId == None:
        return

    if status != 'DRAINING':
        ecs.update_container_instances_state(cluster=clusterName,containerInstances=[ciId],status='DRAINING')

    tasks = ecs.list_tasks(cluster=clusterName, containerInstance=ciId)['taskArns']
    if len(tasks) > 0:
        time.sleep(1)
        session.client('sns').publish(TopicArn=topicArn, Message=json.dumps(msg), Subject='Invoking lambda again')
    else:
        session.client('autoscaling').complete_lifecycle_action(LifecycleHookName=lifecycleHookName, AutoScalingGroupName=asgName, LifecycleActionResult='CONTINUE', InstanceId=ec2Id)
<commit_msg>Loosen lifecycle check period 1s -> 5s<commit_after>import boto3
import json
import os
import time

session = boto3.session.Session()
ecs = session.client(service_name='ecs')

clusterName = os.environ["CLUSTER_NAME"]

def ciFor(ec2Id):
    listResp = ecs.list_container_instances(cluster=clusterName)
    descResp = ecs.describe_container_instances(cluster=clusterName, containerInstances=listResp['containerInstanceArns'])

    for ci in descResp['containerInstances']:
        if ci['ec2InstanceId'] == ec2Id:
            return ci['containerInstanceArn'], ci['status']

    return None, None

def lambda_handler(event, context):
    msg = json.loads(event['Records'][0]['Sns']['Message'])
    ec2Id = msg['EC2InstanceId']
    asgName = msg['AutoScalingGroupName']
    lifecycleHookName = msg['LifecycleHookName']
    topicArn = event['Records'][0]['Sns']['TopicArn']

    if msg['LifecycleTransition'] != 'autoscaling:EC2_INSTANCE_TERMINATING':
        return

    ciId, status = ciFor(ec2Id)
    if ciId == None:
        return

    if status != 'DRAINING':
        ecs.update_container_instances_state(cluster=clusterName,containerInstances=[ciId],status='DRAINING')

    tasks = ecs.list_tasks(cluster=clusterName, containerInstance=ciId)['taskArns']
    if len(tasks) > 0:
        time.sleep(5)
        session.client('sns').publish(TopicArn=topicArn, Message=json.dumps(msg), Subject='Invoking lambda again')
    else:
        session.client('autoscaling').complete_lifecycle_action(LifecycleHookName=lifecycleHookName, AutoScalingGroupName=asgName, LifecycleActionResult='CONTINUE', InstanceId=ec2Id)
<|endoftext|>


<commit_before># coding: utf-8
'''
Quantum Gate Language Module

Copyright 2013 Raytheon BBN Technologies

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 copy import copy
import json
import numpy as np
import operator
from functools import reduce
from builtins import str

import six

from . import ChannelLibrary, PulseShapes

class Pulse(object):
    '''
    A single channel pulse object
        label - name of the pulse
        channel - logical channel the pulse acts upon
        shape - numpy array pulse shape
        frameChange - accumulated phase from the pulse
    '''
    def __init__(self, label, channel, shapeParams, amp=1.0, phase=0, frameChange=0):
        self.label = label
        if isinstance(channel, (list, tuple)):
            # with more than one qubit, need to look up the channel
            self.channel = ChannelLibrary.QubitFactory(reduce(operator.add, [c.label for c in channel]))
        else:
            self.channel = channel
        self.shapeParams = shapeParams
        self.phase = phase
        self.amp = amp
        self.frameChange = frameChange
        self.isTimeAmp = False
        requiredParams = ['length', 'shapeFun']
        for param in requiredParams:
            if param not in shapeParams.keys():
                raise NameError("ShapeParams must incluce {0}".format(param))

    def _repr_pretty_(self, p, cycle):
        p.text(str(self))

    def __str__(self):
        if isinstance(self.channel, tuple):
            return '{0}({1})'.format(self.label, ','.join([channel.label for channel in self.channel]))
        else:
            return '{0}({1})'.format(self.label, self.channel.label)

    # adding pulses concatenates the pulse shapes
    def __add__(self, other):
        if self.channel != other.channel:
            raise NameError("Can only concatenate pulses acting on the same channel")
        return CompositePulse([self, other])

    # unary negation inverts the pulse amplitude and frame change
    def __neg__(self):
        return Pulse(self.label, self.channel, copy(self.shapeParams), -self.amp, self.phase, -self.frameChange)

    def __mul__(self, other):
        return self.promote()*other.promote()

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        return False

    def __ne__(self, other):
        return not self == other

    def hashshape(self):
        return hash(frozenset(self.shapeParams.items()))

    def promote(self):
        # promote a Pulse to a PulseBlock
        pb =  PulseBlock()
        pb.pulses = {self.channel: self}
        return pb

    @property
    def length(self):
        return self.shapeParams['length']

    @length.setter
    def length(self, value):
        self.shapeParams['length'] = value
        return value

    @property
    def isZero(self):
        return self.amp == 0

    @property
    def shape(self):
        params = copy(self.shapeParams)
        params['samplingRate'] = self.channel.physChan.samplingRate
        params.pop('shapeFun')
        return self.shapeParams['shapeFun'](**params)

def TAPulse(label, channel, length, amp, phase=0, frameChange=0):
    '''
    Creates a time/amplitude pulse with the given pulse length and amplitude
    '''
    params = {'length': length, 'shapeFun': PulseShapes.constant}
    p = Pulse(label, channel, params, amp, phase, frameChange)
    p.isTimeAmp = True
    return p

class CompositePulse(object):
    '''
    A sequential series of pulses that reside within one time bin of a pulse block
    '''
    def __init__(self, pulses, label=""):
        self.pulses = pulses
        self.label = label

    def _repr_pretty_(self, p, cycle):
        p.text(str(self))

    def __str__(self):
        if self.label != "":
            return self.label
        else:
            return "+".join([str(p) for p in self.pulses])

    def __add__(self, other):
        if self.channel != other.channel:
            raise NameError("Can only concatenate pulses acting on the same channel")
        if hasattr(other, 'pulses'):
            return CompositePulse(self.pulses + other.pulses)
        else:
            return CompositePulse(self.pulses + [other])

    def __mul__(self, other):
        return self.promote()*other.promote()

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        return False

    def __ne__(self, other):
        return not self == other

    def promote(self):
        # promote a CompositePulse to a PulseBlock
        pb =  PulseBlock()
        pb.pulses = {self.channel: self}
        return pb

    @property
    def channel(self):
        # Assume that the first pulse in the composite contains the channel information
        return self.pulses[0].channel

    @property
    def length(self):
        return sum(p.length for p in self.pulses)

    @property
    def frameChange(self):
        return sum(p.frameChange for p in self.pulses)

    @property
    def isZero(self):
        return all(p.isZero for p in self.pulses)

@six.python_2_unicode_compatible
class PulseBlock(object):
    '''
    The basic building block for pulse sequences. This is what we can concatenate together to make sequences.
    We overload the * operator so that we can combine pulse blocks on different channels.
    We overload the + operator to concatenate pulses on the same channel.
    '''
    def __init__(self):
        #Set some default values
        #How multiple channels are aligned.
        self.alignment = 'left'
        self.pulses = {}
        self.label = None

    def _repr_pretty_(self, p, cycle):
        p.text(str(self))

    def __str__(self):
        labelPart = u"{0}: ".format(self.label) if self.label else u""
        return labelPart + u"⊗ ".join([str(pulse) for pulse in self.pulses.values()])

    def __unicode__(self):
        labelPart = u"{0}: ".format(self.label) if self.label else u""
        return labelPart + u"⊗ ".join([str(pulse) for pulse in self.pulses.values()])

    def __repr__(self):
        return "Pulses " + ";".join([str(pulse) for pulse in self.pulses.values()]) + " alignment: {0}".format(self.alignment)

    #Overload the multiplication operator to combine pulse blocks
    def __mul__(self, rhs):
        # make sure RHS is a PulseBlock
        rhs = rhs.promote()
        # we need to go one layer deep in the copy so that we can manipulate self.pulses and self.channel w/o affecting the original object
        # should bundle this behavior into a __copy__ method
        result = copy(self)
        result.pulses = copy(self.pulses)

        for (k, v) in rhs.pulses.items():
            if k in result.pulses.keys():
                raise NameError("Attempted to multiply pulses acting on the same space")
            else:
                result.pulses[k] = v
        return result

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            # ignore label in equality testing
            mydict = self.__dict__.copy()
            otherdict = other.__dict__.copy()
            mydict.pop('label')
            otherdict.pop('label')
            return mydict == otherdict
        return False

    def __ne__(self, other):
        return not self == other

    #PulseBlocks don't need to be promoted, so just return self
    def promote(self):
        return self

    @property
    def channel(self):
        return self.pulses.keys()

    #The maximum number of points needed for any channel on this block
    @property
    def length(self):
        return max([p.length for p in self.pulses.values()])

def align(pulseBlock, mode="center"):
    # make sure we have a PulseBlock
    pulseBlock = pulseBlock.promote()
    pulseBlock.alignment = mode
    return pulseBlock
<commit_msg>Define a serializable __repr__ for Pulses.<commit_after># coding: utf-8
'''
Quantum Gate Language Module

Copyright 2013 Raytheon BBN Technologies

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 unicode_literals
from copy import copy
import json
import numpy as np
import operator
from functools import reduce
from builtins import str

import six

from . import ChannelLibrary, PulseShapes

class Pulse(object):
    '''
    A single channel pulse object
        label - name of the pulse
        channel - logical channel the pulse acts upon
        shape - numpy array pulse shape
        frameChange - accumulated phase from the pulse
    '''
    def __init__(self, label, channel, shapeParams, amp=1.0, phase=0, frameChange=0):
        self.label = label
        if isinstance(channel, (list, tuple)):
            # with more than one qubit, need to look up the channel
            self.channel = ChannelLibrary.QubitFactory(reduce(operator.add, [c.label for c in channel]))
        else:
            self.channel = channel
        self.shapeParams = shapeParams
        self.phase = phase
        self.amp = amp
        self.frameChange = frameChange
        self.isTimeAmp = False
        requiredParams = ['length', 'shapeFun']
        for param in requiredParams:
            if param not in shapeParams.keys():
                raise NameError("ShapeParams must incluce {0}".format(param))

    def __repr__(self):
        return "Pulse({0}, {1}, {2}, {3}, {4}, {5})".format(
            self.label,
            self.channel,
            self.shapeParams,
            self.amp,
            self.phase,
            self.frameChange)

    def __str__(self):
        if isinstance(self.channel, tuple):
            return '{0}({1})'.format(self.label, ','.join([channel.label for channel in self.channel]))
        else:
            return '{0}({1})'.format(self.label, self.channel.label)

    def _repr_pretty_(self, p, cycle):
        p.text(str(self))

    # adding pulses concatenates the pulse shapes
    def __add__(self, other):
        if self.channel != other.channel:
            raise NameError("Can only concatenate pulses acting on the same channel")
        return CompositePulse([self, other])

    # unary negation inverts the pulse amplitude and frame change
    def __neg__(self):
        return Pulse(self.label, self.channel, copy(self.shapeParams), -self.amp, self.phase, -self.frameChange)

    def __mul__(self, other):
        return self.promote()*other.promote()

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        return False

    def __ne__(self, other):
        return not self == other

    def hashshape(self):
        return hash(frozenset(self.shapeParams.items()))

    def promote(self):
        # promote a Pulse to a PulseBlock
        pb =  PulseBlock()
        pb.pulses = {self.channel: self}
        return pb

    @property
    def length(self):
        return self.shapeParams['length']

    @length.setter
    def length(self, value):
        self.shapeParams['length'] = value
        return value

    @property
    def isZero(self):
        return self.amp == 0

    @property
    def shape(self):
        params = copy(self.shapeParams)
        params['samplingRate'] = self.channel.physChan.samplingRate
        params.pop('shapeFun')
        return self.shapeParams['shapeFun'](**params)

def TAPulse(label, channel, length, amp, phase=0, frameChange=0):
    '''
    Creates a time/amplitude pulse with the given pulse length and amplitude
    '''
    params = {'length': length, 'shapeFun': PulseShapes.constant}
    p = Pulse(label, channel, params, amp, phase, frameChange)
    p.isTimeAmp = True
    return p

class CompositePulse(object):
    '''
    A sequential series of pulses that reside within one time bin of a pulse block
    '''
    def __init__(self, pulses, label=""):
        self.pulses = pulses
        self.label = label

    def __repr__(self):
        return "CompositePulse({0}, {1})".format(self.pulses, self.label)

    def __str__(self):
        if self.label != "":
            return self.label
        else:
            return "+".join([str(p) for p in self.pulses])

    def _repr_pretty_(self, p, cycle):
        p.text(str(self))

    def __add__(self, other):
        if self.channel != other.channel:
            raise NameError("Can only concatenate pulses acting on the same channel")
        if hasattr(other, 'pulses'):
            return CompositePulse(self.pulses + other.pulses)
        else:
            return CompositePulse(self.pulses + [other])

    def __mul__(self, other):
        return self.promote()*other.promote()

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        return False

    def __ne__(self, other):
        return not self == other

    def promote(self):
        # promote a CompositePulse to a PulseBlock
        pb =  PulseBlock()
        pb.pulses = {self.channel: self}
        return pb

    @property
    def channel(self):
        # Assume that the first pulse in the composite contains the channel information
        return self.pulses[0].channel

    @property
    def length(self):
        return sum(p.length for p in self.pulses)

    @property
    def frameChange(self):
        return sum(p.frameChange for p in self.pulses)

    @property
    def isZero(self):
        return all(p.isZero for p in self.pulses)

@six.python_2_unicode_compatible
class PulseBlock(object):
    '''
    The basic building block for pulse sequences. This is what we can concatenate together to make sequences.
    We overload the * operator so that we can combine pulse blocks on different channels.
    We overload the + operator to concatenate pulses on the same channel.
    '''
    def __init__(self):
        #Set some default values
        #How multiple channels are aligned.
        self.alignment = 'left'
        self.pulses = {}
        self.label = None

    def __str__(self):
        labelPart = "{0}: ".format(self.label) if self.label else ""
        return labelPart + "⊗ ".join([str(pulse) for pulse in self.pulses.values()])

    def __repr__(self):
        return "Pulses " + ";".join([str(pulse) for pulse in self.pulses.values()]) + " alignment: {0}".format(self.alignment)

    def _repr_pretty_(self, p, cycle):
        p.text(str(self))

    #Overload the multiplication operator to combine pulse blocks
    def __mul__(self, rhs):
        # make sure RHS is a PulseBlock
        rhs = rhs.promote()
        # we need to go one layer deep in the copy so that we can manipulate self.pulses and self.channel w/o affecting the original object
        # should bundle this behavior into a __copy__ method
        result = copy(self)
        result.pulses = copy(self.pulses)

        for (k, v) in rhs.pulses.items():
            if k in result.pulses.keys():
                raise NameError("Attempted to multiply pulses acting on the same space")
            else:
                result.pulses[k] = v
        return result

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            # ignore label in equality testing
            mydict = self.__dict__.copy()
            otherdict = other.__dict__.copy()
            mydict.pop('label')
            otherdict.pop('label')
            return mydict == otherdict
        return False

    def __ne__(self, other):
        return not self == other

    #PulseBlocks don't need to be promoted, so just return self
    def promote(self):
        return self

    @property
    def channel(self):
        return self.pulses.keys()

    #The maximum number of points needed for any channel on this block
    @property
    def length(self):
        return max([p.length for p in self.pulses.values()])

def align(pulseBlock, mode="center"):
    # make sure we have a PulseBlock
    pulseBlock = pulseBlock.promote()
    pulseBlock.alignment = mode
    return pulseBlock
<|endoftext|>


<commit_before>import sys
import time
import logging
from collections import OrderedDict
from socket import error as SocketError
from hiredis import ReplyError
from retrying import retry
from redistrib.clusternode import Talker, pack_command, ClusterNode
from influxdb.client import InfluxDBClientError

import config
import file_ipc
import stats.db

INTERVAL = 10
CMD_INFO = pack_command('info')
CMD_CLUSTER_NODES = pack_command('cluster', 'nodes')
CMD_PROXY = '+PROXY\r\n'

COLUMNS = OrderedDict([
    ('used_memory_rss', 'used_memory_rss'),
    ('connected_clients', 'connected_clients'),
    ('expired_keys', 'expired_keys'),
    ('evicted_keys', 'evicted_keys'),
    ('keyspace_hits', 'keyspace_hits'),
    ('keyspace_misses', 'keyspace_misses'),
    ('used_cpu_sys', 'used_cpu_sys'),
    ('used_cpu_user', 'used_cpu_user'),
])

PRECPU = {}

def _info_detail(t):
    details = {}
    for line in t.talk_raw(CMD_INFO).split('\n'):
        if len(line) == 0 or line.startswith('#'):
            continue
        r = line.split(':')
        if len(r) != 2:
            continue
        k, v = r
        details[k.strip()] = v.strip()
    return details

def _info_slots(t):
    for line in t.talk_raw(CMD_CLUSTER_NODES).split('\n'):
        if len(line) == 0 or 'fail' in line or 'myself' not in line:
            continue
        node = ClusterNode(*line.split(' '))
        return {
            'node_id': node.node_id,
            'slave': node.role_in_cluster != 'master',
            'master_id': node.master_id if node.master_id != '-' else None,
            'slots': node.assigned_slots,
        }

@retry(stop_max_attempt_number=3, wait_fixed=200)
def _emit_data(json_body):
    stats.db.client.write_points(json_body)

def _send_to_influxdb(node):
    def cpu_delta(now, pre, t):
        return float(now - pre) / (time.time() - t)

    name = '%s:%s' % (node['host'], node['port'])
    points = [
        node['mem'][COLUMNS['used_memory_rss']],
        node['conn'][COLUMNS['connected_clients']],
        node['storage'][COLUMNS['expired_keys']],
        node['storage'][COLUMNS['evicted_keys']],
        node['storage'][COLUMNS['keyspace_hits']],
        node['storage'][COLUMNS['keyspace_misses']],
    ]
    cpu = PRECPU.get(name)
    used_cpu_sys = cpu_delta(node['cpu'][COLUMNS['used_cpu_sys']],
                             cpu['used_cpu_sys'], cpu['__time__']) if cpu else 0
    used_cpu_user = cpu_delta(node['cpu'][COLUMNS['used_cpu_user']],
                              cpu['used_cpu_user'], cpu['__time__']) if cpu else 0
    PRECPU[name] = {
        'used_cpu_sys': node['cpu'][COLUMNS['used_cpu_sys']],
        'used_cpu_user': node['cpu'][COLUMNS['used_cpu_user']],
        '__time__': time.time(),
    }
    points.append(used_cpu_sys)
    points.append(used_cpu_user)
    json_body = [{
        'name': name,
        'columns': COLUMNS.keys(),
        'points': [points],
    }]

    try:
        _emit_data(json_body)
    except InfluxDBClientError, e:
        logging.exception(e)

def _send_proxy_to_influxdb(proxy):
    name = '%s:%s:p' % (proxy['host'], proxy['port'])
    points = [
        proxy['mem']['mem_buffer_alloc'],
        proxy['conn']['connected_clients'],
    ]
    json_body = [{
        'name': name,
        'columns': ['mem_buffer_alloc', 'connected_clients'],
        'points': [points],
    }]

    try:
        _emit_data(json_body)
    except InfluxDBClientError, e:
        logging.exception(e)

@retry(stop_max_attempt_number=3, wait_fixed=200)
def _info_node(host, port):
    t = Talker(host, port)
    try:
        node_info = _info_slots(t)
        details = _info_detail(t)
        node_info['mem'] = {
            'used_memory_rss': int(details['used_memory_rss']),
            'used_memory_human': details['used_memory_human'],
        }
        node_info['cpu'] = {
            'used_cpu_sys': float(details['used_cpu_sys']),
            'used_cpu_user': float(details['used_cpu_user']),
        }
        node_info['conn'] = {
            'connected_clients': int(details['connected_clients']),
        }
        node_info['storage'] = {
            'expired_keys': int(details['expired_keys']),
            'evicted_keys': int(details['evicted_keys']),
            'keyspace_hits': int(details['keyspace_hits']),
            'keyspace_misses': int(details['keyspace_misses']),
            'aof_enabled': details['aof_enabled'] == '1',
        }
        node_info['stat'] = True
        return node_info
    finally:
        t.close()

@retry(stop_max_attempt_number=3, wait_fixed=200)
def _info_proxy(host, port):
    t = Talker(host, port)
    try:
        lines = t.talk_raw(CMD_PROXY).split('\n')
        st = {}
        for ln in lines:
            k, v = ln.split(':')
            st[k] = v
        conns = sum([int(c) for c in st['clients_count'].split(',')])
        mem_buffer_alloc = sum([int(m) for m in
                                st['mem_buffer_alloc'].split(',')])
        return {
            'stat': True,
            'conn': {'connected_clients': conns},
            'mem': {'mem_buffer_alloc': mem_buffer_alloc},
        }
    finally:
        t.close()

def run():
    while True:
        poll = file_ipc.read_poll()
        nodes = poll['nodes']
        proxies = poll['proxies']
        for node in nodes:
            try:
                node.update(_info_node(**node))
                _send_to_influxdb(node)
            except (ReplyError, SocketError, StandardError), e:
                logging.error('Fail to retrieve info of %s:%d',
                              node['host'], node['port'])
                logging.exception(e)
                node['stat'] = False
        for p in proxies:
            try:
                p.update(_info_proxy(**p))
                _send_proxy_to_influxdb(p)
            except (ReplyError, SocketError, StandardError), e:
                logging.error('Fail to retrieve info of %s:%d',
                              p['host'], p['port'])
                logging.exception(e)
                p['stat'] = False
        logging.info('Total %d nodes, %d proxies', len(nodes), len(proxies))
        try:
            file_ipc.write(nodes, proxies)
        except StandardError, e:
            logging.exception(e)

        time.sleep(INTERVAL)

def main():
    conf = config.load('config.yaml' if len(sys.argv) == 1 else sys.argv[1])
    config.init_logging(conf)
    global INTERVAL
    INTERVAL = int(conf.get('interval', INTERVAL))
    if 'influxdb' in conf:
        stats.db.init(**conf['influxdb'])
    else:
        _send_to_influxdb = lambda _: None
    run()

if __name__ == '__main__':
    main()
<commit_msg>store sla<commit_after>import sys
import time
import logging
from collections import OrderedDict
from socket import error as SocketError
from hiredis import ReplyError
from retrying import retry
from redistrib.clusternode import Talker, pack_command, ClusterNode
from influxdb.client import InfluxDBClientError

import config
import file_ipc
import stats.db

INTERVAL = 10
CMD_INFO = pack_command('info')
CMD_CLUSTER_NODES = pack_command('cluster', 'nodes')
CMD_PROXY = '+PROXY\r\n'

COLUMNS = OrderedDict([
    ('used_memory_rss', 'used_memory_rss'),
    ('connected_clients', 'connected_clients'),
    ('expired_keys', 'expired_keys'),
    ('evicted_keys', 'evicted_keys'),
    ('keyspace_hits', 'keyspace_hits'),
    ('keyspace_misses', 'keyspace_misses'),
    ('used_cpu_sys', 'used_cpu_sys'),
    ('used_cpu_user', 'used_cpu_user'),
])

PRECPU = {}

def _info_detail(t):
    details = {}
    for line in t.talk_raw(CMD_INFO).split('\n'):
        if len(line) == 0 or line.startswith('#'):
            continue
        r = line.split(':')
        if len(r) != 2:
            continue
        k, v = r
        details[k.strip()] = v.strip()
    return details

def _info_slots(t):
    for line in t.talk_raw(CMD_CLUSTER_NODES).split('\n'):
        if len(line) == 0 or 'fail' in line or 'myself' not in line:
            continue
        node = ClusterNode(*line.split(' '))
        return {
            'node_id': node.node_id,
            'slave': node.role_in_cluster != 'master',
            'master_id': node.master_id if node.master_id != '-' else None,
            'slots': node.assigned_slots,
        }

@retry(stop_max_attempt_number=3, wait_fixed=200)
def _emit_data(json_body):
    stats.db.client.write_points(json_body)

def _send_to_influxdb(node):
    def cpu_delta(now, pre, t):
        return float(now - pre) / (time.time() - t)

    name = '%s:%s' % (node['host'], node['port'])
    points = [
        node['mem'][COLUMNS['used_memory_rss']],
        node['conn'][COLUMNS['connected_clients']],
        node['storage'][COLUMNS['expired_keys']],
        node['storage'][COLUMNS['evicted_keys']],
        node['storage'][COLUMNS['keyspace_hits']],
        node['storage'][COLUMNS['keyspace_misses']],
    ]
    cpu = PRECPU.get(name)
    used_cpu_sys = cpu_delta(node['cpu'][COLUMNS['used_cpu_sys']],
                             cpu['used_cpu_sys'], cpu['__time__']) if cpu else 0
    used_cpu_user = cpu_delta(node['cpu'][COLUMNS['used_cpu_user']],
                              cpu['used_cpu_user'], cpu['__time__']) if cpu else 0
    PRECPU[name] = {
        'used_cpu_sys': node['cpu'][COLUMNS['used_cpu_sys']],
        'used_cpu_user': node['cpu'][COLUMNS['used_cpu_user']],
        '__time__': time.time(),
    }
    points.append(used_cpu_sys)
    points.append(used_cpu_user)
    json_body = [{
        'name': name,
        'columns': COLUMNS.keys(),
        'points': [points],
    }]

    try:
        _emit_data(json_body)
    except InfluxDBClientError, e:
        logging.exception(e)

def _send_proxy_to_influxdb(proxy):
    name = '%s:%s:p' % (proxy['host'], proxy['port'])
    points = [
        proxy['mem']['mem_buffer_alloc'],
        proxy['conn']['connected_clients'],
    ]
    json_body = [{
        'name': name,
        'columns': ['mem_buffer_alloc', 'connected_clients'],
        'points': [points],
    }]

    try:
        _emit_data(json_body)
    except InfluxDBClientError, e:
        logging.exception(e)

@retry(stop_max_attempt_number=3, wait_fixed=200)
def _info_node(host, port):
    t = Talker(host, port)
    try:
        node_info = _info_slots(t)
        details = _info_detail(t)
        node_info['mem'] = {
            'used_memory_rss': int(details['used_memory_rss']),
            'used_memory_human': details['used_memory_human'],
        }
        node_info['cpu'] = {
            'used_cpu_sys': float(details['used_cpu_sys']),
            'used_cpu_user': float(details['used_cpu_user']),
        }
        node_info['conn'] = {
            'connected_clients': int(details['connected_clients']),
        }
        node_info['storage'] = {
            'expired_keys': int(details['expired_keys']),
            'evicted_keys': int(details['evicted_keys']),
            'keyspace_hits': int(details['keyspace_hits']),
            'keyspace_misses': int(details['keyspace_misses']),
            'aof_enabled': details['aof_enabled'] == '1',
        }
        node_info['stat'] = True
        return node_info
    finally:
        t.close()

@retry(stop_max_attempt_number=3, wait_fixed=200)
def _info_proxy(host, port):
    t = Talker(host, port)
    try:
        lines = t.talk_raw(CMD_PROXY).split('\n')
        st = {}
        for ln in lines:
            k, v = ln.split(':')
            st[k] = v
        conns = sum([int(c) for c in st['clients_count'].split(',')])
        mem_buffer_alloc = sum([int(m) for m in
                                st['mem_buffer_alloc'].split(',')])
        return {
            'stat': True,
            'conn': {'connected_clients': conns},
            'mem': {'mem_buffer_alloc': mem_buffer_alloc},
        }
    finally:
        t.close()

def _set_sla(s, step=1.0):
    s['count'] = s.get('count', 0) + 1
    s['sla'] = (s.get('sla', 0) + step) / s['count']

def run():
    while True:
        poll = file_ipc.read_poll()
        nodes = poll['nodes']
        proxies = poll['proxies']
        for node in nodes:
            try:
                node.update(_info_node(**node))
                _send_to_influxdb(node)
            except (ReplyError, SocketError, StandardError), e:
                logging.error('Fail to retrieve info of %s:%d',
                              node['host'], node['port'])
                logging.exception(e)
                node['stat'] = False
                _set_sla(node, 0)
            else:
                _set_sla(node)

        for p in proxies:
            try:
                p.update(_info_proxy(**p))
                _send_proxy_to_influxdb(p)
            except (ReplyError, SocketError, StandardError), e:
                logging.error('Fail to retrieve info of %s:%d',
                              p['host'], p['port'])
                logging.exception(e)
                p['stat'] = False
                _set_sla(p, 0)
            else:
                _set_sla(p)

        logging.info('Total %d nodes, %d proxies', len(nodes), len(proxies))
        try:
            file_ipc.write(nodes, proxies)
        except StandardError, e:
            logging.exception(e)

        time.sleep(INTERVAL)

def main():
    conf = config.load('config.yaml' if len(sys.argv) == 1 else sys.argv[1])
    config.init_logging(conf)
    global INTERVAL
    INTERVAL = int(conf.get('interval', INTERVAL))
    if 'influxdb' in conf:
        stats.db.init(**conf['influxdb'])
    else:
        _send_to_influxdb = lambda _: None
    run()

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


<commit_before>import discord
from discord.ext import commands
import asyncio

import database
from data.links import *
from web import Web

class Stats:
    def __init__(self, bot: commands.Bot):
        self.bot = bot

    @commands.command(aliases=['stat', 'stats', 'statistics'])
    async def statistic(self, ctx: commands.Context, who=None):
        if who is None:
            who = ctx.author
        else:
            try:
                who = await commands.MemberConverter().convert(ctx, who)
            except commands.CommandError:
                who = ctx.author

        limit = 6
        db = await database.Database.get_connection(self.bot.loop)
        user_info = "SELECT message_count, reaction_count, special FROM users WHERE user_id = $1"
        words_used = ("SELECT words.word, usage_count, word_count.last_use FROM word_count "
                      "JOIN words ON word_count.word = words.word AND words.excluded = FALSE "
                      "WHERE user_id = $1 ORDER BY usage_count DESC LIMIT $2")
        reactions_used = ("SELECT reactions.reaction, usage_count, reaction_count.last_use, reactions.custom FROM reaction_count "
                          "JOIN reactions ON reaction_count.reaction = reactions.reaction "
                          "WHERE user_id = $1 ORDER BY usage_count DESC LIMIT $2")
        async with db.transaction():
            user_id = who.id
            embed = discord.Embed(colour=discord.Colour(0xb85f98))
            embed.set_author(icon_url=who.avatar_url, name=who.name)
            message_count, reaction_count, special = await db.fetchrow(user_info, str(who.id))
            if user_id == 186829544764866560:
                embed.set_footer(text="You said 'By Achenar' {} times.".format(special))
            embed.add_field(name="Message statistics", inline=False,
                            value="You sent {} messages. Top used words:".format(message_count))
            async for (word, count, last_use) in db.cursor(words_used, *(str(user_id), limit)):
                embed.add_field(name=word, inline=True, value="{0:4} time(s)\nLast use: {1}".format(count,
                                                                                '{:%d.%m.%Y %H:%M}'.format(
                                                                                last_use)))
            embed.add_field(name="Reaction statistics", inline=False,
                            value="You used {} reactions. Top used reactions:".format(reaction_count))
            async for (reaction, count, last_use, custom) in db.cursor(reactions_used, *(str(user_id), limit)):
                emoji = None
                if custom:
                    emoji = self.bot.get_emoji(int(reaction))
                    reaction = "<:{}:{}>".format(emoji.name, emoji.id)
                embed.add_field(name=emoji or reaction, inline=True, value="{0:4} time(s)\nLast use: {1}"
                                .format(count, '{:%d.%m.%Y %H:%M}'.format(last_use)))
            await ctx.send(embed=embed)
            await ctx.message.delete(reason="Command cleanup")
        await database.Database.close_connection(db)

    @commands.command()
    async def diamonds(self, ctx, who=None):
        link = user_data_link
        if who:
            who = await commands.MemberConverter().convert(ctx, who)
        else:
            who = ctx.message.author
        args = {
            'discord_id': who.id
        }
        response = await Web.get_response(link, args)
        to_delete = [ctx.message]
        sleep = 2
        if response['Response'] == 'User not found':
            if who is ctx.message.author:
                to_delete.append(await ctx.send("❌ This account is not linked"))
            else:
                sleep = 10
                to_delete.append(await ctx.send("❌ Link your account first. Use !link {verification_code} {website_username} . You can find your verification code on website."))
        else:
            count = int(response['Diamonds'])
            emoji_type = ''
            if count > 500:
                emoji_type = 2
            elif count > 2500:
                emoji_type = 3
            elif count > 10000:
                emoji_type = 4
            try:
                emoji = await commands.EmojiConverter().convert(ctx, "diamond{}".format(emoji_type))
            except commands.CommandError as err:
                emoji = '💎'
            embed = discord.Embed(description="{} {}".format(emoji, count), color=discord.Colour.blue())
            rank = ""
            if response['Prismatic_rank'] != 'None':
                rank = response['Prismatic_rank']
            embed.set_author(icon_url=who.avatar_url, name="{} {}".format(rank, who.name))
            await ctx.send(embed=embed)
        await asyncio.sleep(sleep)
        await ctx.channel.delete_messages(to_delete, reason="Command cleanup")

    @commands.command()
    async def word(self, ctx: commands.Context, *args):
        to_delete = [ctx.message]
        if args.__len__() < 1:
            to_delete.append(await ctx.send('You must provide a word'))
            await asyncio.sleep(5)
            await ctx.channel.delete_messages(to_delete, reason="Command cleanup")
            return
        what = args[0].lower().strip()
        db = await database.Database.get_connection()
        counts = ("SELECT count(*) AS people, words.word, sum(usage_count) AS count, words.last_use "
                  "FROM word_count "
                  "JOIN words ON word_count.word = words.word "
                  "WHERE words.word = $1"
                  "GROUP BY words.word")
        times = ("SELECT word_count.last_use, usage_count FROM word_count "
                 "JOIN users ON users.user_id = word_count.user_id "
                 "JOIN words ON word_count.word = words.word "
                 "WHERE users.user_id = $1 AND words.word = $2")
        async with db.transaction():
            try:
                people, word, count, use = await db.fetchrow(counts, what)
                last_use, usage = await db.fetchrow(times, *(str(ctx.message.author.id), what))
                embed = discord.Embed(title=what, color=13434828, description="Word {} was used {} times by {} people, {} times by you".format(word, count, people, usage))
                embed.add_field(name="Your last use", value="{:%d.%m.%Y %H:%M}".format(last_use))
                embed.add_field(name="General last use", value="{:%d.%m.%Y %H:%M}".format(use))
            except TypeError as e:
                embed = discord.Embed(title=what, color=13434828,description="Word {} was never used before.".format(what))
        await ctx.send("", embed=embed)
        await ctx.channel.delete_messages(to_delete, reason="Command cleanup")
        await database.Database.close_connection(db)

def setup(bot: commands.Bot):
    bot.add_cog(Stats(bot))
<commit_msg>history parsing fix<commit_after>import discord
from discord.ext import commands
import asyncio

import database
from data.links import *
from web import Web

class Stats:
    def __init__(self, bot: commands.Bot):
        self.bot = bot

    @commands.command(aliases=['stat', 'stats', 'statistics'])
    async def statistic(self, ctx: commands.Context, who=None):
        if who is None:
            who = ctx.author
        else:
            try:
                who = await commands.UserConverter().convert(ctx, who)
            except commands.CommandError:
                who = ctx.author

        limit = 6
        db = await database.Database.get_connection(self.bot.loop)
        user_info = "SELECT message_count, reaction_count, special FROM users WHERE user_id = $1"
        words_used = ("SELECT words.word, usage_count, word_count.last_use FROM word_count "
                      "JOIN words ON word_count.word = words.word AND words.excluded = FALSE "
                      "WHERE user_id = $1 ORDER BY usage_count DESC LIMIT $2")
        reactions_used = ("SELECT reactions.reaction, usage_count, reaction_count.last_use, reactions.custom FROM reaction_count "
                          "JOIN reactions ON reaction_count.reaction = reactions.reaction "
                          "WHERE user_id = $1 ORDER BY usage_count DESC LIMIT $2")
        async with db.transaction():
            user_id = who.id
            embed = discord.Embed(colour=discord.Colour(0xb85f98))
            embed.set_author(icon_url=who.avatar_url, name=who.name)
            message_count, reaction_count, special = await db.fetchrow(user_info, str(who.id))
            if user_id == 186829544764866560:
                embed.set_footer(text="You said 'By Achenar' {} times.".format(special))
            embed.add_field(name="Message statistics", inline=False,
                            value="You sent {} messages. Top used words:".format(message_count))
            async for (word, count, last_use) in db.cursor(words_used, *(str(user_id), limit)):
                embed.add_field(name=word, inline=True, value="{0:4} time(s)\nLast use: {1}".format(count,
                                                                                '{:%d.%m.%Y %H:%M}'.format(
                                                                                last_use)))
            embed.add_field(name="Reaction statistics", inline=False,
                            value="You used {} reactions. Top used reactions:".format(reaction_count))
            async for (reaction, count, last_use, custom) in db.cursor(reactions_used, *(str(user_id), limit)):
                emoji = None
                if custom:
                    emoji = self.bot.get_emoji(int(reaction))
                    reaction = "<:{}:{}>".format(emoji.name, emoji.id)
                embed.add_field(name=emoji or reaction, inline=True, value="{0:4} time(s)\nLast use: {1}"
                                .format(count, '{:%d.%m.%Y %H:%M}'.format(last_use)))
            await ctx.send(embed=embed)
            await ctx.message.delete(reason="Command cleanup")
        await database.Database.close_connection(db)

    @commands.command()
    async def diamonds(self, ctx, who=None):
        link = user_data_link
        if who:
            who = await commands.MemberConverter().convert(ctx, who)
        else:
            who = ctx.message.author
        args = {
            'discord_id': who.id
        }
        response = await Web.get_response(link, args)
        to_delete = [ctx.message]
        sleep = 2
        if response['Response'] == 'User not found':
            if who is ctx.message.author:
                to_delete.append(await ctx.send("❌ This account is not linked"))
            else:
                sleep = 10
                to_delete.append(await ctx.send("❌ Link your account first. Use !link {verification_code} {website_username} . You can find your verification code on website."))
        else:
            count = int(response['Diamonds'])
            emoji_type = ''
            if count > 500:
                emoji_type = 2
            elif count > 2500:
                emoji_type = 3
            elif count > 10000:
                emoji_type = 4
            try:
                emoji = await commands.EmojiConverter().convert(ctx, "diamond{}".format(emoji_type))
            except commands.CommandError as err:
                emoji = '💎'
            embed = discord.Embed(description="{} {}".format(emoji, count), color=discord.Colour.blue())
            rank = ""
            if response['Prismatic_rank'] != 'None':
                rank = response['Prismatic_rank']
            embed.set_author(icon_url=who.avatar_url, name="{} {}".format(rank, who.name))
            await ctx.send(embed=embed)
        await asyncio.sleep(sleep)
        await ctx.channel.delete_messages(to_delete, reason="Command cleanup")

    @commands.command()
    async def word(self, ctx: commands.Context, *args):
        to_delete = [ctx.message]
        if args.__len__() < 1:
            to_delete.append(await ctx.send('You must provide a word'))
            await asyncio.sleep(5)
            await ctx.channel.delete_messages(to_delete, reason="Command cleanup")
            return
        what = args[0].lower().strip()
        db = await database.Database.get_connection()
        counts = ("SELECT count(*) AS people, words.word, sum(usage_count) AS count, words.last_use "
                  "FROM word_count "
                  "JOIN words ON word_count.word = words.word "
                  "WHERE words.word = $1"
                  "GROUP BY words.word")
        times = ("SELECT word_count.last_use, usage_count FROM word_count "
                 "JOIN users ON users.user_id = word_count.user_id "
                 "JOIN words ON word_count.word = words.word "
                 "WHERE users.user_id = $1 AND words.word = $2")
        async with db.transaction():
            try:
                people, word, count, use = await db.fetchrow(counts, what)
                last_use, usage = await db.fetchrow(times, *(str(ctx.message.author.id), what))
                embed = discord.Embed(title=what, color=13434828, description="Word {} was used {} times by {} people, {} times by you".format(word, count, people, usage))
                embed.add_field(name="Your last use", value="{:%d.%m.%Y %H:%M}".format(last_use))
                embed.add_field(name="General last use", value="{:%d.%m.%Y %H:%M}".format(use))
            except TypeError as e:
                embed = discord.Embed(title=what, color=13434828,description="Word {} was never used before.".format(what))
        await ctx.send("", embed=embed)
        await ctx.channel.delete_messages(to_delete, reason="Command cleanup")
        await database.Database.close_connection(db)

def setup(bot: commands.Bot):
    bot.add_cog(Stats(bot))
<|endoftext|>


<commit_before>from django.contrib import admin
from django.forms import TextInput, Textarea, SelectMultiple
from django.db import models
from sam.models import *

class TagAdmin(admin.ModelAdmin):
    """ The admin model for a Tag
    """
admin.site.register(Tag, TagAdmin)

class WebsiteAdmin(admin.ModelAdmin):
    """ The admin model for a Website
    """
    list_display = ("display",
                    "url",
                    "kind",
                    "private")
    list_filter = ["display",
                   "private"]
    actions = ["mark_private",
               "mark_public"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Website:
            queryset.private = True
            queryset.save()
        else:
            for site in queryset.all():
                site.private = True
                site.save()
    mark_private.short_description = "Mark all as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Website:
            queryset.private = False
            queryset.save()
        else:
            for site in queryset.all():
                site.private = False
                site.save()
    mark_public.short_description = "Mark all as public"

admin.site.register(Website, WebsiteAdmin)

class SiteImageAdmin(admin.ModelAdmin):
    """ The admin model for a SiteImage.
    Content-type, width, and height, are all filled in on Image save.
    """
    list_filter = ['name']
    list_display = ("name", "private")
    exclude = ('content_type', 'width', 'height', 'comments', 'description')
    readonly_fields = ('view_count',)
    actions = ["mark_private",
               "mark_public",
               "delete_model"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == SiteImage:
            queryset.private = True
            queryset.save()
        else:
            for image in queryset.all():
                image.private = True
                image.save()
    mark_private.short_description = "Mark all as private"

    def mark_public(self, request, queryset):
        if type(queryset) == SiteImage:
            queryset.private = False
            queryset.save()
        else:
            for image in queryset.all():
                image.private = False
                image.save()
    mark_public.short_description = "Mark all as public"

    def get_actions(self, request):
        actions = super(SiteImageAdmin, self).get_actions(request)
        del actions['delete_selected']
        return actions

    def delete_model(self, request, queryset):
        if type(queryset) == SiteImage:
            queryset.delete()
        else:
            for image in queryset.all():
                image.delete()
    delete_model.short_description = "Delete selected Images"

admin.site.register(SiteImage, SiteImageAdmin)

class QuoteAdmin(admin.ModelAdmin):
    """ The admin model for a Quote.
    """
    list_filter = ['author']
    list_display = ("author", "quote")
    actions = ["mark_private",
               "mark_public"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Quote:
            queryset.private = True
            queryset.save()
        else:
            for quote in queryset.all():
                quote.private = True
                quote.save()
    mark_private.short_description = "Mark all as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Quote:
            queryset.private = False
            queryset.save()
        else:
            for quote in queryset.all():
                quote.private = False
                quote.save()
    mark_public.short_description = "Mark all as public"

admin.site.register(Quote, QuoteAdmin)

class CommentAdmin(admin.ModelAdmin):
    """ The admin model for a Comment.
    """
    list_display = ("name",
                    "subject",
                    "email",
                    "date")
    list_filter = ["name",
                   "email",
                   "date"]
    actions = ["mark_private",
               "mark_public",
               "delete_model"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Comment:
            queryset.private = True
            queryset.save()
        else:
            for comment in queryset.all():
                comment.private = True
                comment.save()
    mark_private.short_description = "Mark all as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Comment:
            queryset.private = False
            queryset.save()
        else:
            for comment in queryset.all():
                comment.private = False
                comment.save()
    mark_public.short_description = "Mark all as public"

#admin.site.register(Comment, CommentAdmin)

class PostAdmin(admin.ModelAdmin):
    """ The admin model for a Blog Post.
    """
    exclude = ('comments',)
    readonly_fields = ('view_count', 'content',)
    list_display = ("title",
                    "creation_date")
    list_filter = ["title",
                   "tags",
                   "creation_date"]
    actions = ["mark_private",
               "mark_public",]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Post:
            queryset.private = True
            queryset.save()
        else:
            for post in queryset.all():
                post.private = True
                post.save()
    mark_private.short_description = "Mark all as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Post:
            queryset.private = False
            queryset.save()
        else:
            for post in queryset.all():
                post.private = False
                post.save()
    mark_public.short_description = "Mark all as public"

admin.site.register(Post, PostAdmin)
<commit_msg>updated verbage for admin action<commit_after>from django.contrib import admin
from django.forms import TextInput, Textarea, SelectMultiple
from django.db import models
from sam.models import *

class TagAdmin(admin.ModelAdmin):
    """ The admin model for a Tag
    """
admin.site.register(Tag, TagAdmin)

class WebsiteAdmin(admin.ModelAdmin):
    """ The admin model for a Website
    """
    list_display = ("display",
                    "url",
                    "kind",
                    "private")
    list_filter = ["display",
                   "private"]
    actions = ["mark_private",
               "mark_public"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Website:
            queryset.private = True
            queryset.save()
        else:
            for site in queryset.all():
                site.private = True
                site.save()
    mark_private.short_description = "Mark selected as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Website:
            queryset.private = False
            queryset.save()
        else:
            for site in queryset.all():
                site.private = False
                site.save()
    mark_public.short_description = "Mark selected as public"

admin.site.register(Website, WebsiteAdmin)

class SiteImageAdmin(admin.ModelAdmin):
    """ The admin model for a SiteImage.
    Content-type, width, and height, are all filled in on Image save.
    """
    list_filter = ['name']
    list_display = ("name", "private")
    exclude = ('content_type', 'width', 'height', 'comments', 'description')
    readonly_fields = ('view_count',)
    actions = ["mark_private",
               "mark_public",
               "delete_model"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == SiteImage:
            queryset.private = True
            queryset.save()
        else:
            for image in queryset.all():
                image.private = True
                image.save()
    mark_private.short_description = "Mark selected as private"

    def mark_public(self, request, queryset):
        if type(queryset) == SiteImage:
            queryset.private = False
            queryset.save()
        else:
            for image in queryset.all():
                image.private = False
                image.save()
    mark_public.short_description = "Mark selected as public"

    def get_actions(self, request):
        actions = super(SiteImageAdmin, self).get_actions(request)
        del actions['delete_selected']
        return actions

    def delete_model(self, request, queryset):
        if type(queryset) == SiteImage:
            queryset.delete()
        else:
            for image in queryset.all():
                image.delete()
    delete_model.short_description = "Delete selected Images"

admin.site.register(SiteImage, SiteImageAdmin)

class QuoteAdmin(admin.ModelAdmin):
    """ The admin model for a Quote.
    """
    list_filter = ['author']
    list_display = ("author", "quote", "private")
    actions = ["mark_private",
               "mark_public"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Quote:
            queryset.private = True
            queryset.save()
        else:
            for quote in queryset.all():
                quote.private = True
                quote.save()
    mark_private.short_description = "Mark selected as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Quote:
            queryset.private = False
            queryset.save()
        else:
            for quote in queryset.all():
                quote.private = False
                quote.save()
    mark_public.short_description = "Mark selected as public"

admin.site.register(Quote, QuoteAdmin)

class CommentAdmin(admin.ModelAdmin):
    """ The admin model for a Comment.
    """
    list_display = ("name",
                    "subject",
                    "email",
                    "date")
    list_filter = ["name",
                   "email",
                   "date"]
    actions = ["mark_private",
               "mark_public",
               "delete_model"]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Comment:
            queryset.private = True
            queryset.save()
        else:
            for comment in queryset.all():
                comment.private = True
                comment.save()
    mark_private.short_description = "Mark selected as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Comment:
            queryset.private = False
            queryset.save()
        else:
            for comment in queryset.all():
                comment.private = False
                comment.save()
    mark_public.short_description = "Mark selected as public"

#admin.site.register(Comment, CommentAdmin)

class PostAdmin(admin.ModelAdmin):
    """ The admin model for a Blog Post.
    """
    exclude = ('comments',)
    readonly_fields = ('view_count', 'content',)
    list_display = ("title",
                    "creation_date")
    list_filter = ["title",
                   "tags",
                   "creation_date"]
    actions = ["mark_private",
               "mark_public",]

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'168'})},
        models.TextField: {'widget': Textarea(attrs={'rows':40, 'cols':120})},
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'15'})}
    }

    def mark_private(self, request, queryset):
        if type(queryset) == Post:
            queryset.private = True
            queryset.save()
        else:
            for post in queryset.all():
                post.private = True
                post.save()
    mark_private.short_description = "Mark selected as private"

    def mark_public(self, request, queryset):
        if type(queryset) == Post:
            queryset.private = False
            queryset.save()
        else:
            for post in queryset.all():
                post.private = False
                post.save()
    mark_public.short_description = "Mark selected as public"

admin.site.register(Post, PostAdmin)
<|endoftext|>