<commit_before>import os
import pwd
from twisted.internet import defer
from twisted.internet.endpoints import TCP4ClientEndpoint
from twisted.conch.ssh import connection, common
from twisted.conch.ssh.connection import SSHConnection
from twisted.conch.client.default import SSHUserAuthClient
from twisted.conch.client.options import ConchOptions
from carnifex.inductor import ProcessInductor
from carnifex.ssh.client import SSHClientFactory
from carnifex.ssh.session import SSHSession
from carnifex.ssh.command import SSHCommand

class SSHProcessInductor(ProcessInductor):
    _sep = ';' # '&&' to fail fast or ';' to continue on fails
    _cd = 'cd'

    def __init__(self, reactor, host, port, timeout=30, bindAddress=None,
                 precursor=None):
        self._connections = {}
        self.reactor = reactor
        self.endpoint = TCP4ClientEndpoint(reactor, host, port, timeout,
                                           bindAddress)
        self.precursor = precursor # 'source /etc/profile'

    def execute(self, processProtocol, command, env={},
                path=None, uid=None, gid=None, usePTY=0, childFDs=None):
        """Execute a process on the remote machine using SSH

        @param processProtocol: the ProcessProtocol instance to connect
        @param executable: the executable program to run
        @param args: the arguments to pass to the process
        @param env: environment variables to request the remote ssh server to set
        @param path: the remote path to start the remote process on
        @param uid: user id or username to connect to the ssh server with
        @param gid: this is not used for remote ssh processes
        @param usePTY: wither to request a pty for the process
        @param childFDs: file descriptors to use for stdin, stdout and stderr
        """

        sshCommand = (command if isinstance(command, SSHCommand)
                      else SSHCommand(command, self.precursor, path))
        commandLine = sshCommand.getCommandLine()

        user = self._getUser(uid)

        # Get connection to ssh server
        connectionDeferred = self.getConnection(user)
        @connectionDeferred.addCallback
        def executeCommand(connection):
            connection.openChannel(session)
            @sessionOpenDeferred.addCallback
            def sessionOpened(specificData):
                # Send requests to set the environment variables
                for variable, value in env.iteritems():
                    data = common.NS(variable) + common.NS(value)
                    connection.sendRequest(session, 'env', data)
                # Send request to exec the command line
                return connection.sendRequest(session, 'exec',
                                              common.NS(commandLine),
                                              wantReply=True)
            return sessionOpenDeferred

        return session

    def getConnection(self, user):
        options = ConchOptions()
        verifyHostKey = lambda *a, **kwa: defer.succeed(True)

        serviceStartedDeferred = defer.Deferred()
        serviceStoppedDeferred = defer.Deferred()
        connection = SSHConnection()
        connection.serviceStarted = lambda: serviceStartedDeferred.callback(None)
        connection.serviceStopped = lambda: serviceStoppedDeferred.callback(None)
        @serviceStartedDeferred.addCallback
        def connectionServiceStarted(result):
            self._connections[user] = connection
            self._disconnectDeferred = serviceStoppedDeferred
            return connection
        @serviceStoppedDeferred.addCallback
        def connectionServiceStopped(result):
            del self._connections[user]

        userAuthObject = SSHUserAuthClient(user, options, connection)

        connectionLostDeferred = defer.Deferred()
        sshClientFactory = SSHClientFactory(verifyHostKey, userAuthObject)
        sshClientFactory.clientConnectionFailed = lambda _, reason: serviceStartedDeferred.errback(reason)
        sshClientFactory.clientConnectionLost = connectionLostDeferred.errback

        connectionDeferred = self.endpoint.connect(sshClientFactory)
        @connectionDeferred.addCallback
        def connected(transport):
            self._transport = transport
            return serviceStartedDeferred
        return connectionDeferred

    def disconnectAll(self):
        for connection in self._connections.values():
            connection.transport.loseConnection()

    def disconnectUser(self, user):
        connection = self._connections[user]
        connection.transport.loseConnection()

    def _getUser(self, uid):
        # Get the username from a uid, or use current user
        uid = uid or self._defaultUser or os.getuid()
        if isinstance(uid, int):
            user = pwd.getpwuid(uid).pw_name
        else:
            user = uid
        return user
    def __del__(self):
        self.disconnectAll()
<commit_msg>Support for verifying host keys automatically for known hosts<commit_after>import os
import pwd
from twisted.internet import defer
from twisted.internet.endpoints import TCP4ClientEndpoint
from twisted.conch.ssh import connection, common
from twisted.conch.ssh.connection import SSHConnection
from twisted.conch.client.default import SSHUserAuthClient
from twisted.conch.client.options import ConchOptions
from carnifex.inductor import ProcessInductor
from carnifex.ssh.client import SSHClientFactory
from carnifex.ssh.session import SSHSession
from carnifex.ssh.command import SSHCommand

class UnknownHostKey(Exception):
    """Raised when we reject validation of a server's host key
    """
    pass

class AllHostKeys(object):
    """Placeholder for known hosts container to allow all host keys.
    """
    def __contains__(self, key):
        return True
allHostKeys = AllHostKeys()

class SSHProcessInductor(ProcessInductor):
    _sep = ';' # '&&' to fail fast or ';' to continue on fails
    _cd = 'cd'
    knownHosts = allHostKeys

    def __init__(self, reactor, host, port, timeout=30, bindAddress=None,
                 precursor=None):
        self._connections = {}
        self.reactor = reactor
        self.endpoint = TCP4ClientEndpoint(reactor, host, port, timeout,
                                           bindAddress)
        self.precursor = precursor # 'source /etc/profile'

    def addKnownHost(self, hostKey, fingerprint):
        if self.knownHosts == allHostKeys:
            self.knownHosts = {}
        self.knownHosts[fingerprint] = hostKey

    def execute(self, processProtocol, command, env={},
                path=None, uid=None, gid=None, usePTY=0, childFDs=None):
        """Execute a process on the remote machine using SSH

        @param processProtocol: the ProcessProtocol instance to connect
        @param executable: the executable program to run
        @param args: the arguments to pass to the process
        @param env: environment variables to request the remote ssh server to set
        @param path: the remote path to start the remote process on
        @param uid: user id or username to connect to the ssh server with
        @param gid: this is not used for remote ssh processes
        @param usePTY: wither to request a pty for the process
        @param childFDs: file descriptors to use for stdin, stdout and stderr
        """

        sshCommand = (command if isinstance(command, SSHCommand)
                      else SSHCommand(command, self.precursor, path))
        commandLine = sshCommand.getCommandLine()

        user = self._getUser(uid)

        # Get connection to ssh server
        connectionDeferred = self.getConnection(user)
        @connectionDeferred.addCallback
        def executeCommand(connection):
            connection.openChannel(session)
            @sessionOpenDeferred.addCallback
            def sessionOpened(specificData):
                # Send requests to set the environment variables
                for variable, value in env.iteritems():
                    data = common.NS(variable) + common.NS(value)
                    connection.sendRequest(session, 'env', data)
                # Send request to exec the command line
                return connection.sendRequest(session, 'exec',
                                              common.NS(commandLine),
                                              wantReply=True)
            return sessionOpenDeferred

        return session

    def getConnection(self, user):
        options = ConchOptions()
        verifyHostKey = lambda *a, **kwa: defer.succeed(True)

        serviceStartedDeferred = defer.Deferred()
        serviceStoppedDeferred = defer.Deferred()
        connection = SSHConnection()
        connection.serviceStarted = lambda: serviceStartedDeferred.callback(None)
        connection.serviceStopped = lambda: serviceStoppedDeferred.callback(None)
        @serviceStartedDeferred.addCallback
        def connectionServiceStarted(result):
            self._connections[user] = connection
            self._disconnectDeferred = serviceStoppedDeferred
            return connection
        @serviceStoppedDeferred.addCallback
        def connectionServiceStopped(result):
            del self._connections[user]

        userAuthObject = SSHUserAuthClient(user, options, connection)

        connectionLostDeferred = defer.Deferred()
        sshClientFactory = SSHClientFactory(verifyHostKey, userAuthObject)
        sshClientFactory.clientConnectionFailed = lambda _, reason: serviceStartedDeferred.errback(reason)
        sshClientFactory.clientConnectionLost = connectionLostDeferred.errback

        connectionDeferred = self.endpoint.connect(sshClientFactory)
        @connectionDeferred.addCallback
        def connected(transport):
            self._transport = transport
            return serviceStartedDeferred
        return connectionDeferred

    def disconnectAll(self):
        for connection in self._connections.values():
            connection.transport.loseConnection()

    def disconnectUser(self, user):
        connection = self._connections[user]
        connection.transport.loseConnection()

    def _getUser(self, uid):
        # Get the username from a uid, or use current user
        uid = uid or self._defaultUser or os.getuid()
        if isinstance(uid, int):
            user = pwd.getpwuid(uid).pw_name
        else:
            user = uid
        return user

    def _verifyHostKey(self, hostKey, fingerprint):
        """Called when ssh transport requests us to verify a given host key.
        Return a deferred that callback if we accept the key or errback if we
        decide to reject it.
        """
        if fingerprint in self.knownHosts:
            return defer.succeed(True)
        return defer.fail(UnknownHostKey(hostKey, fingerprint))

    def __del__(self):
        self.disconnectAll()
<|endoftext|>


<commit_before>import os, tempfile
import compile, style, output
from compile import compile
from style import stylesheet_rulesets, rulesets_declarations, stylesheet_declarations

try:
    import mapnik
except ImportError:
    # it's not going to be possible to use load_map(), but nothing else requires mapnik
    pass

def load_map(map, input):
    """
    """
    (handle, compiled) = tempfile.mkstemp('.xml', 'cascadenik-compiled-')
    os.close(handle)

    open(compiled, 'w').write(compile(input))
    return mapnik.load_map(map, compiled)
<commit_msg>oops<commit_after>import os, tempfile
import compile, style
from compile import compile
from style import stylesheet_rulesets, rulesets_declarations, stylesheet_declarations

try:
    import mapnik
except ImportError:
    # it's not going to be possible to use load_map(), but nothing else requires mapnik
    pass

def load_map(map, input):
    """
    """
    (handle, compiled) = tempfile.mkstemp('.xml', 'cascadenik-compiled-')
    os.close(handle)

    open(compiled, 'w').write(compile(input))
    return mapnik.load_map(map, compiled)
<|endoftext|>


<commit_before>#!/usr/bin/python

import sys, re, pdb
import logging
import argparse

import numpy as np, pandas as pd

import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')

import utils, data_helper, analysis

def parse_args():
    parser = argparse.ArgumentParser(description='SOPERNOVUS analysator')
    parser.add_argument('--input-file', help='Input CSV file', required=True)
    parser.add_argument('--output-file', help='Output CSV file', required=False, default = None)
    args = vars(parser.parse_args())
    return args

def main():
    args = parse_args()
    inputFileName = args['input_file']
    outputFileName = args['output_file']

    utils.log_config()
    logger = logging.getLogger(__name__)

    logger.info("Data file: {}".format(inputFileName))

    # exported to global scope for debugging purposes
    global df

    df = data_helper.import_data(inputFileName)

    logger.info("N of events: {}, from {} to {} ".format(len(df), df['datetime'].min(), df['datetime'].max()))

    # exported to global scope for debugging purposes
    global apps
    apps =  analysis.summarize_applications(df)

    logger.info("N of applications = {}".format(len(apps)))

    print(apps)

    if outputFileName is not None:
        apps.to_csv(outputFileName, sep=';', encoding='utf-8')
    else:
        print apps

    print("Succesfully parsed {} apps".format(len(apps)))

if __name__ == "__main__":
    main()
<commit_msg>command line args shortcut<commit_after>#!/usr/bin/python

import sys, re, pdb
import logging
import argparse

import numpy as np, pandas as pd

import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')

import utils, data_helper, analysis

def parse_args():
    parser = argparse.ArgumentParser(description='SOPERNOVUS analysator')
    parser.add_argument('-i', '--input-file', help='Input CSV file', required=True)
    parser.add_argument('-o', '--output-file', help='Output CSV file', required=False, default = None)
    args = vars(parser.parse_args())
    return args

def main():
    args = parse_args()
    inputFileName = args['input_file']
    outputFileName = args['output_file']

    utils.log_config()
    logger = logging.getLogger(__name__)

    logger.info("Data file: {}".format(inputFileName))

    # exported to global scope for debugging purposes
    global df

    df = data_helper.import_data(inputFileName)

    logger.info("N of events: {}, from {} to {} ".format(len(df), df['datetime'].min(), df['datetime'].max()))

    # exported to global scope for debugging purposes
    global apps
    apps =  analysis.summarize_applications(df)

    logger.info("N of applications = {}".format(len(apps)))

    print(apps)

    if outputFileName is not None:
        apps.to_csv(outputFileName, sep=';', encoding='utf-8')
    else:
        print apps

    print("Succesfully parsed {} apps".format(len(apps)))

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


<commit_before># Copyright (C) 2017 Forest and Biomass Romania
# Copyright (C) 2020 Terrabit
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import os

from odoo import SUPERUSER_ID, api, tools

def post_init_hook(cr, registry):

    path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")

    files = ["res.country.zone.csv", "res.country.state.csv", "res.country.commune.csv"]
    for file in files:
        with tools.file_open(path + "/" + file, mode="rb") as fp:
            tools.convert_csv_import(
                cr,
                "base",
                file,
                fp.read(),
                {},
                mode="init",
                noupdate=True,
            )
    with api.Environment.manage():
        env = api.Environment(cr, SUPERUSER_ID, {})
        env["res.partner"]._install_l10n_ro_siruta()
<commit_msg>Fix pre-commit.<commit_after># Copyright (C) 2017 Forest and Biomass Romania
# Copyright (C) 2020 Terrabit
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import os

from odoo import SUPERUSER_ID, api, tools

def post_init_hook(cr, registry):

    path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")

    files = ["res.country.zone.csv", "res.country.state.csv", "res.country.commune.csv"]
    for file in files:
        with tools.file_open(path + "/" + file, mode="rb") as fp:
            tools.convert_csv_import(
                cr, "base", file, fp.read(), {}, mode="init", noupdate=True,
            )
    with api.Environment.manage():
        env = api.Environment(cr, SUPERUSER_ID, {})
        env["res.partner"]._install_l10n_ro_siruta()
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Copyright 2016 BMC Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import apachelog
import os
import sys
from log_utils import LogfileParser, parse_apache_line
from tspapi import API
from tspapi import Measurement

class ApacheLogfileParser(LogfileParser):
    def __init__(self, path=None):
        super(ApacheLogfileParser, self).__init__(path)
        log_format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}\i"'
        self.parser = apachelog.parser(log_format)
        self.api = API()
        # Set our application id from the environment variable
        self.appl_id = os.environ['TSI_APPL_ID']

    def send_measurements(self, measurements):
        """
        Sends measurements to standard out to be read by plugin manager

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def parse_line(self):
        """
        Parse each of the lines of the Apache HTTP server access log.
        :return:
        """
        parsed = parse_apache_line(self.parser, self.line)
        measurements = []
        user_agent = parsed['%{User-Agent}\i"']
        bytes = int(parsed['%b'])
        status_code = parsed['%>s']
        properties = {"appl_id", self.appl_id}
        # Split the line by spaces and get the request in the first value
        request = parsed['%r'].split(' ')[0]
        print("user_agent: {0}, bytes: {1}, request: {2}, status_code: {3}".format(
                user_agent, bytes, request, status_code))

        measurements.append(Measurement(
                metric='HTTP_REQUESTS',
                value=1, source=request,
                properities=properties))
        measurements.append(Measurement(
                metric='HTTP_BYTES',
                value=bytes,
                source=user_agent,
                properities=properties))
        self.send_measurements(measurements)

        if __name__ == '__main__':
            if
        len(sys.argv) == 2:
        parser = ApacheLogfileParser(path=sys.argv[1])
        parser.monitor_file()
        else:
        sys.stderr.write("{0}".format(os.path.basename(sys.argv[0])))
<commit_msg>named arguments for properties misspelled ; push application id to parent class ; fix running of script as main<commit_after>#!/usr/bin/env python
#
# Copyright 2016 BMC Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import apachelog
import os
import sys
from log_utils import LogfileParser, parse_apache_line
from tspapi import API
from tspapi import Measurement

class ApacheLogfileParser(LogfileParser):
    def __init__(self, path=None):
        super(ApacheLogfileParser, self).__init__(path)
        log_format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}\i"'
        self.parser = apachelog.parser(log_format)
        self.api = API()

    def send_measurements(self, measurements):
        """
        Sends measurements to standard out to be read by plugin manager

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def parse_line(self):
        """
        Parse each of the lines of the Apache HTTP server access log.
        :return:
        """
        parsed = parse_apache_line(self.parser, self.line)
        measurements = []
        user_agent = parsed['%{User-Agent}\i"']
        bytes = int(parsed['%b'])
        status_code = parsed['%>s']
        properties = {"appl_id", self.appl_id}
        # Split the line by spaces and get the request in the first value
        request = parsed['%r'].split(' ')[0]
        print("user_agent: {0}, bytes: {1}, request: {2}, status_code: {3}".format(
                user_agent, bytes, request, status_code))

        measurements.append(Measurement(
                metric='HTTP_REQUESTS',
                value=1, source=request,
                properties=properties))
        measurements.append(Measurement(
                metric='HTTP_BYTES',
                value=bytes,
                source=user_agent,
                properties=properties))
        self.send_measurements(measurements)

        if __name__ == '__main__':
            if len(sys.argv) == 2:
                parser = ApacheLogfileParser(path=sys.argv[1])
                parser.monitor_file()
            else:
                sys.stderr.write("{0}".format(os.path.basename(sys.argv[0])))
<|endoftext|>


<commit_before>from sys import argv, exit
from pprint import pformat, pprint
from os.path import abspath
from tqdm import tqdm, trange
from itertools import combinations
from collections import Counter
from functions import phash64, dhash, dhash_freesize, \
                      hamming, longuest_repeated_string, \
                      get_indexes, hamming_match, \
                      get_hash_of_hashes, sliding_window, \
                      compress_indexes, merge_intervals, mseq, cseq, \
                      get_scenes_segmentation
from skvideo.io import vreader, ffprobe
from subprocess import call
from time import sleep
from base64 import b64decode
from sklearn.cluster import KMeans
import os
import warnings
import numpy as np

def get_metdata(path: str):
    a = ffprobe(path)['video']
    # print('FFPROBE :', path, pformat(a))
    return a

if __name__ == '__main__':
    stats = []

    SLIDING_WINDOW  = int(os.environ['SLIDING_WINDOW'])
    SEQUENCE_LENGTH = int(os.environ['SEQUENCE_LENGTH'])

    ORIGINAL_VIDEOS = []
    # First argument is a path to original videos informations
    with open(argv[1], 'r') as f:
        for line in f:
            idx, source, encoded = line.split(';')
            ORIGINAL_VIDEOS += [{
                "index": int(idx) - 1,
                "source": source,
                "encoded": encoded.replace('\n', '')
            }]
        ORIGINAL_VIDEOS = [(v['source'], v['encoded']) for v in sorted(ORIGINAL_VIDEOS, key=lambda x: x['index'])]
        print(ORIGINAL_VIDEOS)

    # Temporary arg parsing
    for _, source in zip(trange( \
                            len(argv) - 2, \
                            desc='Files', \
                            ), \
                         argv[2:]):

        # Loading source video
        VIDEO_PATH = abspath(source)

        if not os.access(VIDEO_PATH, os.R_OK):
            print('Internal error, source file is not avaliable')
            exit(1)
        METADATA = get_metdata(source)
        VIDEO_FRAMES_COUNT = int(METADATA["@nb_frames"])
        VIDEO_TIME_BASE = eval(METADATA["@codec_time_base"])
        # VIDEO_FRAMES_COUNT = 100000
        cap = vreader(VIDEO_PATH)

        L = []
        diffs = [0]

        # Hashing
        for _, frame in zip(trange(VIDEO_FRAMES_COUNT, leave=False), cap):
            hash_img = int(phash64(frame))
            if len(L):
                diffs.append(hamming(hash_img, L[-1]))
            L.append(hash_img)

        # Get scene segmentation and their hash
        scenes = get_scenes_segmentation(diffs, nb_std_above_mean_th=2.5)
        scenes_hashes = [get_hash_of_hashes(L[s:e]) for s, e in scenes]
        scenes_hashes_vector = list(map(lambda k: list(map(int, list(bin(k)[2:]))), scenes_hashes))
        scenes_hashes_vector = list(map(lambda v: [0] * (64 - len(v)) + v, scenes_hashes_vector)) # 0 padding to get the same length
        scenes_hashes_vector = np.array(scenes_hashes_vector)

        tqdm.write(pformat(Counter(scenes_hashes)))

        #TODO: make clustering to find clusters with the greatest density
        #those could be the generics and redundant parts...
        kmean = KMeans(n_clusters=len(scenes_hashes_vector) // int(np.log(len(scenes_hashes_vector))))
        scenes_clusters = kmean.fit_predict(scenes_hashes_vector)
        scenes_clusters_freq = Counter(scenes_clusters)
        scene_freq = np.array(list(scenes_clusters_freq.values()))
        min_scene_freq = scene_freq.mean() + scene_freq.std() * 3
        redundant_scenes_clusters_id = list(filter(
            lambda k: scenes_clusters_freq[k] >= min_scene_freq,
            scenes_clusters_freq.keys()
        ))
        redudant_scenes = set([i if w else -1 for i, w in enumerate(map(lambda v: v in redundant_scenes_clusters_id, scenes_clusters))])
        redudant_scenes.remove(-1)
        redudant_scenes = sorted(list(redudant_scenes))
        print(len(redudant_scenes))

        for rs in redudant_scenes:
            print(scenes[rs])

        count_tab = Counter(L)
        collisions = sum(count_tab.values()) - len(count_tab)
        assert len(L) == VIDEO_FRAMES_COUNT
        stats += [{
            'source': VIDEO_PATH,
            'frames': VIDEO_FRAMES_COUNT,
            'time_base': VIDEO_TIME_BASE,
            'collisions': collisions,
            'datas': {
                'diffs': diffs,
                'hashes': L
            },
        }]

        #for v in L:
        #    print(v)

        f = open("/cache/L.txt", "w")
        f.write(str(L))
        f.close()

        #try to automatically find a good SEQUENCE_LENGTH
        s_mseq = mseq(L)
        h_mseq = get_hash_of_hashes(s_mseq)
        print("potential sequence of ints representing the generic : ")
        print(s_mseq)
        print("correspinding sequence hash :")
        print(h_mseq)
        print(h_mseq)
        print(h_mseq)

        SEQUENCE_LENGTH = len(s_mseq)

        #trying some stuffs about sequence hashing
        sequences = list(sliding_window(L, SEQUENCE_LENGTH, SLIDING_WINDOW, get_hash_of_hashes))
        c = Counter(sequences)
        # tqdm.write(pformat(c, indent=2, depth=2))

        tqdm.write(pformat(c.most_common()[:10]))

        best = c.most_common(1)[0][0]
        indexes = [x for x, s in enumerate(sequences) if s == best]
        #tqdm.write('[matchs] %d [indexes] %s' % (
        #    c.most_common(1)[0][1],
        #    indexes
        #))

    tqdm.write(pformat(stats, indent=2, depth=2))
    tqdm.write(pformat(ORIGINAL_VIDEOS, indent=2, depth=2))
    for stat in stats:
        tqdm.write('Frames: %s %s %s' % (stat['frames'], 'TimeBase:', stat['time_base']))
    start_frame = 0
    idx = 0

    ## DEPRECATED
    ##compressed_indexes = compress_indexes(indexes)
    ## we can choose to take juste the first index matched by sequence
    ## or take the middle sequence index... just a question of POV...
    ##indexes = d.keys() #here we take the first
    ##indexes = map(lambda k: int(k + compressed_indexes[k] / 2.),
    ##              compressed_indexes.keys()) #here we take the mean
    indexes = map(lambda t: (t[0] + t[1]) // 2,
                  merge_intervals(indexes, SEQUENCE_LENGTH))

    indexes = sorted(indexes)

    tqdm.write(str(indexes))
    tqdm.write("# matchs : {}".format(len(indexes)))
    #"""
    for match in indexes:
        found = False

        for source, dest in ORIGINAL_VIDEOS[idx:]:
            # destination video
            time_base = eval(get_metdata(dest + ".mp4")["@codec_time_base"])
            video_frames = int(get_metdata(dest + ".mp4")["@nb_frames"])

            # print(start_frame, '+', video_frames, '>', match)
            if start_frame + video_frames > match:
                print('timeout 2 vlc --start-time=%s "videos/%s";' % (match - start_frame, source))
                found = True
                break
            idx += 1
            start_frame += video_frames

        # If this assertion raise, we were not able to locate match in source videos
        assert found is True
    #"""
<commit_msg>Testing new methods for scene cut detection and clusturing...<commit_after>from sys import argv, exit
from pprint import pformat, pprint
from os.path import abspath
from tqdm import tqdm, trange
from itertools import combinations
from collections import Counter
from functions import phash64, dhash, dhash_freesize, \
                      hamming, longuest_repeated_string, \
                      get_indexes, hamming_match, \
                      get_hash_of_hashes, sliding_window, \
                      compress_indexes, merge_intervals, mseq, cseq, \
                      get_scenes_segmentation, get_joly_scenes_sementation
from skvideo.io import vreader, ffprobe
from subprocess import call
from time import sleep
from base64 import b64decode
from sklearn.cluster import KMeans, MeanShift, AffinityPropagation
import os
import warnings
import numpy as np

def get_metdata(path: str):
    a = ffprobe(path)['video']
    # print('FFPROBE :', path, pformat(a))
    return a

if __name__ == '__main__':
    stats = []

    SLIDING_WINDOW  = int(os.environ['SLIDING_WINDOW'])
    SEQUENCE_LENGTH = int(os.environ['SEQUENCE_LENGTH'])

    ORIGINAL_VIDEOS = []
    # First argument is a path to original videos informations
    with open(argv[1], 'r') as f:
        for line in f:
            idx, source, encoded = line.split(';')
            ORIGINAL_VIDEOS += [{
                "index": int(idx) - 1,
                "source": source,
                "encoded": encoded.replace('\n', '')
            }]
        ORIGINAL_VIDEOS = [(v['source'], v['encoded']) for v in sorted(ORIGINAL_VIDEOS, key=lambda x: x['index'])]
        print(ORIGINAL_VIDEOS)

    # Temporary arg parsing
    for _, source in zip(trange( \
                            len(argv) - 2, \
                            desc='Files', \
                            ), \
                         argv[2:]):

        # Loading source video
        VIDEO_PATH = abspath(source)

        if not os.access(VIDEO_PATH, os.R_OK):
            print('Internal error, source file is not avaliable')
            exit(1)
        METADATA = get_metdata(source)
        VIDEO_FRAMES_COUNT = int(METADATA["@nb_frames"])
        VIDEO_TIME_BASE = eval(METADATA["@codec_time_base"])
        # VIDEO_FRAMES_COUNT = 100000
        cap = vreader(VIDEO_PATH)

        L = []
        diffs = [0]
        frames = []

        # Hashing
        for _, frame in zip(trange(VIDEO_FRAMES_COUNT, leave=False), cap):
            hash_img = int(phash64(frame))
            if len(L):
                diffs.append(hamming(hash_img, L[-1]))
            L.append(hash_img)
            frames.append(frame)

        # Get scene segmentation and their hash
        scenes = get_joly_scenes_sementation(frames, nb_std_above_mean_th=2.)#get_scenes_segmentation(diffs, nb_std_above_mean_th=2.5)
        del frames #not take to much memory too long for nothing...
        scenes_hashes = [get_hash_of_hashes(L[s:e]) for s, e in scenes]

        #tqdm.write(pformat(Counter(scenes_hashes)))

        distance_matrix = np.zeros([len(scenes_hashes)] * 2)
        #compute distance between scenes' hashes
        for i in trange(len(scenes_hashes)):
            for j in range(len(scenes_hashes)):
                distance_matrix[i, j] = hamming(scenes_hashes[i], scenes_hashes[j])
        #find similar scenes which have hases distance too close compared to others
        similar_scenes_matrix = distance_matrix < 64 - (distance_matrix.mean() + distance_matrix.std() * 3)
        #try to automatically found clusters with affinity propagation
        ap = AffinityPropagation()
        scenes_clusters = ap.fit_predict(similar_scenes_matrix)
        #find the clusters with 'too much' points inside compared to others
        clusters_counter = Counter(scenes_clusters)
        clusters_freq = np.array(list(clusters_counter.values()))
        clusters_freq_th = clusters_freq.mean() + clusters_freq.std() * 2.5
        frequent_clusters_id = list(filter(lambda k: clusters_counter[k] > clusters_freq_th, clusters_counter))
        #find hashes corresponding to these clusters
        scenes_hashes_idx = np.array(list(map(lambda v: v in frequent_clusters_id, scenes_clusters)))
        generics_scenes_hashes = np.array(scenes_hashes, dtype=np.uint64)[scenes_hashes_idx]
        #get the generics indexes from the scene hashes
        generics_scenes_idx = []
        for i, h in enumerate(scenes_hashes):
            if h in generics_scenes_hashes:
                generics_scenes_idx.append(i)
        #get the boundaries of gnerics scenes
        generics_scenes = list(map(lambda i: scenes[i], generics_scenes_idx))

        tqdm.write(str(len(generics_scenes)))
        tqdm.write(pformat(list(generics_scenes)))

        scenes_hashes_vector = list(map(lambda k: list(map(int, list(bin(k)[2:]))), scenes_hashes))
        scenes_hashes_vector = list(map(lambda v: [0] * (64 - len(v)) + v, scenes_hashes_vector)) # 0 padding to get the same length
        scenes_hashes_vector = np.array(scenes_hashes_vector)
        #TODO: make clustering to find clusters with the greatest density
        #those could be the generics and redundant parts...
        kmean = KMeans(n_clusters=len(scenes_hashes_vector) // int(np.log(len(scenes_hashes_vector))))
        scenes_clusters = kmean.fit_predict(scenes_hashes_vector)
        scenes_clusters_freq = Counter(scenes_clusters)
        scene_freq = np.array(list(scenes_clusters_freq.values()))
        min_scene_freq = scene_freq.mean() + scene_freq.std() * 3
        redundant_scenes_clusters_id = list(filter(
            lambda k: scenes_clusters_freq[k] >= min_scene_freq,
            scenes_clusters_freq.keys()
        ))
        redudant_scenes = set([i if w else -1 for i, w in enumerate(map(lambda v: v in redundant_scenes_clusters_id, scenes_clusters))])
        try:
            redudant_scenes.remove(-1)
        except:
            pass
        redudant_scenes = sorted(list(redudant_scenes))
        print(len(redudant_scenes))

        for rs in redudant_scenes:
            print(scenes[rs])

        count_tab = Counter(L)
        collisions = sum(count_tab.values()) - len(count_tab)
        assert len(L) == VIDEO_FRAMES_COUNT
        stats += [{
            'source': VIDEO_PATH,
            'frames': VIDEO_FRAMES_COUNT,
            'time_base': VIDEO_TIME_BASE,
            'collisions': collisions,
            'datas': {
                'diffs': diffs,
                'hashes': L
            },
        }]

        #for v in L:
        #    print(v)

        f = open("/cache/L.txt", "w")
        f.write(str(L))
        f.close()

        #try to automatically find a good SEQUENCE_LENGTH
        s_mseq = mseq(L)
        h_mseq = get_hash_of_hashes(s_mseq)
        print("potential sequence of ints representing the generic : ")
        print(s_mseq)
        print("correspinding sequence hash :")
        print(h_mseq)
        print(h_mseq)
        print(h_mseq)

        SEQUENCE_LENGTH = len(s_mseq)

        #trying some stuffs about sequence hashing
        sequences = list(sliding_window(L, SEQUENCE_LENGTH, SLIDING_WINDOW, get_hash_of_hashes))
        c = Counter(sequences)
        # tqdm.write(pformat(c, indent=2, depth=2))

        tqdm.write(pformat(c.most_common()[:10]))

        best = c.most_common(1)[0][0]
        indexes = [x for x, s in enumerate(sequences) if s == best]
        #tqdm.write('[matchs] %d [indexes] %s' % (
        #    c.most_common(1)[0][1],
        #    indexes
        #))

    tqdm.write(pformat(stats, indent=2, depth=2))
    tqdm.write(pformat(ORIGINAL_VIDEOS, indent=2, depth=2))
    for stat in stats:
        tqdm.write('Frames: %s %s %s' % (stat['frames'], 'TimeBase:', stat['time_base']))
    start_frame = 0
    idx = 0

    ## DEPRECATED
    ##compressed_indexes = compress_indexes(indexes)
    ## we can choose to take juste the first index matched by sequence
    ## or take the middle sequence index... just a question of POV...
    ##indexes = d.keys() #here we take the first
    ##indexes = map(lambda k: int(k + compressed_indexes[k] / 2.),
    ##              compressed_indexes.keys()) #here we take the mean
    indexes = map(lambda t: (t[0] + t[1]) // 2,
                  merge_intervals(indexes, SEQUENCE_LENGTH))

    indexes = sorted(indexes)

    ###########
    indexes = np.array(generics_scenes).T[0]
    ###########

    tqdm.write(str(indexes))
    tqdm.write("# matchs : {}".format(len(indexes)))
    #"""
    for match in indexes:
        found = False

        for source, dest in ORIGINAL_VIDEOS[idx:]:
            # destination video
            time_base = eval(get_metdata(dest + ".mp4")["@codec_time_base"])
            video_frames = int(get_metdata(dest + ".mp4")["@nb_frames"])

            # print(start_frame, '+', video_frames, '>', match)
            if start_frame + video_frames > match:
                print('timeout 2 vlc --start-time=%s "videos/%s";' % (match - start_frame, source))
                found = True
                break
            idx += 1
            start_frame += video_frames

        # If this assertion raise, we were not able to locate match in source videos
        assert found is True
    #"""
<|endoftext|>


<commit_before>
import sys

import os
os.environ['PANDA_PRC_DIR'] = os.path.join(os.path.dirname(__file__), 'etc')

# This import should be kept near the top to avoid issues with CEF/Chromium hooking malloc
from cefexample import CEFPanda

from direct.showbase.ShowBase import ShowBase, DirectObject
from direct.interval.LerpInterval import LerpPosInterval

from panda3d.core import *

from combat.terrain import Terrain as CombatTerrain, MAP_SIZE
from combat.player import Player as CombatPlayer
from stance_generator import StanceGenerator

loadPrcFileData("", "textures-power-2 none")

class CombatState(DirectObject.DirectObject):
	def __init__(self):
		self.accept("arrow_up", self.sel_up)
		self.accept("arrow_left", self.sel_left)
		self.accept("arrow_down", self.sel_down)
		self.accept("arrow_right", self.sel_right)
		self.accept("arrow_up-repeat", self.sel_up)
		self.accept("arrow_left-repeat", self.sel_left)
		self.accept("arrow_down-repeat", self.sel_down)
		self.accept("arrow_right-repeat", self.sel_right)
		self.accept("enter", self.accept_selection)
		self.accept("escape", self.escape)
		self.accept("1", self.enter_move_mode)
		self.accept("2", self.enter_attack_mode)
		self.accept("3", self.end_turn)

		base.ui.load('ui.html')

		def stm():
			base.ui.execute_js("switchToMenu('stances')")
		self.accept("space", stm)

		self.terrain = CombatTerrain()
		self.player = CombatPlayer("Player")
		self.player.roll_initiative()

		self.enemies = []
		self.active_set = []

		base.disableMouse()
		base.camera.setPos(25, -25, 28)
		base.camera.setHpr(45, -45, 0)
		base.camLens.setFov(65)

		self.ui_last = self.ui_selection = 0
		base.ui.execute_js("setActiveSelection(%d)" % self.ui_selection, True)

		self.selected_pos = [16, 16, 0]

		self.mode = "NONE"

		# Setup the combatants
		self.player = CombatPlayer("Player", level=3)
		for stance in self.player.stances:
			print(stance)
		stance_str = "[" + ",".join(["'%s'" % i.name for i in self.player.stances]) + "]"
		base.ui.execute_js("setStances(%s)" % stance_str, onload=True)
		self.player.roll_initiative()

		self.enemies = []
		for i in range(3):
			enemy = CombatPlayer.from_player_chassis("clay_golem")
			enemy.grid_position = CombatTerrain.get_random_tile()
			enemy.roll_initiative()
			enemy.target = self.player
			self.enemies.append(enemy)

		self.active_set = []
		self.move_interval = None

	def destroy(self):
		self.ignoreAll()
		for n in base.render.getChildren():
			n.removeNode()

	def escape(self):
		if self.mode == "STANCE":
			self.ui_selection = 0
			base.ui.execute_js("switchToMenu('actions')")
		self.mode = "NONE"

	def accept_selection(self):
		p0 = self.player.grid_position
		p1 = self.selected_pos
		if self.mode == "MOVE":
			distance = CombatTerrain.get_distance(p0, p1)
			if distance <= self.player.remaining_movement:
				start_pos = self.player.model.getPos()
				self.player.grid_position = self.selected_pos[:]
				self.player.remaining_movement -= distance
				if self.player.remaining_movement <= 0:
					self.player.action_set.remove("MOVE")
					base.ui.execute_js("disableItem('MOVE')")
				end_pos = self.player.model.getPos()
				self.move_interval = self.player.model.posInterval(distance * 0.125, end_pos, start_pos, blendType='easeInOut')
				self.move_interval.start()
				self.mode = "ANIMATION"
		elif self.mode == "ATTACK":
			if CombatTerrain.check_distance(self.player.range, p0, p1):
				for enemy in self.enemies:
					if enemy.grid_position == self.selected_pos:
						enemy.health -= self.player.damage
						self.player.action_set.remove("ATTACK")
						base.ui.execute_js("disableItem('ATTACK')")
						self.mode = "NONE"
		elif self.mode == "STANCE":
			self.player.active_stance = self.player.stances[self.ui_selection]
			self.player.action_set.remove("STANCE")
			base.ui.execute_js("disableItem('STANCE')")
			self.escape()
		else:
			if self.ui_selection == 0:
				self.enter_stance_mode()
			elif self.ui_selection == 1:
				self.enter_move_mode()
			elif self.ui_selection == 2:
				self.enter_attack_mode()
			elif self.ui_selection == 3:
				self.end_turn()

	def enter_stance_mode(self):
		if "STANCE" in self.player.action_set:
			self.mode = "STANCE"
			base.ui.execute_js("switchToMenu('stances')")

	def enter_move_mode(self):
		if "MOVE" in self.player.action_set:
			self.mode = "MOVE" if self.mode != "MOVE" else "NONE"

	def enter_attack_mode(self):
		if "ATTACK" in self.player.action_set:
			self.mode = "ATTACK" if self.mode != "ATTACK" else "NONE"

	def end_turn(self):
		self.player.action_set = []
		self.ui_selection = 0
		self.mode = "NONE"

	def sel_up(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[1] += 1
		else:
			self.ui_selection -= 1

	def sel_left(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[0] -= 1

	def sel_down(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[1] -= 1
		else:
			self.ui_selection += 1

	def sel_right(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[0] += 1

	def main_loop(self):
		# Reset anim mode
		if self.move_interval is not None and self.move_interval.isStopped():
			self.move_interval = None
			self.mode = "NONE"
		if self.mode == "ANIMATION":
			return

		# Bound selection
		self.selected_pos[0] = min(max(self.selected_pos[0], 0), MAP_SIZE-1)
		self.selected_pos[1] = min(max(self.selected_pos[1], 0), MAP_SIZE-1)

		# Track remaining enemies and and exit if none are left
		for dead_enemy in [e for e in self.enemies if e.health <= 0]:
			if dead_enemy in self.active_set:
				self.active_set.remove(dead_enemy)
		self.enemies = [e for e in self.enemies if e.health > 0]
		if not self.enemies or self.player.health <= 0:
			new_pool = StanceGenerator.n_from_pool(5, self.player.stances)
			for stance in new_pool:
				print(stance)
			base.change_state(EndCombatState)
			return

		# Get current participants
		participants = [self.player] + self.enemies
		if not self.active_set:
			while not self.active_set:
				for participant in participants:
					participant.atb += participant.speed
					if participant.atb >= 10:
						self.active_set.append(participant)

			self.active_set.sort(key=lambda x: x.atb)
			for participant in self.active_set:
				participant.action_set = ["ATTACK", "MOVE", "STANCE"]
				participant.remaining_movement = participant.movement
				for i in participant.action_set:
					base.ui.execute_js("enableItem('%s')" % i)

		current_player = self.active_set[0]
		if current_player != self.player and current_player.target:
			target = current_player.target.grid_position
			if "MOVE" in current_player.action_set:
				center = current_player.grid_position
				radius = current_player.movement
				closest = CombatTerrain.find_closest_in_range(center, radius, target)
				if closest:
					distance = CombatTerrain.get_distance(center, closest)
					start_pos = current_player.model.getPos()
					current_player.grid_position = closest
					end_pos = current_player.model.getPos()
					self.move_interval = current_player.model.posInterval(distance * 0.125, end_pos, start_pos, blendType='easeInOut')
					self.move_interval.start()
				current_player.action_set.remove("MOVE")
				self.mode = "ANIMATION"
			elif "ATTACK" in current_player.action_set:
				center = current_player.grid_position
				if CombatTerrain.check_distance(current_player.range, center, target):
					current_player.target.health -= current_player.damage
				current_player.action_set.remove("ATTACK")
			elif "STANCE" in current_player.action_set:
				current_player.active_stance = current_player.stances[0] if current_player.stances else None
				current_player.action_set.remove("STANCE")
			else:
				current_player.action_set = []

		if not current_player.action_set:
			current_player.atb -= 10
			self.active_set.remove(current_player)

		# Handle selection
		self.terrain.clear_selection()
		self.terrain.set_cursor_selection(*self.selected_pos[:2])
		if self.mode == "MOVE":
			self.terrain.display_move_range(self.player)
		if self.mode == "ATTACK":
			self.terrain.display_attack_range(self.player)
		if self.mode == "NONE":
			self.selected_pos = self.player.grid_position[:]
		self.terrain.update_selection()

		if self.mode == "STANCE":
			ui_max = len(self.player.stances) - 1
		else:
			ui_max = 3

		if self.ui_selection > ui_max:
			self.ui_selection = 0
		elif self.ui_selection < 0:
			self.ui_selection = ui_max

		if self.ui_last != self.ui_selection:
			base.ui.execute_js("setActiveSelection(%d)" % self.ui_selection)
			self.ui_last = self.ui_selection

class LobbyState(DirectObject.DirectObject):
	def __init__(self):
		self.accept("arrow_up", self.sel_up)
		self.accept("arrow_left", self.sel_up)
		self.accept("arrow_down", self.sel_down)
		self.accept("arrow_right", self.sel_down)
		self.accept("arrow_up-repeat", self.sel_up)
		self.accept("arrow_left-repeat", self.sel_up)
		self.accept("arrow_down-repeat", self.sel_down)
		self.accept("arrow_right-repeat", self.sel_down)
		self.accept("enter", self.accept_selection)
		self.accept("escape", self.escape)

		base.ui.load('lobby_ui.html')

		self.ui_last = self.ui_selection = 0
		self.ui_options = [
			"STUDENT_INFO",
			"COURSEWORK",
			"OPTIONS",
			"QUIT",
		]
		self.mode = None
		base.ui.execute_js("setActiveTab(%d)" % self.ui_selection, True)

	def destroy(self):
		self.ignoreAll()

	def accept_selection(self):
		if self.mode is None:
			self.mode = self.ui_options[self.ui_selection]
			self.ui_selection = 0

			if self.mode == "STUDENT_INFO":
				pass
			elif self.mode == "COURSEWORK":
				base.change_state(CombatState)
			elif self.mode == "OPTIONS":
				pass
			elif self.mode == "QUIT":
				sys.exit()

	def escape(self):
		if self.mode is not None:
			self.ui_selection = self.ui_options.index(self.mode)
			self.mode = None

	def sel_up(self):
		self.ui_selection -= 1

	def sel_down(self):
		self.ui_selection += 1

	def main_loop(self):

		ui_max = 3
		if self.ui_selection > ui_max:
			self.ui_selection = 0
		elif self.ui_selection < 0:
			self.ui_selection = ui_max

		if self.ui_last != self.ui_selection:
			if self.mode is None:
				base.ui.execute_js("setActiveTab(%d)" % self.ui_selection)
			self.ui_last = self.ui_selection

class EndCombatState(DirectObject.DirectObject):
	def __init__(self):
		self.accept("arrow_up", self.sel_up)
		self.accept("arrow_left", self.sel_up)
		self.accept("arrow_down", self.sel_down)
		self.accept("arrow_right", self.sel_down)
		self.accept("arrow_up-repeat", self.sel_up)
		self.accept("arrow_left-repeat", self.sel_up)
		self.accept("arrow_down-repeat", self.sel_down)
		self.accept("arrow_right-repeat", self.sel_down)
		self.accept("enter", self.accept_selection)
		self.accept("escape", self.escape)

		base.ui.load('end_combat_ui.html')
		self.ui_last = self.ui_selection = 0

	def destroy(self):
		self.ignoreAll()

	def accept_selection(self):
		base.change_state(LobbyState)

	def escape(self):
		pass

	def sel_up(self):
		self.ui_selection -= 1

	def sel_down(self):
		self.ui_selection += 1

	def main_loop(self):
		pass

class Game(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)

		self.accept("f1", sys.exit)
		self.win.setCloseRequestEvent("f1")

		self.ui = CEFPanda()

		self.state = LobbyState()

		self.taskMgr.add(self.main_loop, "MainLoop")

	def change_state(self, new_state):
		self.state.destroy()
		self.state = new_state()

	def main_loop(self, task):
		self.state.main_loop()
		return task.cont

app = Game()
app.run()<commit_msg>Creating a GameState class to clean up duplicate code.<commit_after>
import sys

import os
os.environ['PANDA_PRC_DIR'] = os.path.join(os.path.dirname(__file__), 'etc')

# This import should be kept near the top to avoid issues with CEF/Chromium hooking malloc
from cefexample import CEFPanda

from direct.showbase.ShowBase import ShowBase, DirectObject
from direct.interval.LerpInterval import LerpPosInterval

from panda3d.core import *

from combat.terrain import Terrain as CombatTerrain, MAP_SIZE
from combat.player import Player as CombatPlayer
from stance_generator import StanceGenerator

loadPrcFileData("", "textures-power-2 none")

class GameState(object, DirectObject.DirectObject):
	def __init__(self, ui=None):
		self.accept("arrow_up", self.sel_up)
		self.accept("arrow_left", self.sel_left)
		self.accept("arrow_down", self.sel_down)
		self.accept("arrow_right", self.sel_right)
		self.accept("arrow_up-repeat", self.sel_up)
		self.accept("arrow_left-repeat", self.sel_left)
		self.accept("arrow_down-repeat", self.sel_down)
		self.accept("arrow_right-repeat", self.sel_right)
		self.accept("enter", self.accept_selection)
		self.accept("escape", self.escape)

		if ui is not None:
			base.ui.load(ui+'.html')

		self.ui_last = self.ui_selection = 0

	def destroy(self):
		self.ignoreAll()

	def accept_selection(self):
		pass

	def escape(self):
		pass

	def sel_up(self):
		self.ui_selection -= 1

	def sel_down(self):
		self.ui_selection += 1

	def sel_left(self):
		self.sel_up()

	def sel_right(self):
		self.sel_down()

	def main_loop(self):
		pass

class CombatState(GameState):
	def __init__(self):
		super(CombatState, self).__init__('ui')
		self.accept("1", self.enter_move_mode)
		self.accept("2", self.enter_attack_mode)
		self.accept("3", self.end_turn)

		def stm():
			base.ui.execute_js("switchToMenu('stances')")
		self.accept("space", stm)

		self.terrain = CombatTerrain()
		self.player = CombatPlayer("Player")
		self.player.roll_initiative()

		self.enemies = []
		self.active_set = []

		base.disableMouse()
		base.camera.setPos(25, -25, 28)
		base.camera.setHpr(45, -45, 0)
		base.camLens.setFov(65)

		base.ui.execute_js("setActiveSelection(%d)" % self.ui_selection, True)

		self.selected_pos = [16, 16, 0]

		self.mode = "NONE"

		# Setup the combatants
		self.player = CombatPlayer("Player", level=3)
		for stance in self.player.stances:
			print(stance)
		stance_str = "[" + ",".join(["'%s'" % i.name for i in self.player.stances]) + "]"
		base.ui.execute_js("setStances(%s)" % stance_str, onload=True)
		self.player.roll_initiative()

		self.enemies = []
		for i in range(3):
			enemy = CombatPlayer.from_player_chassis("clay_golem")
			enemy.grid_position = CombatTerrain.get_random_tile()
			enemy.roll_initiative()
			enemy.target = self.player
			self.enemies.append(enemy)

		self.active_set = []
		self.move_interval = None

	def destroy(self):
		super(CombatState, self).destroy()
		for n in base.render.getChildren():
			n.removeNode()

	def escape(self):
		if self.mode == "STANCE":
			self.ui_selection = 0
			base.ui.execute_js("switchToMenu('actions')")
		self.mode = "NONE"

	def accept_selection(self):
		p0 = self.player.grid_position
		p1 = self.selected_pos
		if self.mode == "MOVE":
			distance = CombatTerrain.get_distance(p0, p1)
			if distance <= self.player.remaining_movement:
				start_pos = self.player.model.getPos()
				self.player.grid_position = self.selected_pos[:]
				self.player.remaining_movement -= distance
				if self.player.remaining_movement <= 0:
					self.player.action_set.remove("MOVE")
					base.ui.execute_js("disableItem('MOVE')")
				end_pos = self.player.model.getPos()
				self.move_interval = self.player.model.posInterval(distance * 0.125, end_pos, start_pos, blendType='easeInOut')
				self.move_interval.start()
				self.mode = "ANIMATION"
		elif self.mode == "ATTACK":
			if CombatTerrain.check_distance(self.player.range, p0, p1):
				for enemy in self.enemies:
					if enemy.grid_position == self.selected_pos:
						enemy.health -= self.player.damage
						self.player.action_set.remove("ATTACK")
						base.ui.execute_js("disableItem('ATTACK')")
						self.mode = "NONE"
		elif self.mode == "STANCE":
			self.player.active_stance = self.player.stances[self.ui_selection]
			self.player.action_set.remove("STANCE")
			base.ui.execute_js("disableItem('STANCE')")
			self.escape()
		else:
			if self.ui_selection == 0:
				self.enter_stance_mode()
			elif self.ui_selection == 1:
				self.enter_move_mode()
			elif self.ui_selection == 2:
				self.enter_attack_mode()
			elif self.ui_selection == 3:
				self.end_turn()

	def enter_stance_mode(self):
		if "STANCE" in self.player.action_set:
			self.mode = "STANCE"
			base.ui.execute_js("switchToMenu('stances')")

	def enter_move_mode(self):
		if "MOVE" in self.player.action_set:
			self.mode = "MOVE" if self.mode != "MOVE" else "NONE"

	def enter_attack_mode(self):
		if "ATTACK" in self.player.action_set:
			self.mode = "ATTACK" if self.mode != "ATTACK" else "NONE"

	def end_turn(self):
		self.player.action_set = []
		self.ui_selection = 0
		self.mode = "NONE"

	def sel_up(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[1] += 1
		else:
			self.ui_selection -= 1

	def sel_left(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[0] -= 1

	def sel_down(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[1] -= 1
		else:
			self.ui_selection += 1

	def sel_right(self):
		if self.mode in {"ATTACK", "MOVE"}:
			self.selected_pos[0] += 1

	def main_loop(self):
		# Reset anim mode
		if self.move_interval is not None and self.move_interval.isStopped():
			self.move_interval = None
			self.mode = "NONE"
		if self.mode == "ANIMATION":
			return

		# Bound selection
		self.selected_pos[0] = min(max(self.selected_pos[0], 0), MAP_SIZE-1)
		self.selected_pos[1] = min(max(self.selected_pos[1], 0), MAP_SIZE-1)

		# Track remaining enemies and and exit if none are left
		for dead_enemy in [e for e in self.enemies if e.health <= 0]:
			if dead_enemy in self.active_set:
				self.active_set.remove(dead_enemy)
		self.enemies = [e for e in self.enemies if e.health > 0]
		if not self.enemies or self.player.health <= 0:
			new_pool = StanceGenerator.n_from_pool(5, self.player.stances)
			for stance in new_pool:
				print(stance)
			base.change_state(EndCombatState)
			return

		# Get current participants
		participants = [self.player] + self.enemies
		if not self.active_set:
			while not self.active_set:
				for participant in participants:
					participant.atb += participant.speed
					if participant.atb >= 10:
						self.active_set.append(participant)

			self.active_set.sort(key=lambda x: x.atb)
			for participant in self.active_set:
				participant.action_set = ["ATTACK", "MOVE", "STANCE"]
				participant.remaining_movement = participant.movement
				for i in participant.action_set:
					base.ui.execute_js("enableItem('%s')" % i)

		current_player = self.active_set[0]
		if current_player != self.player and current_player.target:
			target = current_player.target.grid_position
			if "MOVE" in current_player.action_set:
				center = current_player.grid_position
				radius = current_player.movement
				closest = CombatTerrain.find_closest_in_range(center, radius, target)
				if closest:
					distance = CombatTerrain.get_distance(center, closest)
					start_pos = current_player.model.getPos()
					current_player.grid_position = closest
					end_pos = current_player.model.getPos()
					self.move_interval = current_player.model.posInterval(distance * 0.125, end_pos, start_pos, blendType='easeInOut')
					self.move_interval.start()
				current_player.action_set.remove("MOVE")
				self.mode = "ANIMATION"
			elif "ATTACK" in current_player.action_set:
				center = current_player.grid_position
				if CombatTerrain.check_distance(current_player.range, center, target):
					current_player.target.health -= current_player.damage
				current_player.action_set.remove("ATTACK")
			elif "STANCE" in current_player.action_set:
				current_player.active_stance = current_player.stances[0] if current_player.stances else None
				current_player.action_set.remove("STANCE")
			else:
				current_player.action_set = []

		if not current_player.action_set:
			current_player.atb -= 10
			self.active_set.remove(current_player)

		# Handle selection
		self.terrain.clear_selection()
		self.terrain.set_cursor_selection(*self.selected_pos[:2])
		if self.mode == "MOVE":
			self.terrain.display_move_range(self.player)
		if self.mode == "ATTACK":
			self.terrain.display_attack_range(self.player)
		if self.mode == "NONE":
			self.selected_pos = self.player.grid_position[:]
		self.terrain.update_selection()

		if self.mode == "STANCE":
			ui_max = len(self.player.stances) - 1
		else:
			ui_max = 3

		if self.ui_selection > ui_max:
			self.ui_selection = 0
		elif self.ui_selection < 0:
			self.ui_selection = ui_max

		if self.ui_last != self.ui_selection:
			base.ui.execute_js("setActiveSelection(%d)" % self.ui_selection)
			self.ui_last = self.ui_selection

class LobbyState(GameState):
	def __init__(self):
		super(LobbyState, self).__init__('lobby_ui')

		self.ui_options = [
			"STUDENT_INFO",
			"COURSEWORK",
			"OPTIONS",
			"QUIT",
		]
		self.mode = None
		base.ui.execute_js("setActiveTab(%d)" % self.ui_selection, True)

	def accept_selection(self):
		if self.mode is None:
			self.mode = self.ui_options[self.ui_selection]
			self.ui_selection = 0

			if self.mode == "STUDENT_INFO":
				pass
			elif self.mode == "COURSEWORK":
				base.change_state(CombatState)
			elif self.mode == "OPTIONS":
				pass
			elif self.mode == "QUIT":
				sys.exit()

	def escape(self):
		if self.mode is not None:
			self.ui_selection = self.ui_options.index(self.mode)
			self.mode = None

	def main_loop(self):

		ui_max = 3
		if self.ui_selection > ui_max:
			self.ui_selection = 0
		elif self.ui_selection < 0:
			self.ui_selection = ui_max

		if self.ui_last != self.ui_selection:
			if self.mode is None:
				base.ui.execute_js("setActiveTab(%d)" % self.ui_selection)
			self.ui_last = self.ui_selection

class EndCombatState(GameState):
	def __init__(self):
		super(EndCombatState, self).__init__('end_combat_ui')

	def accept_selection(self):
		base.change_state(LobbyState)

class Game(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)

		self.accept("f1", sys.exit)
		self.win.setCloseRequestEvent("f1")

		self.ui = CEFPanda()

		self.state = LobbyState()

		self.taskMgr.add(self.main_loop, "MainLoop")

	def change_state(self, new_state):
		self.state.destroy()
		self.state = new_state()

	def main_loop(self, task):
		self.state.main_loop()
		return task.cont

app = Game()
app.run()<|endoftext|>


<commit_before>import os
import glob
import logging
import shutil
import sys

def get_binary(name):
    binpath = name
    if hasattr(sys, "frozen"):
        binpath = os.path.abspath(os.path.join(sys._MEIPASS, '..', 'Resources', name))
    elif os.path.exists(name):
        binpath = "./%s" % (name)

    logging.info("binpath %s", binpath)
    return binpath

def get_resource(path):
    rpath = path
    if hasattr(sys, "frozen"):
        rpath = os.path.abspath(os.path.join(sys._MEIPASS, '..', 'Resources', path))
    logging.info("resourcepath %s", rpath)
    return rpath

def get_datadir(path):
    datadir = path
    if hasattr(sys, "frozen"):# and sys.frozen == "macosx_app":
        datadir = os.path.join(os.environ['HOME'], '.gentle', path)
    logging.info("datadir %s", datadir)
    return datadir
<commit_msg>fallback on .gentle for get_resourcepath<commit_after>import os
import glob
import logging
import shutil
import sys

def get_binary(name):
    binpath = name
    if hasattr(sys, "frozen"):
        binpath = os.path.abspath(os.path.join(sys._MEIPASS, '..', 'Resources', name))
    elif os.path.exists(name):
        binpath = "./%s" % (name)

    logging.debug("binpath %s", binpath)
    return binpath

def get_resource(path):
    rpath = path
    if hasattr(sys, "frozen"):
        rpath = os.path.abspath(os.path.join(sys._MEIPASS, '..', 'Resources', path))
        if not os.path.exists(rpath):
            # DMG may be read-only; fall-back to datadir (ie. so language models can be added)
            rpath = get_datadir(path)
    logging.debug("resourcepath %s", rpath)
    return rpath

def get_datadir(path):
    datadir = path
    if hasattr(sys, "frozen"):# and sys.frozen == "macosx_app":
        datadir = os.path.join(os.environ['HOME'], '.gentle', path)
    logging.debug("datadir %s", datadir)
    return datadir
<|endoftext|>


<commit_before># Copyright 2014 OpenStack Foundation
#
# 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.

import urwid

GLOBAL_HELP = """\
Global Keys
===========
<F1> or <?> Help
<ESC>       Back to previous screen
<CTRL-Q>    Quit Gertty
"""

class TextButton(urwid.Button):
    def selectable(self):
        return True

    def __init__(self, text, on_press=None, user_data=None):
        super(TextButton, self).__init__('', on_press=on_press, user_data=user_data)
        self.text = urwid.Text(text)
        self._w = urwid.AttrMap(self.text, None, focus_map='focused')

class FixedButton(urwid.Button):
    def sizing(self):
        return frozenset([urwid.FIXED])

    def pack(self, size, focus=False):
        return (len(self.get_label())+4, 1)

class TableColumn(urwid.Pile):
    def pack(self, size, focus=False):
        mx = max([len(i[0].text) for i in self.contents])
        return (mx+2, len(self.contents))

class Table(urwid.WidgetWrap):
    def __init__(self, headers=[], columns=None):
        if columns is None:
            cols = [('pack', TableColumn([('pack', w)])) for w in headers]
        else:
            cols = [('pack', TableColumn([])) for x in range(columns)]
        super(Table, self).__init__(
            urwid.Columns(cols))

    def addRow(self, cells=[]):
        for i, widget in enumerate(cells):
            self._w.contents[i][0].contents.append((widget, ('pack', None)))

class ButtonDialog(urwid.WidgetWrap):
    def __init__(self, title, message, entry_prompt=None, entry_text='', buttons=[]):
        button_widgets = []
        for button in buttons:
            button_widgets.append(('pack', button))
        button_columns = urwid.Columns(button_widgets, dividechars=2)
        rows = []
        rows.append(urwid.Text(message))
        if entry_prompt:
            self.entry = urwid.Edit(entry_prompt, edit_text=entry_text)
            rows.append(self.entry)
        else:
            self.entry = None
        rows.append(urwid.Divider())
        rows.append(button_columns)
        pile = urwid.Pile(rows)
        fill = urwid.Filler(pile, valign='top')
        super(ButtonDialog, self).__init__(urwid.LineBox(fill, title))

class MessageDialog(ButtonDialog):
    signals = ['close']
    def __init__(self, title, message):
        ok_button = FixedButton('OK')
        urwid.connect_signal(ok_button, 'click',
                             lambda button:self._emit('close'))
        super(MessageDialog, self).__init__(title, message, buttons=[ok_button])

class YesNoDialog(ButtonDialog):
    signals = ['yes', 'no']
    def __init__(self, title, message):
        yes_button = FixedButton('Yes')
        no_button = FixedButton('No')
        urwid.connect_signal(yes_button, 'click',
                             lambda button:self._emit('yes'))
        urwid.connect_signal(no_button, 'click',
                             lambda button:self._emit('no'))
        super(YesNoDialog, self).__init__(title, message, buttons=[yes_button,
                                                                   no_button])
    def keypress(self, size, key):
        r = super(YesNoDialog, self).keypress(size, key)
        if r in ('Y', 'y'):
            self._emit('yes')
            return None
        if r in ('N', 'n'):
            self._emit('no')
            return None
        return r

class HyperText(urwid.Text):
    _selectable = True

    def __init__(self, markup, align=urwid.LEFT, wrap=urwid.SPACE, layout=None):
        self._mouse_press_item = None
        self.selectable_items = []
        self.focused_index = None
        super(HyperText, self).__init__(markup, align, wrap, layout)

    def focusFirstItem(self):
        if len(self.selectable_items) == 0:
            return False
        self.focusItem(0)
        return True

    def focusLastItem(self):
        if len(self.selectable_items) == 0:
            return False
        self.focusItem(len(self.selectable_items)-1)
        return True

    def focusPreviousItem(self):
        if len(self.selectable_items) == 0:
            return False
        item = max(0, self.focused_index-1)
        if item != self.focused_index:
            self.focusItem(item)
            return True
        return False

    def focusNextItem(self):
        if len(self.selectable_items) == 0:
            return False
        item = min(len(self.selectable_items)-1, self.focused_index+1)
        if item != self.focused_index:
            self.focusItem(item)
            return True
        return False

    def focusItem(self, item):
        self.focused_index = item
        self.set_text(self._markup)
        self._invalidate()

    def select(self):
        if self.focused_index is not None:
            self.selectable_items[self.focused_index][0].select()

    def keypress(self, size, key):
        if self._command_map[key] == urwid.CURSOR_UP:
            if self.focusPreviousItem():
                return False
            return key
        elif self._command_map[key] == urwid.CURSOR_DOWN:
            if self.focusNextItem():
                return False
            return key
        elif key == 'enter':
            self.select()
            return False
        return key

    def getPosAtCoords(self, maxcol, col, row):
        trans = self.get_line_translation(maxcol)
        colpos = 0
        line = trans[row]
        for t in line:
            if len(t) == 2:
                width, pos = t
                if colpos <= col < colpos + width:
                    return pos
            else:
                width, start, end = t
                if colpos <= col < colpos + width:
                    return start + (col - colpos)
            colpos += width
        return None

    def getItemAtCoords(self, maxcol, col, row):
        pos = self.getPosAtCoords(maxcol, col, row)
        index = 0
        for item, start, end in self.selectable_items:
            if start <= pos <= end:
                return index
            index += 1
        return None

    def mouse_event(self, size, event, button, col, row, focus):
        if ((button not in [0, 1]) or
            (event not in ['mouse press', 'mouse release'])):
            return False
        item = self.getItemAtCoords(size[0], col, row)
        if item is None:
            if self.focused_index is None:
                self.focusItemLeft()
            return False
        if event == 'mouse press':
            self.focusItem(item)
            self._mouse_press_item = item
        if event == 'mouse release':
            if self._mouse_press_item == item:
                self.select()
            self._mouse_press_item = None
        return True

    def processLinks(self, markup, data=None):
        if data is None:
            data = dict(pos=0)
        if isinstance(markup, list):
            return [self.processLinks(i, data) for i in markup]
        if isinstance(markup, tuple):
            return (markup[0], self.processLinks(markup[1], data))
        if isinstance(markup, Link):
            self.selectable_items.append((markup, data['pos'], data['pos']+len(markup.text)))
            data['pos'] += len(markup.text)
            focused = len(self.selectable_items)-1 == self.focused_index
            link_attr = markup.getAttr(focused)
            if link_attr:
                return (link_attr, markup.text)
            else:
                return markup.text
        data['pos'] += len(markup)
        return markup

    def set_text(self, markup):
        self._markup = markup
        self.selectable_items = []
        super(HyperText, self).set_text(self.processLinks(markup))

    def move_cursor_to_coords(self, size, col, row):
        if self.focused_index is None:
            if row:
                self.focusLastItem()
            else:
                self.focusFirstItem()
        return True

    def render(self, size, focus=False):
        if (not focus) and (self.focused_index is not None):
            self.focusItem(None)
        return super(HyperText, self).render(size, focus)

class Link(urwid.Widget):
    signals = ['selected']

    def __init__(self, text, attr=None, focused_attr=None):
        self.text = text
        self.attr = attr
        self.focused_attr = focused_attr

    def select(self):
        self._emit('selected')

    def getAttr(self, focus):
        if focus:
            return self.focused_attr
        return self.attr
<commit_msg>Correct a problem with tables at very small widths<commit_after># Copyright 2014 OpenStack Foundation
#
# 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.

import urwid

GLOBAL_HELP = """\
Global Keys
===========
<F1> or <?> Help
<ESC>       Back to previous screen
<CTRL-Q>    Quit Gertty
"""

class TextButton(urwid.Button):
    def selectable(self):
        return True

    def __init__(self, text, on_press=None, user_data=None):
        super(TextButton, self).__init__('', on_press=on_press, user_data=user_data)
        self.text = urwid.Text(text)
        self._w = urwid.AttrMap(self.text, None, focus_map='focused')

class FixedButton(urwid.Button):
    def sizing(self):
        return frozenset([urwid.FIXED])

    def pack(self, size, focus=False):
        return (len(self.get_label())+4, 1)

class TableColumn(urwid.Pile):
    def pack(self, size, focus=False):
        maxcol = size[0]
        mx = max([len(i[0].text) for i in self.contents])
        return (min(mx+2, maxcol), len(self.contents))

class Table(urwid.WidgetWrap):
    def __init__(self, headers=[], columns=None):
        if columns is None:
            cols = [('pack', TableColumn([('pack', w)])) for w in headers]
        else:
            cols = [('pack', TableColumn([])) for x in range(columns)]
        super(Table, self).__init__(
            urwid.Columns(cols))

    def addRow(self, cells=[]):
        for i, widget in enumerate(cells):
            self._w.contents[i][0].contents.append((widget, ('pack', None)))

class ButtonDialog(urwid.WidgetWrap):
    def __init__(self, title, message, entry_prompt=None, entry_text='', buttons=[]):
        button_widgets = []
        for button in buttons:
            button_widgets.append(('pack', button))
        button_columns = urwid.Columns(button_widgets, dividechars=2)
        rows = []
        rows.append(urwid.Text(message))
        if entry_prompt:
            self.entry = urwid.Edit(entry_prompt, edit_text=entry_text)
            rows.append(self.entry)
        else:
            self.entry = None
        rows.append(urwid.Divider())
        rows.append(button_columns)
        pile = urwid.Pile(rows)
        fill = urwid.Filler(pile, valign='top')
        super(ButtonDialog, self).__init__(urwid.LineBox(fill, title))

class MessageDialog(ButtonDialog):
    signals = ['close']
    def __init__(self, title, message):
        ok_button = FixedButton('OK')
        urwid.connect_signal(ok_button, 'click',
                             lambda button:self._emit('close'))
        super(MessageDialog, self).__init__(title, message, buttons=[ok_button])

class YesNoDialog(ButtonDialog):
    signals = ['yes', 'no']
    def __init__(self, title, message):
        yes_button = FixedButton('Yes')
        no_button = FixedButton('No')
        urwid.connect_signal(yes_button, 'click',
                             lambda button:self._emit('yes'))
        urwid.connect_signal(no_button, 'click',
                             lambda button:self._emit('no'))
        super(YesNoDialog, self).__init__(title, message, buttons=[yes_button,
                                                                   no_button])
    def keypress(self, size, key):
        r = super(YesNoDialog, self).keypress(size, key)
        if r in ('Y', 'y'):
            self._emit('yes')
            return None
        if r in ('N', 'n'):
            self._emit('no')
            return None
        return r

class HyperText(urwid.Text):
    _selectable = True

    def __init__(self, markup, align=urwid.LEFT, wrap=urwid.SPACE, layout=None):
        self._mouse_press_item = None
        self.selectable_items = []
        self.focused_index = None
        super(HyperText, self).__init__(markup, align, wrap, layout)

    def focusFirstItem(self):
        if len(self.selectable_items) == 0:
            return False
        self.focusItem(0)
        return True

    def focusLastItem(self):
        if len(self.selectable_items) == 0:
            return False
        self.focusItem(len(self.selectable_items)-1)
        return True

    def focusPreviousItem(self):
        if len(self.selectable_items) == 0:
            return False
        item = max(0, self.focused_index-1)
        if item != self.focused_index:
            self.focusItem(item)
            return True
        return False

    def focusNextItem(self):
        if len(self.selectable_items) == 0:
            return False
        item = min(len(self.selectable_items)-1, self.focused_index+1)
        if item != self.focused_index:
            self.focusItem(item)
            return True
        return False

    def focusItem(self, item):
        self.focused_index = item
        self.set_text(self._markup)
        self._invalidate()

    def select(self):
        if self.focused_index is not None:
            self.selectable_items[self.focused_index][0].select()

    def keypress(self, size, key):
        if self._command_map[key] == urwid.CURSOR_UP:
            if self.focusPreviousItem():
                return False
            return key
        elif self._command_map[key] == urwid.CURSOR_DOWN:
            if self.focusNextItem():
                return False
            return key
        elif key == 'enter':
            self.select()
            return False
        return key

    def getPosAtCoords(self, maxcol, col, row):
        trans = self.get_line_translation(maxcol)
        colpos = 0
        line = trans[row]
        for t in line:
            if len(t) == 2:
                width, pos = t
                if colpos <= col < colpos + width:
                    return pos
            else:
                width, start, end = t
                if colpos <= col < colpos + width:
                    return start + (col - colpos)
            colpos += width
        return None

    def getItemAtCoords(self, maxcol, col, row):
        pos = self.getPosAtCoords(maxcol, col, row)
        index = 0
        for item, start, end in self.selectable_items:
            if start <= pos <= end:
                return index
            index += 1
        return None

    def mouse_event(self, size, event, button, col, row, focus):
        if ((button not in [0, 1]) or
            (event not in ['mouse press', 'mouse release'])):
            return False
        item = self.getItemAtCoords(size[0], col, row)
        if item is None:
            if self.focused_index is None:
                self.focusItemLeft()
            return False
        if event == 'mouse press':
            self.focusItem(item)
            self._mouse_press_item = item
        if event == 'mouse release':
            if self._mouse_press_item == item:
                self.select()
            self._mouse_press_item = None
        return True

    def processLinks(self, markup, data=None):
        if data is None:
            data = dict(pos=0)
        if isinstance(markup, list):
            return [self.processLinks(i, data) for i in markup]
        if isinstance(markup, tuple):
            return (markup[0], self.processLinks(markup[1], data))
        if isinstance(markup, Link):
            self.selectable_items.append((markup, data['pos'], data['pos']+len(markup.text)))
            data['pos'] += len(markup.text)
            focused = len(self.selectable_items)-1 == self.focused_index
            link_attr = markup.getAttr(focused)
            if link_attr:
                return (link_attr, markup.text)
            else:
                return markup.text
        data['pos'] += len(markup)
        return markup

    def set_text(self, markup):
        self._markup = markup
        self.selectable_items = []
        super(HyperText, self).set_text(self.processLinks(markup))

    def move_cursor_to_coords(self, size, col, row):
        if self.focused_index is None:
            if row:
                self.focusLastItem()
            else:
                self.focusFirstItem()
        return True

    def render(self, size, focus=False):
        if (not focus) and (self.focused_index is not None):
            self.focusItem(None)
        return super(HyperText, self).render(size, focus)

class Link(urwid.Widget):
    signals = ['selected']

    def __init__(self, text, attr=None, focused_attr=None):
        self.text = text
        self.attr = attr
        self.focused_attr = focused_attr

    def select(self):
        self._emit('selected')

    def getAttr(self, focus):
        if focus:
            return self.focused_attr
        return self.attr
<|endoftext|>


<commit_before>import argparse
import signal
import sys

from . import __version__
from . import approve
from . import assignme
from . import block
from . import clear_comments
from . import contributions
from . import create
from . import download_release
from . import get_blocks
from . import greenify
from . import langs
from . import ls_notifications
from . import me
from . import notifications
from . import pr
from . import protect
from . import unblock
from . import unwatch
from . import watch

def _signal_handle(sig, frame):
    sys.exit(0)

def _build_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-v", "--version", action="version", version="%(prog)s " + __version__
    )

    subparsers = parser.add_subparsers(dest="subcommand")
    subparsers.required = True

    approve_parser = subparsers.add_parser("approve", help="Approve a PR")
    approve_parser.add_argument("pr", help="the PR to approve")

    assignme_parser = subparsers.add_parser(
        "assignme", help="Assign yourself to a PR"
    )
    assignme_parser.add_argument("pr", help="The PR to assign yourself to")

    block_parser = subparsers.add_parser("block", help="block a given user")
    block_parser.add_argument("user", help="the user to block")

    unblock_parser = subparsers.add_parser(
        "unblock", help="unblock a given user"
    )
    unblock_parser.add_argument("user", help="the user to unblock")

    clear_comments_parser = subparsers.add_parser(
        "clear-comments", help="Protect/Unprotect a branch"
    )
    clear_comments_parser.add_argument("repo", help="the user/repo to edit")
    clear_comments_parser.add_argument("pr", help="the PR number to clear")

    create_parser = subparsers.add_parser(
        "create", help="Create a new GitHub repo"
    )
    create_parser.add_argument("name", help="the name of the repo")
    create_parser.add_argument(
        "-d", "--description", help="the description of the repo"
    )
    create_parser.add_argument(
        "-u", "--url", help="the homepage for the repo", dest="homepage"
    )
    create_parser.add_argument(
        "-p",
        "--private",
        action="store_true",
        help="make the repo private",
        default=False,
    )
    create_parser.add_argument(
        "-w",
        "--wiki",
        action="store_true",
        help="enable wikis",
        default=False,
        dest="has_wiki",
    )
    create_parser.add_argument(
        "--no-issues",
        action="store_false",
        help="disable issues",
        default=True,
        dest="has_issues",
    )
    create_parser.add_argument(
        "--no-downloads",
        action="store_false",
        help="disable downloads",
        default=True,
        dest="has_downloads",
    )

    download_release_parser = subparsers.add_parser(
        "download-release", help="Download the most recent release of a repo"
    )
    download_release_parser.add_argument("repo", help="the user/repo")
    download_release_parser.add_argument(
        "-f",
        "--filename",
        action="store_true",
        help="only print the filename",
        default=False,
    )

    langs_parser = subparsers.add_parser(
        "langs", help="Get the language breakdown for a repo"
    )
    langs_parser.add_argument("repo", help="The user/repo")

    protect_parser = subparsers.add_parser(
        "protect", help="Protect/Unprotect a branch"
    )
    protect_parser.add_argument(
        "--disable",
        help="disable protection",
        action="store_true",
        default=False,
    )
    protect_parser.add_argument("repo", help="the user/repo to edit")
    protect_parser.add_argument("branch", help="The name of the branch")
    protect_parser.add_argument(
        "statuses", nargs="*", help="The required status checks"
    )

    pr_parser = subparsers.add_parser("pr", help="Create a PR")
    pr_parser.add_argument(
        "-d",
        "--draft",
        action="store_true",
        help="Create the PR as a draft",
        default=False,
    )
    pr_parser.add_argument(
        "branch",
        help="The branch to base the PR on",
        nargs="?",
        default="master",
    )

    unwatch_parser = subparsers.add_parser(
        "unwatch", help="Unwatch GitHub repos"
    )
    unwatch_parser.add_argument(
        "-u",
        "--users",
        help="comma separated valid users. "
        "Repos from these users are never unwatched",
        default="",
    )
    unwatch_parser.add_argument(
        "-i",
        "--ignored",
        help="command separated ignored repo names. "
        "Repos from this list are automatically unwatched",
        default="",
    )

    watch_parser = subparsers.add_parser("watch", help="Watch GitHub repos")
    watch_parser.add_argument("repo", help="the user/repo to watch")

    subparsers.add_parser(
        "contributions", help="Get your contribution count for today"
    )
    subparsers.add_parser(
        "get-blocks", help="Get list of users you've blocked"
    )
    subparsers.add_parser(
        "ls-notifications", help="Show your unread notifications"
    )
    subparsers.add_parser("me", help="Open your profile")
    subparsers.add_parser("notifications", help="Open unread notifications")

    greenify_parser = subparsers.add_parser(
        "greenify", help="Make a commit green by editing the statuses"
    )
    greenify_parser.add_argument("repo", help="the user/repo to edit")
    greenify_parser.add_argument("sha", help="the sha with the statuses")
    return parser

def main():
    args = _build_parser().parse_args()
    commands = {
        "approve": approve.main,
        "assignme": assignme.main,
        "block": block.main,
        "unblock": unblock.main,
        "clear-comments": clear_comments.main,
        "contributions": contributions.main,
        "create": create.main,
        "download-release": download_release.main,
        "get-blocks": get_blocks.main,
        "greenify": greenify.main,
        "langs": langs.main,
        "ls-notifications": ls_notifications.main,
        "me": me.main,
        "notifications": notifications.main,
        "pr": pr.main,
        "protect": protect.main,
        "unwatch": unwatch.main,
        "watch": watch.main,
    }

    signal.signal(signal.SIGINT, _signal_handle)
    commands[args.subcommand](args)

if __name__ == "__main__":
    main()
<commit_msg>Sort commands<commit_after>import argparse
import signal
import sys

from . import __version__
from . import approve
from . import assignme
from . import block
from . import clear_comments
from . import contributions
from . import create
from . import download_release
from . import get_blocks
from . import greenify
from . import langs
from . import ls_notifications
from . import me
from . import notifications
from . import pr
from . import protect
from . import unblock
from . import unwatch
from . import watch

def _signal_handle(sig, frame):
    sys.exit(0)

def _build_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-v", "--version", action="version", version="%(prog)s " + __version__
    )

    subparsers = parser.add_subparsers(dest="subcommand")
    subparsers.required = True

    approve_parser = subparsers.add_parser("approve", help="Approve a PR")
    approve_parser.add_argument("pr", help="the PR to approve")

    assignme_parser = subparsers.add_parser(
        "assignme", help="Assign yourself to a PR"
    )
    assignme_parser.add_argument("pr", help="The PR to assign yourself to")

    block_parser = subparsers.add_parser("block", help="block a given user")
    block_parser.add_argument("user", help="the user to block")

    unblock_parser = subparsers.add_parser(
        "unblock", help="unblock a given user"
    )
    unblock_parser.add_argument("user", help="the user to unblock")

    clear_comments_parser = subparsers.add_parser(
        "clear-comments", help="Protect/Unprotect a branch"
    )
    clear_comments_parser.add_argument("repo", help="the user/repo to edit")
    clear_comments_parser.add_argument("pr", help="the PR number to clear")

    create_parser = subparsers.add_parser(
        "create", help="Create a new GitHub repo"
    )
    create_parser.add_argument("name", help="the name of the repo")
    create_parser.add_argument(
        "-d", "--description", help="the description of the repo"
    )
    create_parser.add_argument(
        "-u", "--url", help="the homepage for the repo", dest="homepage"
    )
    create_parser.add_argument(
        "-p",
        "--private",
        action="store_true",
        help="make the repo private",
        default=False,
    )
    create_parser.add_argument(
        "-w",
        "--wiki",
        action="store_true",
        help="enable wikis",
        default=False,
        dest="has_wiki",
    )
    create_parser.add_argument(
        "--no-issues",
        action="store_false",
        help="disable issues",
        default=True,
        dest="has_issues",
    )
    create_parser.add_argument(
        "--no-downloads",
        action="store_false",
        help="disable downloads",
        default=True,
        dest="has_downloads",
    )

    download_release_parser = subparsers.add_parser(
        "download-release", help="Download the most recent release of a repo"
    )
    download_release_parser.add_argument("repo", help="the user/repo")
    download_release_parser.add_argument(
        "-f",
        "--filename",
        action="store_true",
        help="only print the filename",
        default=False,
    )

    langs_parser = subparsers.add_parser(
        "langs", help="Get the language breakdown for a repo"
    )
    langs_parser.add_argument("repo", help="The user/repo")

    protect_parser = subparsers.add_parser(
        "protect", help="Protect/Unprotect a branch"
    )
    protect_parser.add_argument(
        "--disable",
        help="disable protection",
        action="store_true",
        default=False,
    )
    protect_parser.add_argument("repo", help="the user/repo to edit")
    protect_parser.add_argument("branch", help="The name of the branch")
    protect_parser.add_argument(
        "statuses", nargs="*", help="The required status checks"
    )

    pr_parser = subparsers.add_parser("pr", help="Create a PR")
    pr_parser.add_argument(
        "-d",
        "--draft",
        action="store_true",
        help="Create the PR as a draft",
        default=False,
    )
    pr_parser.add_argument(
        "branch",
        help="The branch to base the PR on",
        nargs="?",
        default="master",
    )

    unwatch_parser = subparsers.add_parser(
        "unwatch", help="Unwatch GitHub repos"
    )
    unwatch_parser.add_argument(
        "-u",
        "--users",
        help="comma separated valid users. "
        "Repos from these users are never unwatched",
        default="",
    )
    unwatch_parser.add_argument(
        "-i",
        "--ignored",
        help="command separated ignored repo names. "
        "Repos from this list are automatically unwatched",
        default="",
    )

    watch_parser = subparsers.add_parser("watch", help="Watch GitHub repos")
    watch_parser.add_argument("repo", help="the user/repo to watch")

    subparsers.add_parser(
        "contributions", help="Get your contribution count for today"
    )
    subparsers.add_parser(
        "get-blocks", help="Get list of users you've blocked"
    )
    subparsers.add_parser(
        "ls-notifications", help="Show your unread notifications"
    )
    subparsers.add_parser("me", help="Open your profile")
    subparsers.add_parser("notifications", help="Open unread notifications")

    greenify_parser = subparsers.add_parser(
        "greenify", help="Make a commit green by editing the statuses"
    )
    greenify_parser.add_argument("repo", help="the user/repo to edit")
    greenify_parser.add_argument("sha", help="the sha with the statuses")
    return parser

def main():
    args = _build_parser().parse_args()
    commands = {
        "approve": approve.main,
        "assignme": assignme.main,
        "block": block.main,
        "clear-comments": clear_comments.main,
        "contributions": contributions.main,
        "create": create.main,
        "download-release": download_release.main,
        "get-blocks": get_blocks.main,
        "greenify": greenify.main,
        "langs": langs.main,
        "ls-notifications": ls_notifications.main,
        "me": me.main,
        "notifications": notifications.main,
        "pr": pr.main,
        "protect": protect.main,
        "unblock": unblock.main,
        "unwatch": unwatch.main,
        "watch": watch.main,
    }

    signal.signal(signal.SIGINT, _signal_handle)
    commands[args.subcommand](args)

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


<commit_before>from flask_admin import Admin, AdminIndexView, expose
from flask_admin.contrib.sqla import ModelView
from flask_security import current_user, roles_required

from .models import db, User, Role, Group, Challenge, Prompt, Entry, FFARating, Rating

class IndexView(AdminIndexView):
    @expose('/')
    @roles_required('ADMIN')
    def index(self):
        return self.render('admin/index.html')

class CommonModelView(ModelView):
    form_excluded_columns = ('date_created',
                             'date_modified')
    column_display_pk = True

    def is_accessible(self):
        return current_user.has_role('ADMIN')

class UserModelView(CommonModelView):
    form_excluded_columns = CommonModelView.form_excluded_columns + ('password',
                             'reset_password_token',
                             'confirmed_at')

    column_searchable_list = ['email', 'username']
    column_exclude_list = ['password', 'reset_password_token']

    def is_accessible(self):
        return current_user.has_role('SUPER_ADMIN')

class RoleModelView(CommonModelView):
    def is_accessible(self):
        return current_user.has_role('SUPER_ADMIN')

views = [
    dict(view=User, cls=UserModelView),
    dict(view=Role, cls=RoleModelView),
    dict(view=Group, cls=CommonModelView),
    dict(view=Challenge, cls=CommonModelView),
    dict(view=Prompt, cls=CommonModelView),
    dict(view=Entry, cls=CommonModelView),
    dict(view=FFARating, cls=CommonModelView),
    dict(view=Rating, cls=CommonModelView),
]

admin = Admin(name="Admin", index_view=IndexView(), template_mode='bootstrap3')

for view in views:
    admin.add_view(view['cls'](view['view'], db.session))
<commit_msg>show ignored not working, still.<commit_after>from flask_admin import Admin, AdminIndexView, expose
from flask_admin.contrib.sqla import ModelView
from flask_security import current_user, roles_required

from .models import db, User, Role, Group, Challenge, Prompt, Entry, FFARating, Rating

class IndexView(AdminIndexView):
    @expose('/')
    @roles_required('ADMIN')
    def index(self):
        return self.render('admin/index.html')

class CommonModelView(ModelView):
    ignore_hidden = False
    column_display_pk = True

    form_excluded_columns = ('date_created',
                             'date_modified')

    def is_accessible(self):
        return current_user.has_role('ADMIN')

class UserModelView(CommonModelView):
    form_excluded_columns = CommonModelView.form_excluded_columns + ('password',
                             'reset_password_token',
                             'confirmed_at')

    column_searchable_list = ['email', 'username']
    column_exclude_list = ['password', 'reset_password_token']

    def is_accessible(self):
        return current_user.has_role('SUPER_ADMIN')

class RoleModelView(CommonModelView):
    def is_accessible(self):
        return current_user.has_role('SUPER_ADMIN')

views = [
    dict(view=User, cls=UserModelView),
    dict(view=Role, cls=RoleModelView),
    dict(view=Group, cls=CommonModelView),
    dict(view=Challenge, cls=CommonModelView),
    dict(view=Prompt, cls=CommonModelView),
    dict(view=Entry, cls=CommonModelView),
    dict(view=FFARating, cls=CommonModelView),
    dict(view=Rating, cls=CommonModelView),
]

admin = Admin(name="Admin", index_view=IndexView(), template_mode='bootstrap3')

for view in views:
    admin.add_view(view['cls'](view['view'], db.session))
<|endoftext|>