# -*- coding: utf-8 -*-
"""
Created on Mon Jul 27 08:26:42 2020

@author: David
"""

import itertools
from enum import IntEnum, Enum
from .dataframe_filtering.filtering import (
        filter_dataframe
)
import os
from ..utils.settings import load_object, load_object_with_params
import json
from collections import defaultdict, UserDict
import numpy as np
import pandas as pd
import logging
from ..utils.initialization import create_directory
import pathlib
from .support_classes import DescriptiveStats, ResultDict, Order
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

def get_loader(settings):
    info = settings["STATISTICS_DATA_LOADER"]
    return load_object_with_params(info)

class StatisticsManager:
    def __init__(self, settings):
        self.pvalue = settings["BASE_PVALUE"]
        self.data_columns = settings["STATISTICS_DATA_COLUMNS"]
        self.descriptive_columns = settings.get(
                "STATISTICS_DESCRIPTIVE_COLUMNS", [])
        self.normality_test = load_object(settings["NORMALITY_TEST"])
        self.difference_test = load_object(settings["DIFFERENCE_TEST"])
        self.posthoc_test = load_object(settings["POSTHOC_TEST"])
        self.posthoc_normal_test = load_object(settings["POSTHOC_NORMAL_TEST"])
        self.difference_function = load_object(settings["DIFFERENCE_FUNCTION"])
        self.loader = get_loader(settings)
        self.redundant = settings.get("REDUNDANT_INFORMATION", [])
        self.redundancy_removal_selector = load_object(
                settings["REDUNDANT_INFORMATION_REMOVAL_FUNCTION"])
        self.file = settings["STATISTICS_INPUT_FILE"]
        self.output_file = settings["STATISTICS_OUTPUT_FILE"]
        self.output_path = settings["STATISTICS_OUTPUT_PATH"]
        self.evaluation_order = settings["COLUMN_EVALUATION_ORDER"]
        self.elimination = settings["STATISTICS_BY_ELIMINATION"]
        self.register_intermediate = settings["REGISTER_INTERMEDIATE_RESULTS"]

    def compute_normality_single(self, *values):
        return map(lambda x: self.normality_test(x) >= self.pvalue, values)

    def compute_normality_all(self, *values):
        return all(self.compute_normality_single(*values))

    def remove_redundant_info(self, df, by=None, metrics=None):
        if not by:
            by = set(df.columns) - self.data_columns
        if not metrics:
            metrics = self.data_columns
        to_delete = []
        for redundant_dict in self.redundant:
            redundant_col, redundant_vals = next(iter(redundant_dict.items()))
            if len(redundant_vals) <= 1:
                logger.warning(
                    ("Number of redundant values lower than 2, cannot compute"
                     + ": %s", redundant_vals)
                    )
                continue
            missing_vals = (set(redundant_vals)
                            - set(df[redundant_col].unique()))
            if missing_vals:
                logger.warning(
                    "Redundant values %s not found in column %s",
                        missing_vals, redundant_col)
                continue
            dicts = dict.fromkeys(metrics, {})
            for metric in metrics:
                dicts[metric]["ranking"], dicts[metric]["comparisons"] = (
                        self.redundant_info_comparison_single(df, by, metric,
                                                              redundant_dict)
                )
                if self.register_intermediate:
                    self.write_intermediate(dicts[metric]["ranking"],
                                            dicts[metric]["comparisons"],
                                            metric, extra_dir="redundancy")
            to_delete.append(
                    {redundant_col: self.redundancy_removal_selector(
                                           dicts, redundant_vals,
                                           by.index(redundant_col)
                                        )}
            )
        # Delete after processing all redundancies just in case there are
        # overlaps between dicts
        to_delete_dict = defaultdict(list)
        for d in to_delete:
            for key, val in d.items():
                to_delete_dict[key].extend(val)
        return filter_dataframe(df, to_exclude=to_delete_dict)

    def redundant_info_comparison_single(self, df, by, metric, redundant_dict):
        grouped = df.groupby(by)[metric]
        redundant_col, redundant_values = next(iter(redundant_dict.items()))
        valued = filter(
                lambda x: np.isin(x[0], redundant_values).any(), grouped)
        combinations = itertools.combinations(valued, 2)
        index = by.index(redundant_col)

        def compatible(pair):
            first, second = pair
            # Same value in redundant_col
            if first[0][index] == second[0][index]:
                return False
            first_ = [x for i, x in enumerate(first[0]) if i != index]
            second_ = [x for i, x in enumerate(second[0]) if i != index]
            if first_ == second_:
                return True
            return False
        selected_comb = filter(compatible, combinations)
        ranking, results = self.compute_difference(selected_comb)
        return ranking, results

    def compute_difference(self, groups):
        results = ResultDict()
        differences = {}
        i = 0
        for i, ((tup_1, data_1), (tup_2, data_2)) in enumerate(groups):
            if self.compute_normality_all(data_1, data_2):
                pval = self.posthoc_normal_test(data_1, data_2)
            else:
                pval = self.posthoc_test(data_1, data_2)
            if tup_1 not in differences:
                differences[tup_1] = DescriptiveStats(
                        tup_1, value=self.difference_function(data_1))
            if tup_2 not in differences:
                differences[tup_2] = DescriptiveStats(
                        tup_2, value=self.difference_function(data_2))
            results[tup_1, tup_2] = pval
        i += 1
        for key, pvalue in results.items():
            if pvalue < self.pvalue / i:
                lower = differences[key[0]].value < differences[key[1]].value
                differences[key[lower]].count += 1
                results[key] = (pvalue, Order.LOWER if lower else Order.GREATER)
            else:
                results[key] = (pvalue, Order.EQUAL)
        if i == 1:  # There is a single group
            return results, differences
        ranking = sorted(differences.values(), reverse=True)
        return ranking, results

    def get_best(self, df, by=None, metrics=None):
        '''
        Computes the value of a certain descriptive column that provides the
        best results.

        Arguments
        ----------------------
        df: pandas.DataFrame
            dataframe that contains the results.
        by: array-like
            list that contains the descriptive columns whose best combination
            of values is going to be computed
        '''
        if not by:
            by = list(set(df.columns) - self.data_columns)
        if not metrics:
            metrics = self.data_columns
        results = defaultdict(dict)
        for metric in metrics:
            results[metric]["ranking"], results[metric]["comparisons"] = (
                    self.compute_metric_best(df, by, metric)
            )
        return results

    def get_best_by_elimination(self, df, by=None, metrics=None):
        if not by:
            by = list(set(df.columns) - self.data_columns)
        if not metrics:
            metrics = self.data_columns
        results = defaultdict(dict)
        for metric in metrics:
            results[metric]["ranking"], results[metric]["comparisons"] =(
                    self.compute_best_metric_by_elimination(df, by, metric)
            )
        return results

    def compute_best_metric_by_elimination(self, df, by, metric):
        evaluated = []
        if not set(self.evaluation_order).issubset(set(by)):
            raise ValueError("Columns in evaluation order are not in descriptive columns")
        to_evaluate = (self.evaluation_order
                       + list(set(by) - set(self.evaluation_order))
        )
        #by[:-1]:  # Only reduce until one dimension is left
        for column in to_evaluate[:-1]:
            evaluated.append(column)
            rest_cols = list(set(by) - set(evaluated))
            filtered_dfs = df.groupby(rest_cols)
            selected_tups = []
            for _, filtered in filtered_dfs:
                ranking, results = self.compute_metric_best(
                    filtered, by, metric)
                selected_tups.append(
                    ranking[0] #if ranking else filtered[by].iloc[0].values.tolist()
                )
                if self.register_intermediate:
                    self.write_intermediate(ranking, results, metric,
                                            rest_cols)
            df = filter_dataframe(df, to_include={tuple(by): selected_tups})
        return self.compute_metric_best(df, by, metric)

    def void_differences(self, groups):
        ranking = []
        for tup, data in groups:
            ranking.append(
                    DescriptiveStats(tup, 0, self.difference_function(data)))
        results = ResultDict(
                map(lambda x: ((x[0][0], x[1][0]), (1, Order.EQUAL)),
                    itertools.combinations(groups, 2))
        )
        ranking = sorted(ranking, reverse=True)
        return ranking, results

    def compute_metric_best(self, df, by, metric):
        grouped = df.groupby(by)[metric]
        if grouped.ngroups >= 3:
            pvalue = self.difference_test(
                    *[g[-1].values for g in grouped])
            if pvalue >= self.pvalue:
                return self.void_differences(grouped)
        ranking, results =  self.compute_difference(
            itertools.combinations(grouped, 2)
        )
        # If we have a single group, adjust the results
        ranking = (
            ranking or
            [DescriptiveStats(tuple(df.iloc[0][by].values.tolist()),
                              value=self.difference_function(df[metric]))]
        )
        return ranking, results

    def adjust_columns(self, df):
        if not self.descriptive_columns:
            self.descriptive_columns = list(
                                           set(df.columns) - self.data_columns)

    def _process(self):
        df = self.loader.load(self.file)
        self.adjust_columns(df)
        df = self.remove_redundant_info(
                df, self.descriptive_columns, self.data_columns)
        if self.elimination:
            return self.get_best_by_elimination(
                    df, by=self.descriptive_columns, metrics=self.data_columns)
        return self.get_best(
                    df, by=self.descriptive_columns, metrics=self.data_columns)

    def write_results(self, results, file):
        def dumper(obj):
            if "to_json" in dir(obj):
                return obj.to_json()
            return json.dumps(obj)
        with open(file, "w") as f:
            json.dump(results, f, indent=4, default=dumper)

    def write_intermediate(self, ranking, results, metric, rest_columns=None,
                           write_columns=False, extra_dir=""):

        if rest_columns:
            unique_indices = [self.descriptive_columns.index(col)
                         for col in rest_columns]
            unique_vals = [ranking[0].name[ind] for ind in unique_indices]
        else:
            unique_vals = ["final"]
        base_path = (pathlib.Path(self.output_path) / extra_dir / metric
                     / '_'.join(unique_vals))
        create_directory(base_path)
        df_ranking = pd.DataFrame(
            [list(tup.name) + [tup.count, tup.value] for tup in ranking],
            columns=self.descriptive_columns + ["Count", "Median_%s" % metric]
        )
        df_ranking.to_csv(str(base_path / "ranking.csv"), header=True,
                          index=False)
        # To load .apply(lambda x: x.strip("()").replace("'", "").split(","))
        df_results = pd.DataFrame(
            [[tup1, tup2, pvalue, order.value]
             for (tup1, tup2), (pvalue, order) in results.items()],
            columns=["First", "Second", "pvalue", "Order"]
        )
        df_results.to_csv(str(base_path / "results.csv"), header=True,
                          index=False)
        if write_columns:
            d = {"all": self.descriptive_columns}
            if rest_columns:
                d["rest"] = rest_columns
            with open(base_path / "columns.csv", "w") as f:
                json.dump(d, f)

    def process(self):
        logger.info("Starting processing")
        results = self._process()
        logger.info("Processing finished, saving results")
        for metric, res in results.items():
            self.write_intermediate(res["ranking"], res["comparisons"],
                                    metric, write_columns=True)
        #self.write_results(results, self.output_file)

def compute_statistics(config):
    sm = StatisticsManager(config)
    sm.process()


import rsa
import hashlib
from Crypto.Signature.pkcs1_15 import PKCS115_SigScheme
from Crypto.Hash import BLAKE2b

class Asymetric_Crypto:

    def __init__(self, content: str, public_key: str, crypto_algorithm: str):
        self.content = content.encode("utf-8")
        self.crypto_algorithm = crypto_algorithm
        self.public_key = public_key

    def get_signature(self, private_key):
        signer = PKCS115_SigScheme(private_key)
        return signer.sign(self.content)

    def get_content(self):
        return self.content.decode("utf-8")

    def encrypt(self):
        try:
            hash = BLAKE2b.new()
            hash.update(self.content)
            self.content = hash
        except Exception as exception:
            print(exception)

    def decrypt(self, private_key):
        try:
            self.content = rsa.decrypt(self.content, private_key)
        except Exception as exception:
            print(exception)
            return False

    def verify_signature(self, private_key):
        try:
            check = PKCS115_SigScheme(private_key).verify(self.content, self.get_signature(private_key))
            return check
        except Exception as exception:
            print(exception)
            return False


from typing import List

class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        num_set = set(nums)
        longest = 0

        for num in num_set:
            if num - 1 not in num_set:
                length = 0
                while num + length in num_set:
                    length += 1
                longest = max(longest, length)

        return longest

s = Solution()
print(s.longestConsecutive([100,4,200,1,3,2]))
print(s.longestConsecutive([0,3,7,2,5,8,4,6,0,1]))


"""Add table tokens

Revision ID: eeeede4c6639
Revises: d58a3bf35637
Create Date: 2022-02-05 21:35:46.857812

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "eeeede4c6639"
down_revision = "d58a3bf35637"
branch_labels = None
depends_on = None

def upgrade():
    op.create_table(
        "tokens",
        sa.Column("id", postgresql.UUID(), nullable=False),
        sa.Column("token", sa.String(), nullable=True),
        sa.Column("comment", sa.String(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(op.f("ix_tokens_token"), "tokens", ["token"], unique=True)

def downgrade():
    op.drop_index(op.f("ix_tokens_token"), table_name="tokens")
    op.drop_table("tokens")


#!/usr/bin/env python

import ipaddress
import pdb
import shelve

from plugins import PLUGINS, UNAVAILABLE_PLUGINS

DATA = None
VERBOSE = False

def ensure_structure(d):
    try:
        DATA['index']
    except KeyError:
        DATA['index'] = dict()

def main():
    global DATA, VERBOSE

    import argparse
    parser = argparse.ArgumentParser(description='Scan a network')
    parser.add_argument('--extensive', '-e', action='store_true', help='Start an extensive nmap scan.')
    parser.add_argument('--netbios', '-n', action='store_true', help='Start a netbios nmap scan.')
    parser.add_argument('--shelvefile', '-s', help='File to store the run in.')
    parser.add_argument('--plugin', '-p', default='libnmap', help='Backend plugin and an scan type.')
    parser.add_argument('--verbose', '-v', action='store_true', help='Make the tool more verbose.')
    parser.add_argument('networks', metavar='NETWORK', nargs='+', help='A network to be scanned.')
    args = parser.parse_args()

    # Check 'networks' arguments
    try:
        # Try to interpret each argument as an IP network
        networks = [ipaddress.ip_network(network, strict=False) for network in args.networks]
    except:
        parser.error('Did not understand the network(s) provided.')

    if args.verbose: VERBOSE = True

    # Check the --shelvefile parameter
    if args.shelvefile:
        try:
            DATA = shelve.open(args.shelvefile)
        except:
            parser.error('Could not open the shelvefile!.')
        ensure_structure(DATA)

    # Check the parameters to pre-set the nmap arguments
    arguments = '-sn -PE -PA21,23,80,3389'
    if args.extensive:
        arguments = '-A -v -v -T aggressive'
    if args.netbios:
        arguments = '-sU -p 137,5353 --script nbstat,dns-service-discovery -T aggressive'

    # Check the --plugin parameter
    if args.plugin:
        plugin_name = args.plugin.partition(':')[0]
        plugin_arguments = args.plugin.partition(':')[2]
        if plugin_name in UNAVAILABLE_PLUGINS:
            parser.error("Sorry, the plugin {} is currently not available. Please install its requirements.".format(plugin_name))
        if plugin_name not in PLUGINS:
            parser.error("Sorry, the plugin {} does not exist.".format(plugin_name))
        scanner = PLUGINS[plugin_name]()
        if plugin_arguments:
            arguments = plugin_arguments

    # Start scanning
    scanner.scan(networks=networks, arguments=arguments, verbose=VERBOSE)
    #pdb.set_trace()
    if DATA:
        scanner.log_scan(DATA)

    if DATA: DATA.close()

if __name__ == "__main__":
    main()


import os
import re
import copy
import json
import tensorflow as tf
import numpy as np
import time
from classes.keyboard_structure import KeyboardStructure
from classes.characters_placement import CharactersPlacement

start_time = time.time()

random_seed=961
np.random.seed(random_seed)
tf.random.set_seed(random_seed)

punct = True
number_of_characters_placements = 10000

def _preprocess_line(line):
    _regex = re.compile('[^%s]' % ''.join(sorted(set(initial_characters_placement))))
    return _regex.sub('', line)

def build_corpus():
    corpus_path = "./data_dir/TED2013 v1.1.txt"
    maximum_line_length = 500
    searching_corpus_size = 10000

    corpus = open(corpus_path, 'r', encoding='utf-8').read().split('\n')
    corpus = [line for line in corpus if len(line) <= maximum_line_length]

    rng = np.random.RandomState(random_seed)
    rng.shuffle(corpus)

    searching_corpus = [_preprocess_line(line) for line in corpus[:searching_corpus_size]]

    if len(searching_corpus) < searching_corpus_size:
        print('Searching corpus size didn\'t reach %s, its current size is %s' %
                    (searching_corpus_size, len(searching_corpus)))

    searching_corpus_dict = dict()
    for line in searching_corpus:
        for char in line.strip():
            try:
                searching_corpus_dict[char] += 1
            except:
                searching_corpus_dict[char] = 1

    return searching_corpus_dict

def buildCarpalxInput(keyboard):
    carpalx_file_name = "carpalx-0.12\keren\keren.conf"
    with open(carpalx_file_name, 'w') as carpalx_file:
        carpalx_file.write(
            "<keyboard>\n<row 1>\nkeys    = `~ 1! 2@ 3\\# 4$ 5% 6^ 7& 8* 9( 0) -_ =+\nfingers =  0  1  1   2  3  3  3  6 7   7  8  9  9\n</row>\n<row 2>\nkeys    =")

        letters = 0
        for button, character in zip(keyboard_structure.buttons, keyboard):
            if character in my_letters:
                letters += 1
                carpalx_file.write(" " + character)

                if letters == 9:
                    carpalx_file.write(" ;: [{ ]} \\|\nfingers = 0 1 2 3 3 6 6 7 8 9  9  9  9\n</row>\n<row 3>\nkeys    =")

                if letters == 19:
                    carpalx_file.write(" '\"\nfingers = 0 1 2 3 3 6 6 7 8  9  9\n</row>\n<row 4>\nkeys    =")

                if letters == 26:
                    carpalx_file.write(" ,< .> /?\nfingers = 0 1 2 3 3 6 6  7  8  9\n</row>\n</keyboard>")
                    break

        carpalx_file.close()

def buildCarpalxInput_punct(keyboard):
    punct_map = {"-":"-_", "+":"=+", "{":"[{", "}":"]}", ";":";:", "'":"'\"", ",":",<", ".":".>", "?":"/?"}

    carpalx_file_name = "carpalx-0.12\keren\keren.conf"
    with open(carpalx_file_name, 'w') as carpalx_file:
        carpalx_file.write("<keyboard>\n<row 1>\nkeys    = `~ 1! 2@ 3\\# 4$ 5% 6^ 7& 8* 9( 0)")

        letters = 0
        for button, character in zip(keyboard_structure.buttons, keyboard):
            if character in my_letters:
                letters += 1

                if character in punct_map.keys():
                    carpalx_file.write(" " + punct_map[character])
                elif character>='a' and character<='z':
                    carpalx_file.write(" " + character)
                else:
                    print("wrong character: ", character)
                    exit(1)

                if letters == 2:
                    carpalx_file.write("\nfingers =  0  1  1   2  3  3  3  6 7   7  8  9  9\n</row>\n<row 2>\nkeys    =")

                if letters == 14:
                    carpalx_file.write(" \\|\nfingers = 0 1 2 3 3 6 6 7 8 9  9  9  9\n</row>\n<row 3>\nkeys    =")

                if letters == 25:
                    carpalx_file.write(" \nfingers = 0 1 2 3 3 6 6 7 8  9  9\n</row>\n<row 4>\nkeys    =")

                if letters == 35:
                    carpalx_file.write(" \nfingers = 0 1 2 3 3 6 6  7  8  9\n</row>\n</keyboard>")
                    break

        carpalx_file.close()

#open genetic_config
if(punct):
    path_str = "and_punctuations"
else:
    path_str = "only"

genetic_config_path = "searched_characters_placements\letters_" + path_str + "_dir\genetic_config.json"
with open(genetic_config_path, 'r') as file:
    genetic_config = json.load(file)
initial_characters_placement = CharactersPlacement(characters_set=genetic_config['characters_set'])
keyboard_structure = KeyboardStructure(
    name=genetic_config['keyboard_structure']['name'],
    width=genetic_config['keyboard_structure']['width'],
    height=genetic_config['keyboard_structure']['height'],
    buttons=genetic_config['keyboard_structure']['buttons'],
    hands=genetic_config['hands']
)

#my buttons ids
my_letters = []
my_buttons = [keyboard_structure.buttons[i].id for i in range(len(keyboard_structure.buttons))]
for c in initial_characters_placement.characters_set:
    if(c.button_id is not None):
        my_buttons.remove(c.button_id)
    else:
        my_letters.append(c.character)
number_of_characters = len(my_letters)

print("generating labeled keyboards...")
searching_corpus_dict = build_corpus()
characters_placements = list()
labels = np.zeros([number_of_characters_placements], dtype=float)
for i in range(number_of_characters_placements):
    characters_placements.append(copy.deepcopy(initial_characters_placement))
    characters_placements[-1].randomize()

    if(punct):
        buildCarpalxInput_punct(characters_placements[-1])
    else:
        buildCarpalxInput(characters_placements[-1])
    my_cmd = "perl carpalx-0.12/keren/carpalx_keren -conf carpalx-0.12/etc/tutorial-00.conf"
    my_cmd_output = os.popen(my_cmd)
    for line in my_cmd_output:
        labels[i] = float(line.rstrip())

#one-hot from bzq
features = np.zeros([number_of_characters_placements,number_of_characters,number_of_characters], dtype=int)
for cp in range(len(characters_placements)):
    for l in range(len(my_letters)):
        for button, character in zip(keyboard_structure.buttons, characters_placements[cp]):
            if character == my_letters[l]:
                #if (button.id==22):
                #    print(cp)
                #    for button, character in zip(keyboard_structure.buttons, characters_placements[cp]):
                #        print(button.id, character)
                #    exit()
                position = my_buttons.index(button.id)
                features[cp][l][position] = 1
                break

#qwerty
#qpath = "predefined_characters_placements\qwerty_dir\genetic_config.json"
#with open(qpath, 'r') as file:
#    qgenetic_config = json.load(file)
#qwerty_placement = CharactersPlacement(characters_set=qgenetic_config['characters_set'])
#qwerty_onehot = np.zeros([1,number_of_characters,number_of_characters], dtype=int)
#for l in range(len(my_letters)):
#    for button, character in zip(keyboard_structure.buttons, qwerty_placement):
#        if character == my_letters[l]:
#            position = my_buttons.index(button.id)
#            qwerty_onehot[0][l][position] = 1
#            break

#qwerty_placement.calculate_fitness(keyboard_structure, searching_corpus_dict)
#qwerty_label = qwerty_placement.fitness

#save generated data
path_str = ""
if(punct):
    path_str = "_punct"

data_file_path = "carpalx-0.12\keren\data" + path_str + ".txt"
with open(data_file_path, 'w') as data_file:
    for f in range(len(features)):
        for i in range(len(my_letters)):
            for j in range(len(my_letters)):
                data_file.write(str(features[f][i][j]) + " ")
        data_file.write(str(labels[f]) + "\n")

data_file.close()

print("time: ", time.time() - start_time)


from . import catalog
from . import irodscatalog

from six.moves import configparser
from six import print_

import os
import os.path
import stat
import tempfile
import collections

# default config location
default_config_filename = os.path.join(os.path.expanduser('~'),
                                       '.brocoli.ini')

# available catalogs
catalog_dict = {
    'os': catalog.OSCatalog,
    'irods3': irodscatalog.iRODSCatalog3,
    'irods4': irodscatalog.iRODSCatalog4,
}

catalog_types = list(catalog_dict.keys())

SETTINGS = 'SETTINGS'
DEFAULT_CONNECTION = 'default_connection'

class Config(collections.OrderedDict):
    """
    Holds the brocoli configuration loaded from the config file
    """

    def connection(self, name=None):
        name = name or self.default_connection_name()

        if name is None:
            return None, None

        conn = self['connection:' + name]

        cat = None
        catalog_type = conn['catalog_type']
        if catalog_type == 'os':
            cat = lambda master: catalog.OSCatalog()
        elif catalog_type == 'irods3':
            cat = irodscatalog.irods3_catalog_from_config(conn)
        elif catalog_type == 'irods4':
            cat = irodscatalog.irods4_catalog_from_config(conn)

        return cat, conn['root_path']

    def connection_names(self):
        return [k.split(':', 1)[1] for k in self if k.startswith('connection:')]

    def default_connection_name(self):
        return self[SETTINGS].get('default_connection', None)

def bootstrap_config_parser(config):
    """
    Fills ConfigParser object with minimal values
    """
    config.add_section(SETTINGS)

def load_config(filename=None):
    """
    Loads configuration from file
    """
    filename = filename or default_config_filename

    config = configparser.RawConfigParser()

    if os.path.exists(filename):
        config.read(filename)
    else:
        bootstrap_config_parser(config)

    ret = Config()

    for section in config.sections():
        ret[section] = collections.OrderedDict(config.items(section))

    return ret

def save_config(config_dict, filename=None, update=False):
    """
    Writes configuration to a file
    """
    filename = filename or default_config_filename

    config = configparser.RawConfigParser()

    if update:
        if os.path.exists(filename):
            config.read(filename)
        else:
            bootstrap_config_parser(config)

    for section, section_content in config_dict.items():
        if not config.has_section(section):
            config.add_section(section)

        for option, option_value in section_content.items():
            config.set(section, option, option_value)

    with open(filename, 'wt') as f:
        os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR)
        config.write(f)


import dlib
import pickle
import numpy as np
from skimage import io
from iextraction import IExtraction
import matplotlib.pyplot as plt

class FacePrefExctractor(IExtraction):

    def __init__(self, predictorFilePath):
        self.shape_predictor_path = predictorFilePath

    def __transform_to_global_coordinates(self, landmarks, imgPath, xOrigin, yOrigin):
        '''Transforms the X and Y coordinates of the extracted features from relative picture coordinates to screen coordinates'''
        xLL, yLL = self.__compute_picture_lowerLeft_coord(imgPath, xOrigin, yOrigin)
        for idx, point in enumerate(landmarks):
            landmarks[idx] = [xLL + point[0, 0], yLL + point[0, 1]]

    def __compute_picture_lowerLeft_coord(self, imgPath, xOrigin, yOrigin):
        img = io.imread(imgPath)
        print(img.shape)
        size = img.shape
        return (xOrigin - size[1]//2, yOrigin - size[0]//2) # X and Y dimenstions are flipped when reading the shape of the picture.

    def convert_landmarks_to_features(self, landmarks, heatmap, resReduction):
        features = []
        pointsX = []
        pointsY = []
        for idx, point in enumerate(landmarks):
            pointsX.append(point[0,0])
            pointsY.append(420-point[0,1])
            try:
                print("Point (" + str(point[0,0]//10) +"," + str(point[0,1]//10) + ")")
                p = heatmap[point[0,0]//resReduction, (420-point[0,1])//resReduction]
                features.append(int(p))
            except:
                print("Point (" + str(point[0,0]) +"," + str(point[0,1]) + " out of bounds")
                features.append(0)
        print(features)
        print(len(features))
        plt.scatter(pointsX, pointsY)
        plt.show()
        return features

    def extractFeatures(self, imgPath, xOrigin, yOrigin):
        detector = dlib.get_frontal_face_detector()
        predictor = dlib.shape_predictor(self.shape_predictor_path)

        print("Processing file: {}".format(imgPath))
        img = io.imread(imgPath)

        # Ask the detector to find the bounding boxes of each face. The 1 in the
        # second argument indicates that we should upsample the image 1 time. This
        # will make everything bigger and allow us to detect more faces.
        dets = detector(img, 1)
        print("Number of faces detected: {}".format(len(dets)))
        for k, d in enumerate(dets):
            print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
                k, d.left(), d.top(), d.right(), d.bottom()))
            # Get the landmarks/parts for the face in box d.
            shape = predictor(img, d)
            landmarks = np.matrix([[p.x, p.y] for p in shape.parts()])
            #self.__transform_to_global_coordinates(landmarks, imgPath, xOrigin, yOrigin)
        return landmarks

ex = FaceExctractor("C:\\Users\\Roee\\Desktop\\edf\\shape_predictor_68_face_landmarks.dat")
marks = ex.extractFeatures("C:\\Users\\Roee\\Desktop\\edf\\img\\114_shafir_stav.jpg", 960, 540)

with open("./heatmap.pkl", 'rb') as file:
    heatmap = pickle.load(file)

img = plt.imread("C:\\Users\\Roee\\Desktop\\edf\\img\\114_shafir_stav.jpg")
extent = [0,280,0,420]
heatmap = np.ma.masked_where(heatmap < 1, heatmap, copy=False) # choose lower bound values (currently shows anything with value > 0) for visualization
plt.imshow(img, extent = extent)
plt.imshow(heatmap.T, extent = extent, origin='lower', cmap = 'jet', alpha = 0.7)
feats = ex.convert_landmarks_to_features(marks, heatmap, 10)


# -*- coding: utf-8 -*-
"""
Created on Wed Dec  7 08:33:48 2022

@author: Nino
"""

from aoc import *
import networkx as nx
import matplotlib.pyplot as plt

commands = read_input('day07')

G = nx.DiGraph()

# root node
node_id, cwd_id, cwd_name = 1, 1, '/'
G.add_node(node_id, name=cwd_name, size=0, ftype=0)

for c in commands[1:]:
    if c[:4] == '$ cd':        # go to folder
        _, _, folder_name = c.split(' ')
        if folder_name == '..': # one step back
            cwd_id = list(G.predecessors(cwd_id))[0]
        else: # one step forward
            for n in list(G.successors(cwd_id)):
                if G.nodes[n]['name']==folder_name:
                    cwd_id = n
                    break
        cwd_name = G.nodes[cwd_id]['name']
        print(c, f' -> goto to folder {cwd_name} ({cwd_id})')
    elif c[:4] == '$ ls':
        continue
    elif c[:3] == 'dir': # add folder node
        _, fname = c.split(' ')
        node_id += 1
        print(c, f' -> add folder {fname} ({node_id}) to folder {cwd_name} ({cwd_id})')
        G.add_node(node_id, name=fname, size=0, ftype=0)
        G.add_edge(cwd_id, node_id)
    else: # add file node
        size, file = c.split(' ')
        node_id += 1
        print(c, f' -> add file {file} ({node_id}) to folder {cwd_name} ({cwd_id})')
        G.add_node(node_id, name=file, size = int(size), ftype=1)
        G.add_edge(cwd_id, node_id)

# part 1
part1 = 0
for node in nx.nodes(G):
    for n in nx.descendants(G, node):
        G.nodes[node]['size'] += G.nodes[n]['size']
    if G.nodes[node]['ftype'] == 0 and G.nodes[node]['size'] <= 100_000:
        part1 += G.nodes[node]['size']

print(part1)

# part 2
free_space = 70_000_000 - G.nodes[1]['size']
needed_space = 30_000_000 - free_space

space = 1e9
for node in nx.nodes(G):
    if  (G.nodes[node]['ftype'] == 0 and
         space > G.nodes[node]['size'] >= needed_space):
        space = G.nodes[node]['size']

print(space)


import datetime
import os
import json
import re
import pickle
import requests
from bs4 import BeautifulSoup
from dateutil import parser
from traceback import format_exc
from retry import retry
from project.server.main.utils_swift import upload_object, download_object
from project.server.main.logger import get_logger

logger = get_logger(__name__)

@retry(delay=60, tries=5)
def get_idref_list_in_referentiel():
    NB_ROWS = 10000
    start = 0

    idref_to_download = []
    keep_going = True

    while keep_going:
        url = f'https://www.idref.fr/Sru/Solr?q=recordtype_z:b&version=2.2&start={start}&rows={NB_ROWS}&wt=json&fl=ppn_z'
        res = requests.get(url).json()['response']
        idref_to_download += [p['ppn_z'] for p in res['docs']]
        keep_going = len(res['docs']) > 0
        start += NB_ROWS
        logger.debug(f"{len(idref_to_download)} sur {res['numFound']}")
    return idref_to_download

def get_referentiel(collection_name):
    idref_to_download = get_idref_list_in_referentiel()

    chunk_index = 0
    data_notice, data_parsed = [], []
    MAX_DATA_SIZE = 5000
    #MAX_DATA_SIZE = 100 #fast
    nb_idref = len(idref_to_download)
    logger.debug(f'{nb_idref} idref struct to download and parse')
    for ix, idref in enumerate(idref_to_download):
        if ix % 1000 == 0:
            logger.debug(f'idref struct {ix}')
        try:
            notice = download_referentiel_notice(idref)
            elt_notice = {'idref': idref, 'notice': notice}
            data_notice.append(elt_notice)
            elt_parsed = parse_idref(idref, notice)
            data_parsed.append(elt_parsed)
        except:
            logger.debug(f'error in downloading notice for idref {idref}')
            continue
        if (len(data_notice) > MAX_DATA_SIZE) or (ix == nb_idref - 1):
            if data_notice:
                source = f'idref_struct_raw_{chunk_index}.json'
                target = f'{collection_name}/{source}'
                save_data_referentiel(data_notice, source, target)
                data_notice = []
                chunk_index += 1
    return data_parsed

def save_data_referentiel(data, source, target):
    current_file = source
    json.dump(data, open(current_file, 'w'))
    os.system(f'gzip {current_file}')
    upload_object('theses', f'{source}.gz', f'{target}.gz')
    os.system(f'rm -rf {source}.gz')

def parse_idref(idref, notice):
    soup = BeautifulSoup(notice, 'lxml')
    elt = {}
    idref_elt = soup.find('controlfield', {"tag": "001"})
    try:
        assert(idref_elt.text == idref)
    except Exception as e:
        print("idref not matching in notice")

    elt['idref'] = idref
    alias_idref = []
    aliases = []

    name_elt = soup.find("datafield", {"tag": "210"})
    if name_elt and name_elt.find("subfield", {'code': 'a'}):
        elt['name'] = name_elt.find("subfield", {'code': 'a'}).text

    for f in soup.find_all("datafield", {"tag": "410"}) + soup.find_all("datafield", {"tag": "911"}):
        if f.find("subfield", {'code': 'a'}):
            aliases.append(f.find("subfield", {'code': 'a'}).text)
    elt['aliases'] = list(set(aliases))

    addresses, websites = [], []
    comments = []
    for f in soup.find_all("datafield", {"tag": "340"}):
        if f.find("subfield", {'code': 'a'}):
            txt = f.find("subfield", {'code': 'a'}).text
            if 'adresse' in txt.lower() and len(txt.split(':'))>1:
                addresses.append(':'.join(txt.split(':')[1:]).strip())
            elif 'site internet' in txt.lower() and len(txt.split(':'))>1:
                websites.append(':'.join(txt.split(':')[1:]).strip())
            else:
                comments.append(txt.strip())

    if addresses:
        elt['addresses'] = addresses
    if websites:
        elt['websites'] = websites
    if comments:
        elt['comments'] = comments

    for f in soup.find_all("datafield", {"tag": "010"}):
        if f.find("subfield", {'code': 2}) and f.find("subfield", {'code': 2}).text=='ISNI':
            if f.find("subfield", {'code': 'a'}):
                elt['ISNI'] = f.find("subfield", {'code': 'a'}).text

    for f in soup.find_all("datafield", {"tag": "033"}):
        if f.find("subfield", {'code': 2}) and f.find("subfield", {'code': 2}).text=='BNF':
            if f.find("subfield", {'code': 'a'}):
                elt['BNF'] = f.find("subfield", {'code': 'a'}).text

    for f in soup.find_all("datafield", {"tag": "035"}):
        if f.find("subfield", {'code': 9}) and f.find("subfield", {'code': 9}).text=='sudoc':
            if f.find("subfield", {'code': 'a'}):
                alias_idref.append(f.find("subfield", {'code': 'a'}).text)

        if f.find("subfield", {'code': 2}) and f.find("subfield", {'code': 2}).text=='HAL':
            if f.find("subfield", {'code': 'a'}):
                elt['docid'] = f.find("subfield", {'code': 'a'}).text

        if f.find("subfield", {'code': 2}) and f.find("subfield", {'code': 2}).text=='RNSR':
            if f.find("subfield", {'code': 'a'}):
                elt['rnsr'] = f.find("subfield", {'code': 'a'}).text

        if f.find("subfield", {'code': 2}) and f.find("subfield", {'code': 2}).text=='VIAF':
            if f.find("subfield", {'code': 'a'}):
                elt['viaf'] = f.find("subfield", {'code': 'a'}).text

    elt['alias_idref'] = alias_idref
    return elt

@retry(delay=60, tries=5)
def download_referentiel_notice(idref):
    r = requests.get(f'http://www.idref.fr/{idref}.xml')
    if r.text[0:5] == '<?xml':
        return r.text
    return None

def create_idref_map(data):
    idref_map = {}
    parsed_data = []
    for d in data:
        idrefs = [d['idref']]
        parsed_elt = d
        idrefs += parsed_elt.get('alias_idref', [])
        idrefs = list(set(idrefs))
        parsed_data.append(parsed_elt)
        for idref in idrefs:
            idref_map[str(idref)] = parsed_elt
    logger.debug(f'{len(data)} elts and {len(idref_map)} idrefs (structure) in map')
    return parsed_data, idref_map

def harvest_and_save_idref(collection_name):
    # raw data
    data = get_referentiel(collection_name)

    #parsed data
    parsed_data, idref_map = create_idref_map(data)

    source = f'idref_struct.json'
    target = f'{collection_name}/{source}'
    save_data_referentiel(parsed_data, source, target)

    # idref mapping
    source = f'idref_struct_dict.json'
    target = f'{collection_name}/{source}'
    save_data_referentiel(idref_map, source, target)


import os

import tensorflow as tf

from tensor2tensor import problems
from tensor2tensor.bin import t2t_decoder  # To register the hparams set
from tensor2tensor.utils import registry
from tensor2tensor.utils import trainer_lib
from tensor2tensor.visualization import attention
from tensor2tensor.visualization import visualization
from IPython.display import Image, display

import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
import skimage.transform
import pickle
from PIL import Image
from subprocess import call
import matplotlib.patches as patches

import base64
import csv
import sys

csv.field_size_limit(sys.maxsize)
FIELDNAMES = ['image_id', 'image_w','image_h','num_boxes', 'boxes', 'features']

# Saving the objects:
def save_objects(obj):
    with open('data/objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
        pickle.dump(obj, f)

# Getting back the objects:
def restore_objects():
    with open('data/objs.pkl') as f:  # Python 3: open(..., 'rb')
        obj = pickle.load(f)
    return obj

# PUT THE MODEL YOU WANT TO LOAD HERE!
CHECKPOINT = os.path.expanduser('data/t2t_train/image_ms_coco_tokens32k_object_position/transformer-transformer_base_single_gpu')

# HParams
problem_name = 'image_ms_coco_tokens32k'
data_dir = os.path.expanduser('data/t2t_data_caption_bottom')
model_name = "transformer"
hparams_set = "transformer_base_single_gpu"

# ## Visualization
use_bottom_up_features = True
visualizer = visualization.AttentionVisualizer(hparams_set, use_bottom_up_features, model_name, data_dir, problem_name, beam_size=4)

tf.Variable(0, dtype=tf.int64, trainable=False, name='global_step')

sess = tf.train.MonitoredTrainingSession(
    checkpoint_dir=CHECKPOINT,
    save_summaries_secs=0,
)

image_file_name = 'COCO_val2014_000000076619'
image_file_parts = image_file_name.split('_')
image_id = int(image_file_parts[2])
image_path = os.path.expanduser('data/visualize/'+image_file_name+'.jpg')
bottom_up_feature_filepath = os.path.expanduser('data/tmp/t2t_datagen_caption/bottom_up_features/trainval/karpathy_val_resnet101_faster_rcnn_genome.tsv')

if use_bottom_up_features:
    with open(bottom_up_feature_filepath, "r+b") as tsv_in_file:
        reader = csv.DictReader(tsv_in_file, delimiter='\t', fieldnames=FIELDNAMES)
        for item in reader:
            item['image_id'] = int(item['image_id'])
            item['image_h'] = int(item['image_h'])
            item['image_w'] = int(item['image_w'])
            item['num_boxes'] = int(item['num_boxes'])
            for field in ['boxes', 'features']:
                item[field] = np.frombuffer(base64.decodestring(item[field]),
                                            dtype=np.float32).tolist()
            if image_id == item['image_id']:
                print('Found Matching object features')
                break

output_string, inp_text, out_text, att_mats = visualizer.get_vis_data_from_image(sess, image_id, image_path, item['features'], item['boxes'], use_bottom_up_features)
save_objects([output_string, inp_text, out_text, att_mats])

output_string, inp_text, out_text, att_mats = restore_objects()
print(np.shape(att_mats[0]))
print(np.shape(att_mats[1]))
print(np.shape(att_mats[2]))
print(output_string)

if use_bottom_up_features:
    img = ndimage.imread(image_path, mode='RGB')
    for l in range(4,6):
        for a in range(8):
            # Plot original image
            # img = ndimage.imread(image_path)
            plt.subplot(4, 4, 1)
            plt.imshow(img)
            plt.axis('off')

            # Plot images with attention weights
            words = out_text
            for t in range(len(words)):
                plt.subplot(4, 4, t + 2)
                words[t] = words[t].replace('_', '')
                plt.text(0, 1, '%s' % words[t], color='black', backgroundcolor='white', fontsize=8)
                plt.imshow(img)
                input_output_attn = att_mats[2]
                alp_curr = np.zeros([item['image_w'], item['image_h']])
                num_boxes = item['num_boxes']
                boxes = np.asarray(item['boxes']).reshape(-1, 4)
                for box_index in range(num_boxes):
                    for x in range(int(boxes[box_index][0]), int(boxes[box_index][2])):
                        for y in range(int(boxes[box_index][1]), int(boxes[box_index][3])):
                            alp_curr[x][y] += input_output_attn[l][0][a][t][box_index]
                alp_img = alp_curr

                #alp_img = skimage.transform.pyramid_expand(alp_curr, upscale=16, sigma=20)
                plt.imshow(np.transpose(alp_img), alpha=0.5)
                plt.axis('off')
            # plt.show()
            attn_file = 'data/visualize' + str(image_file_name) \
                        + '/input_output_' + 'layer_' + str(l) + 'head' + str(a)

            directory = os.path.dirname(attn_file)
            try:
                os.stat(directory)
            except:
                os.mkdir(directory)
            plt.savefig(attn_file, format='png', dpi=1000)
    exit(0)

img = inp_text.astype(int)
for l in range(6):
    for a in range(8):
        # Plot original image
        #img = ndimage.imread(image_path)
        plt.subplot(4, 4, 1)
        plt.imshow(img)
        plt.axis('off')

        # Plot images with attention weights
        words = out_text
        for t in range(len(words)):
            plt.subplot(4, 4, t+2)
            words[t] =words[t].replace('_', '')
            plt.text(0, 1, '%s' % words[t], color='black', backgroundcolor='white', fontsize=8)
            plt.imshow(img)
            input_output_attn = att_mats[2]
            alp_curr = input_output_attn[l][0][a][t].reshape(14, 14)
            alp_img = alp_curr
            alp_img = skimage.transform.pyramid_expand(alp_curr, upscale=16, sigma=20)
            plt.imshow(alp_img, alpha=0.85)
            plt.axis('off')
        #plt.show()
        attn_file = 'data/visualize/'+ str(image_file_name) \
                    + '/input_output_' + 'layer_' + str(l) + 'head' + str(a)

        directory = os.path.dirname(attn_file)
        try:
            os.stat(directory)
        except:
            os.mkdir(directory)
        plt.savefig(attn_file, format='png', dpi=1000)


from csv import reader
import sys
from pyspark import SparkContext

sc = SparkContext()

joined = sc.textFile(sys.argv[1], 1) # "/user/as9621/task1b.out")
joined = joined.mapPartitions(lambda x : reader(x))
joined = joined.map(lambda line : [elem.strip() for elem in line])

# agent_name x[20] | fare_amount x[5]

joined = joined.map(lambda x : ( (x[20]), (float(x[5]))  )).reduceByKey(lambda x, y : (x + y) ).sortBy(lambda x : x[1], ascending =  False)

joined = sc.parallelize(joined.take(10))

joined = joined.map(lambda x : str(x[0]) + ',' + str(format(round(x[1], 2), '.2f'))     )

joined.saveAsTextFile('task4c.out')
sc.stop()


import socket
import threading
import json
import time
import random

class Message:
    def __init__(self, request, key, value, timestamp):
        self.request = request
        self.key = key
        self.value = value
        self.timestamp = timestamp

class Server:
    def __init__(self, localIP, localPort, leaderIP, leaderPort):
        self.localIP = localIP
        self.localPort = int(localPort)
        self.leaderIP = leaderIP
        self.leaderPort = int(leaderPort)
        self.dataBase = [["0", "Teste", "-1"]]
        self.serverList = [10097, 10098, 10099]
        self.serverList.remove(self.localPort)
        self.serverTS = 0

        # Define if this server is the Leader
        self.isLeader = self.leaderPort == self.localPort

        try:
            self.Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.Server.bind((self.localIP, self.localPort))
        except socket.error as e:  # Tratamento de erros
            print(f"erro na criacao do socket erro {e}")

    # Uso de threads para responder simultaneamente os clientes
    def serverUp(self):
        self.Server.listen()

        while True:
            connection, adrs = self.Server.accept()

            thread_processes = threading.Thread(target=self.multiThread, args=[connection, adrs])
            thread_processes.start()

    def multiThread(self, connection, adrs):
        req = connection.recv(1024).decode()
        message = json.loads(req)
        reqOption = message["request"]
        kv = f"key: [{message['key']}] value: [{message['value']}]"

        if reqOption == "PUT":
            if self.isLeader:
                print(f"Cliente [{adrs[0]}]:[{adrs[1]}] PUT {kv}")
            else:
                print(f"Encaminhando PUT {kv}")

            self.PUT(connection, adrs, req)

        elif reqOption == "GET":
            self.GET(connection, adrs, message)

        elif reqOption == "REPLICATION":
            print(
                f"REPLICATION {kv} ts: [{message['timestamp']}]")
            self.REPLICATION(connection, message)

        connection.shutdown(socket.SHUT_RDWR)
        connection.close()
        return

    # Requisições PUT, tratando o caso em que servidores que não são o lider que recebem a requisição
    def PUT(self, connection, adrs, req):
        if self.isLeader:
            message = json.loads(req)
            self.updateDB(message["key"], message["value"], self.serverTS)
            try:
                server1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                server2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

                server1.connect(('127.0.0.1', self.serverList[0]))
                server2.connect(('127.0.0.1', self.serverList[1]))

                message_server_aux = Message(
                    "REPLICATION", message["key"], message["value"], self.serverTS)
                message_server = json.dumps(message_server_aux.__dict__)

                server1.send(message_server.encode())
                server2.send(message_server.encode())

                okFromServer1 = server1.recv(1024).decode()
                okFromServer2 = server2.recv(1024).decode()
                server1ToJson = json.loads(okFromServer1)
                server2ToJson = json.loads(okFromServer2)
                server1Request = server1ToJson["request"]
                server2Request = server2ToJson["request"]

                if server1Request != "REPLICATION_OK" or server2Request != "REPLICATION_OK":
                    messagePUT = Message(
                        "PUT_ERROR", message["key"], message["value"], message["timestamp"])
                else:
                    print(
                        f"Enviando PUT_OK ao Cliente {adrs[0]}:{adrs[1]} da key: [{message['key']}] ts: [{self.serverTS}]")
                    messagePUT = Message(
                        "PUT_OK", message["key"], message["value"], message["timestamp"])

                resp = json.dumps(messagePUT.__dict__)
                connection.send(resp.encode())

                server1.close()
                server2.close()

                # Controle do Timestamp
                self.serverTS = self.serverTS + 1

            except socket.error as e:
                print(f"error in PUT request {e}")

        else:
            LeaderServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            LeaderServer.connect((self.leaderIP, self.leaderPort))
            leaderRequest = req.encode()
            LeaderServer.send(leaderRequest)
            leaderReturn = LeaderServer.recv(1024).decode()
            connection.send(leaderReturn.encode())

    # Replication das informações para os outros servidores
    def REPLICATION(self, connectionServer, message):
        try:
            # Uso de ramdomizer para simular latencia
            latency = random.randint(1, 6)
            for i in range(0, latency):
                time.sleep(1)

            for item in self.dataBase:
                if item[0] == message["key"]:
                    item[1] = message["value"]
                    item[2] = message["timestamp"]

            messageRepl = Message(
                "REPLICATION_OK", message["key"], message["value"], message["timestamp"])
            resp = json.dumps(messageRepl.__dict__)

            connectionServer.send(resp.encode())

            self.serverTS = self.serverTS + 1
        except socket.error as e:
            print(f"error in Replicarion {e}")

    # Requisições GET
    def GET(self, connection, adrs, message):
        try:
            # Devolução Null da chave que não existe
            messageGET = Message("NULL", "NULL", "NULL", "0")

            for item in self.dataBase:
                if item[0] == message['key']:
                    # Comparacao do timestamp para obter o valor mais recente
                    if int(item[2]) < int(message["timestamp"]):
                        messageGET = Message(
                            "Error in GET request", item[0], "TRY_OTHER_SERVER_OR_LATER", item[2])
                    else:
                        messageGET = Message(
                            "GET_OK", item[0], item[1], item[2])

            print(f"Cliente {adrs[0]}:{adrs[1]}"
                f" GET key: [{message['key']}]"
                f" ts: [{message['timestamp']}]."
                f" Meu ts é [{messageGET.timestamp}], portanto devolvendo [{messageGET.value}]")

            response = json.dumps(messageGET.__dict__)
            connection.send(response.encode())
        except socket.error as e:
            print(f"error in GET request {e}")

def main():
    # Inicialização do servidor recebendo informações ,capturadas pelo teclado, locais e do lider
    ip = input("Insert local IP: ")
    port = input("Insert local Port: ")
    ipLeader = input("Insert leader IP: ")
    portLeader = input("Insert leader Port: ")

    server = Server(ip, port, ipLeader, portLeader)
    server.serverUp()

main()


import logging
from logging.handlers import SysLogHandler
import os
import sys
import time
import re
from slackclient import SlackClient

log = logging.getLogger('starterbot')

# instantiate Slack client
slack_client = SlackClient(os.environ.get('SLACK_API_TOKEN'))
# starterbot's user ID in Slack: value is assigned after the bot starts up
starterbot_id = None

# constants
rtm_read_delay = 1 # 1 second delay between reading from RTM
command_word = "do"
mention_regex = re.compile("^<@(|[WU].+?)>(.*)")

def parse_bot_commands(slack_events):
    """
        Parses a list of events coming from the Slack RTM API to find bot commands.
        If a bot command is found, this function returns a tuple of command and channel.
        If its not found, then this function returns None, None.
    """
    for event in slack_events:
        # Print just the type for annoyingly long events
        if event['type'] in {'desktop_notification'}:
            log.debug(f'Heard event type {event["type"]}.')
        else:
            log.debug(f'Heard event {event}.')
        if event["type"] == "message" and not "subtype" in event:
            user_id, message = parse_direct_mention(event["text"])
            if user_id == starterbot_id:
                return message, event["channel"]
    return None, None

def parse_direct_mention(message_text):
    """
        Finds a direct mention (a mention that is at the beginning) in message text
        and returns the user ID which was mentioned. If there is no direct mention, returns None
    """
    matches = mention_regex.search(message_text)
    # the first group contains the username, the second group contains the remaining message
    return (matches.group(1), matches.group(2).strip()) if matches else (None, None)

def handle_command(command, channel):
    """
        Executes bot command if the command is known
    """

    def reply(response):
        # Sends the response back to the channel
        slack_client.api_call("chat.postMessage", channel=channel, text=response)

    try:
        # Separate list of numbers by spaces
        nums = command.split()
        nums = [int(num) for num in nums]
    except Exception as err:
        log.debug(f'Got error while parsing command: {err}')
        reply("I don't understand. Did you input a list of numbers?")
        return

    response = '```\n'
    w = 9  # column width in characters
    response += ' ' * w  # add empty top left corner
    # Add column headers with number of points
    for num in nums:
        response += f'{num:>{w},.0f}'
    for num_players in range(2, 10):
        response += f'\n{num_players:>{w}d}'
        for num in nums:
            per_player = (num + num_players - 1) // num_players  # ceil
            response += f'{per_player:>{w},.0f}'
    response += '\n```'
    reply(response)

if __name__ == "__main__":

    # Configure log to print messages to console
    log.setLevel(logging.DEBUG)
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    log.addHandler(handler)

    # Add log handler for Heroku -> PaperTrail
    handler = SysLogHandler()
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    log.addHandler(handler)

    log.debug('Attempting to login to Slack.')
    if slack_client.rtm_connect(with_team_state=False):
        log.debug("Starter Bot connected and running!")
        # Read bot's user ID by calling Web API method `auth.test`
        starterbot_id = slack_client.api_call("auth.test")["user_id"]
        log.debug(f'Connected with id {starterbot_id}. Entering parse loop.')
        while True:
            command, channel = parse_bot_commands(slack_client.rtm_read())
            if command:
                log.debug(f'Heard command "{command}".')
                handle_command(command, channel)
            time.sleep(rtm_read_delay)
    else:
        log.debug("Connection failed. Exception traceback printed above.")


import pygame, random, math, time, sys

# intialize the pygame
pygame.init()

SCREEN_WIDTH = 800
# Create the screen
screen  = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_WIDTH))

# Game area dimenision 600 X 600
AREA_START_POINT = 100 #  X1 =100 , Y1 = 100
AREA_END_POINT = 700  # X2 = 700 , Y2 = 700

# Caption
pygame.display.set_caption("Snake Game")

# Game variable
FPS = 10
CLOCK = pygame.time.Clock()

# Color and font
green = (0, 255, 0)
gray = (220, 220, 220)
blue = (0, 0, 255)
black = (0, 0, 0)
red = (255, 0, 0)
white = (255,255,255)
font = 'times new roman'

# Snake property
X1_SNAKE = 200
Y1_SNAKE = 200
WIDTH = 20
CHANGE_X = 0
CHANGE_y = 0
snake_List= []
Length_of_snake = 1

# score count
score = 0

# generate random snake food position
X1_FOOD = round(random.randrange(AREA_START_POINT, AREA_END_POINT-WIDTH) / 20) * 20
Y1_FOOD= round(random.randrange(AREA_START_POINT, AREA_END_POINT-WIDTH) / 20) * 20

# create a grid
def drawGrid():
    x = AREA_START_POINT
    y = AREA_START_POINT
    row  = (AREA_END_POINT -AREA_START_POINT) // 20 # area  600 x 600  row  = 600//20
    dim  = 600 # width of game area
    pygame.draw.line(screen,gray,(x ,AREA_START_POINT),(x,AREA_END_POINT))
    pygame.draw.line(screen,gray,(AREA_START_POINT,y),(AREA_END_POINT,y))
    pygame.draw.line(screen,gray,(x+dim,AREA_START_POINT),(x+dim,AREA_END_POINT))
    pygame.draw.line(screen,gray,(AREA_START_POINT,y+dim),(AREA_END_POINT,y+dim))

# draw the snake on the screen
def drawSnake(snake_List):
    for x in snake_List:
        pygame.draw.rect(screen, green, (x[0], x[1], WIDTH, WIDTH))

# create a score board
def showScore(choice, color, font, size):
    scoreFont = pygame.font.SysFont(font, size)
    scoreArea = scoreFont.render('Score : ' + str(score), True, color)
    scoreBox = scoreArea.get_rect()
    if choice == 1:
        scoreBox.midtop = (SCREEN_WIDTH/2, 14)
    else:
        scoreBox.midtop = (SCREEN_WIDTH/2, SCREEN_WIDTH/2)
    screen.blit(scoreArea, scoreBox)

# create game over
def gameOver():
    gameOverFont = pygame.font.SysFont(font, 90)
    gameOverArea = gameOverFont.render('YOU DIED', True, green)
    gameOverBox = gameOverArea.get_rect()
    gameOverBox.midtop = (SCREEN_WIDTH/2, SCREEN_WIDTH/4)
    screen.fill(black)
    screen.blit(gameOverArea, gameOverBox)
    showScore(0, red,font, 30)
    pygame.display.flip()
    time.sleep(3)
    pygame.quit()
    sys.exit()

# Game Loop
done = False
while not done:
    screen.fill((0,0,0))
    drawGrid()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        keys = pygame.key.get_pressed()
        for key in keys:
            if keys[pygame.K_LEFT]:
                CHANGE_X = -20
                CHANGE_y = 0
            elif keys[pygame.K_RIGHT]:
                CHANGE_X = 20
                CHANGE_y = 0

            elif keys[pygame.K_UP]:
                CHANGE_X = 0
                CHANGE_y = -20

            elif keys[pygame.K_DOWN]:
                CHANGE_y = 20
                CHANGE_X = 0

    X1_SNAKE += CHANGE_X
    Y1_SNAKE += CHANGE_y

    # draw the snake food on the screen
    pygame.draw.rect(screen,blue,(X1_FOOD,Y1_FOOD,WIDTH,WIDTH))
    snake_Head = []
    snake_Head.append(X1_SNAKE)
    snake_Head.append(Y1_SNAKE)
    snake_List.append(snake_Head)

    if len(snake_List) > Length_of_snake:
        del snake_List[0]

    drawSnake(snake_List)

    if X1_SNAKE == X1_FOOD and Y1_SNAKE == Y1_FOOD:
        X1_FOOD = round(random.randrange(AREA_START_POINT, AREA_END_POINT-WIDTH) / 20) * 20
        Y1_FOOD= round(random.randrange(AREA_START_POINT, AREA_END_POINT-WIDTH) / 20) * 20
        Length_of_snake += 1
        score +=1

   # Touch the border game
    if X1_SNAKE < AREA_START_POINT or X1_SNAKE > AREA_END_POINT-WIDTH:
        gameOver()
    if Y1_SNAKE < AREA_START_POINT or Y1_SNAKE > AREA_END_POINT-WIDTH:
        gameOver()

    # Touch the snake body game over
    for block in snake_List[:-1]:
        if  snake_Head[0]== block[0] and snake_Head[1] == block[1]:
            gameOver()

    # show the score on the screen
    showScore(1, white, font, 30)

    pygame.display.update()

    CLOCK.tick(FPS)


import os
import shutil
import tempfile

from maxminddb.const import MODE_AUTO, MODE_MMAP

from ichnaea.geocode import GEOCODER
from ichnaea import geoip
from ichnaea.tests import DATA_DIRECTORY

GEOIP_BAD_FILE = os.path.join(DATA_DIRECTORY, "GeoIP2-Connection-Type-Test.mmdb")
GEOIP_TEST_FILE = os.path.join(DATA_DIRECTORY, "GeoIP2-City-Test.mmdb")

class Location(object):
    def __init__(self, radius):
        self.accuracy_radius = radius

class TestGeoIP(object):
    @classmethod
    def _open_db(cls, raven, filename=GEOIP_TEST_FILE, mode=MODE_AUTO):
        return geoip.configure_geoip(filename, mode=mode, raven_client=raven)

    def test_open(self, geoip_db):
        assert isinstance(geoip_db, geoip.GeoIPWrapper)

    def test_age(self, geoip_db):
        assert isinstance(geoip_db.age, int)
        # the test file is older than 10 days, but not more than 10 years
        assert geoip_db.age > 10
        assert geoip_db.age < 3650

    def test_c_extension(self, geoip_db):
        assert geoip_db.check_extension()

    def test_c_extension_warning(self, raven):
        with self._open_db(raven, mode=MODE_MMAP) as db:
            assert not db.check_extension()
        raven.check(["RuntimeError: Maxmind C extension not installed"])

    def test_no_file(self, raven):
        with self._open_db(raven, filename="") as db:
            assert isinstance(db, geoip.GeoIPNull)
        raven.check(["OSError: No geoip filename specified."])

    def test_open_missing_file(self, raven):
        tmpdir = tempfile.mkdtemp()
        try:
            filename = os.path.join(tmpdir, "not_there")
            with self._open_db(raven, filename) as db:
                assert isinstance(db, geoip.GeoIPNull)
        finally:
            shutil.rmtree(tmpdir)
        raven.check(["FileNotFoundError"])

    def test_open_invalid_file(self, raven):
        with tempfile.NamedTemporaryFile() as temp:
            temp.write(b"Bucephalus")
            temp.seek(0)
            with self._open_db(raven, temp.name) as db:
                assert isinstance(db, geoip.GeoIPNull)
        raven.check(["InvalidDatabaseError: Error opening database file"])

    def test_open_wrong_file_type(self, raven):
        with self._open_db(raven, GEOIP_BAD_FILE) as db:
            assert isinstance(db, geoip.GeoIPNull)
        raven.check(["InvalidDatabaseError: Invalid database type"])

    def test_regions(self, geoip_db):
        loc = Location(100000.0)
        valid_regions = GEOCODER.valid_regions
        mapped_regions = set(
            [geoip.GEOIP_GENC_MAP.get(r, r) for r in geoip.REGION_SCORE.keys()]
        )
        assert mapped_regions - valid_regions == set()
        for region in mapped_regions:
            radius, region_radius = geoip_db.radius(region, loc, default=None)
            assert radius is not None
            assert region_radius is not None

class TestLookup(object):
    def test_city(self, geoip_data, geoip_db):
        london = geoip_data["London"]
        result = geoip_db.lookup(london["ip"])
        for name in ("latitude", "longitude", "radius", "region_radius"):
            assert round(london[name], 7) == result[name]
        for name in ("region_code", "region_name", "city", "score"):
            assert london[name] == result[name]

    def test_city2(self, geoip_data, geoip_db):
        london = geoip_data["London2"]
        result = geoip_db.lookup(london["ip"])
        for name in ("latitude", "longitude", "radius", "region_radius"):
            assert round(london[name], 7) == result[name]
        for name in ("region_code", "region_name", "city", "score"):
            assert london[name] == result[name]

    def test_region(self, geoip_data, geoip_db):
        bhutan = geoip_data["Bhutan"]
        result = geoip_db.lookup(bhutan["ip"])
        for name in ("latitude", "longitude", "radius", "region_radius"):
            assert round(bhutan[name], 7) == result[name]
        for name in ("region_code", "region_name", "city", "score"):
            assert bhutan[name] == result[name]

    def test_ipv6(self, geoip_db):
        result = geoip_db.lookup("2a02:ffc0::")
        assert result["region_code"] == "GI"
        assert result["region_name"] == "Gibraltar"
        assert result["radius"] == geoip_db.radius("GI", Location(100))[0]

    def test_fail(self, geoip_db):
        assert geoip_db.lookup("127.0.0.1") is None

    def test_fail_bad_ip(self, geoip_db):
        assert geoip_db.lookup("546.839.319.-1") is None

    def test_with_dummy_db(self):
        assert geoip.GeoIPNull().lookup("200") is None

class TestRadius(object):
    def test_region(self, geoip_db):
        assert geoip_db.radius("US", Location(1100))[0] > 1000000.0
        assert geoip_db.radius("XK", Location(51))[0] > 50000.0
        assert geoip_db.radius("XK", Location(11))[0] == 11000.0

    def test_subdivision(self, geoip_db):
        assert geoip_db.radius("RU", Location(2100))[0] > 2000000.0
        assert geoip_db.radius("RU", Location(2100), subs=["A"])[0] < 1500000.0
        assert geoip_db.radius("RU", Location(100), subs=["A"])[0] == 100000.0

    def test_city(self, geoip_db):
        assert geoip_db.radius("GB", Location(41), city=2643743)[0] > geoip.CITY_RADIUS
        assert geoip_db.radius("GB", Location(1), city=2643743)[0] == 1000.0
        assert (
            geoip_db.radius("RU", Location(26), subs=["A"], city=1)[0]
            == geoip.CITY_RADIUS
        )
        assert geoip_db.radius("LI", Location(26), city=1)[0] < geoip.CITY_RADIUS
        assert geoip_db.radius("US", Location(26), city=1)[0] == geoip.CITY_RADIUS

    def test_unknown(self, geoip_db):
        assert geoip_db.radius("XX", Location(5100))[0] == geoip.REGION_RADIUS
        assert geoip_db.radius("XX", Location(100))[0] == 100000.0
        assert geoip_db.radius("XX", Location(26), city=1)[0] == geoip.CITY_RADIUS
        assert geoip_db.radius("XX", Location(10), city=1)[0] == 10000.0


################################################################################################
''' Developed by Kalenia Marquez Florez
    Aix Marseille Univ, CNRS, ISM, Marseille, France
    June 2022
'''
import psutil
import logging
logging.info(psutil.virtual_memory())
# WRITE EXPORT FILE FOR EACH RUN
#90% of available meomry in MB
TOTmem=psutil.virtual_memory()[1]/1024/1024*0.9

def writeExport(outputFile_ExportAster,aster_root,outputFile_Comm,outputFile_Messages,namemess,nameexport):
    #lectura de parametros
    lines=[]
    lines=(
"""P actions make_etude
P aster_root """+aster_root+"""
P version stable
P consbtc oui
P corefilesize unlimited
P cpresok RESNOOK
P debug nodebug
P follow_output yes
P facmtps 1
P lang en
P mpi_nbcpu 1
P mpi_nbnoeud 1
P mode interactif
P memjob """+str(TOTmem*208)+"""
P memory_limit """+str(TOTmem*2)+"""
P time_limit 72000.0
P tpsjob 1201

A memjeveux """+str(TOTmem)+"""
A tpmax 72000.0
F comm """+outputFile_Comm+""" D  1
F mess """+outputFile_Messages+namemess+""".mess R  6
""").split("\n")

    try:
       f = open(outputFile_ExportAster+nameexport+'.export', 'w')
       f.write('\n'.join(lines))
       f.close()
    except:
        logging.error("Error while writing the ExportAster-File")


from bot import SlackBot
from django.core.cache import cache
from django.conf import settings
from django.http import HttpResponse, JsonResponse, HttpResponseBadRequest
from django.shortcuts import render_to_response
from django.views.decorators.http import require_POST
from image_response import ImageResponse
from slack.models import SlackUser
from urllib import urlencode
import cleverbot
import json
import random
import re
import requests

INFO_URL = "https://www.changetip.com/tip-online/slack"
UPGRADE_URL = "https://github.com/changecoin/changetip-slack"
MESSAGES = {
    "help": u"""Hi {user_name}. Here's some help.
To send a tip, mention *a person* and *an amount* like this:
`/changetip give @buddy $1`.
You can also use a moniker for the amount, like `a beer` or `2 coffees`.
Any questions? E-mail support@changetip.com
""",
    "help_webhooks": u"""Hi {user_name}. Here's some help.
To send a tip, mention *changetip*, *a person* and *an amount* like this:
`changetip: give @buddy $1`.
You can also use a moniker for the amount, like `a beer` or `2 coffees`.
Any questions? E-mail support@changetip.com
""",
    "duplicate": "That looks like a duplicate tip.",
    "greeting": u"Hi, {user_name}! {get_started}",
    "get_started": u"To send your first tip, login with your slack account on ChangeTip: {info_url}".format(info_url=INFO_URL),
    "unknown_receiver": u"@{user_name}, before they can receive your tip, ask them to type: *changetip: accept*",
    "out_for_delivery": u"The tip for {amount_display} is out for delivery. {receiver} needs to collect by connecting their ChangeTip account to slack at %s" % INFO_URL,
    "finished": u"The tip has been delivered, {amount_display} has been added to {receiver}'s ChangeTip wallet. {img_url}",
    "upgrade_to_slash_commands": u"Note: Tipping with outgoing webhooks will eventually be removed. Upgrade to our newer, better Slash commands here: {}".format(UPGRADE_URL),
}

def slack_oauth(request):
    client_id = settings.SLACK_CLIENT_ID
    client_secret = settings.SLACK_CLIENT_SECRET

    code = request.GET.get('code', None)

    if not client_id or not client_secret or not code:
        return HttpResponseBadRequest("Error, missing code or improperly configured")

    response = requests.get("https://slack.com/api/oauth.access?client_id={}&client_secret={}&code={}&{}".format(
        client_id, client_secret, code, urlencode({"redirect_uri": "https://bots.changetip.com/slack/auth"})))

    info = json.loads(response.text)
    if "access_token" in info:
        info['access_token'] = 'redacted'

    response = response.json()
    if not response['ok'] or 'access_token' not in response:
        return HttpResponseBadRequest("Error - could not obtain access token: {}".format(info))

    return render_to_response('success.html')

@require_POST
def command_webhook(request):
    """
    Handle data from a webhook
    """
    print(json.dumps(request.POST.copy(), indent=2))

    return JsonResponse({"text": "ChangeTip services have been discontinued. See https://www.reddit.com/r/changetip/comments/5dn3rc/changetip_shutting_down/ Please close your account and disconnect ChangeTip from Slack."})

    if request.POST.get("noop"):
        return JsonResponse({"text": "Hi!"})

    # Separated so we can still support the legacy webhook integration
    if 'command' in request.POST.keys():
        return slash_command(request)
    else:
        return outgoing_webhook(request)

def slash_command(request):
    if 'balance' in request.POST['command']:
        return balance(request)

    return tip(request)

def balance(request):
    if not settings.CHANGETIP_BALANCE_API_KEY:
        return JsonResponse({"text": "Sorry, I can't do that for some reason."})

    try:
        assert 3 == 'D'
        # Filler code for now while we wait for API endpoint
    except Exception:
        return JsonResponse({"text": "Sorry, I can't do that right now."})

def tip(request):
    user_name = request.POST.get("user_name")

    # TODO tagging for usernames
    # Create SlackUser. This is used for tagging
    SlackUser.objects.get_or_create(
        name=user_name,
        team_id=request.POST.get("team_id"),
        user_id=request.POST.get("user_id"),
    )

    text = request.POST.get("text", "")

    # Check for mention in the format of @userId123-_. (only grab first)
    mention_match = re.search('@([A-Za-z0-9-_.]+)', text)
    if not mention_match:
        # Do they want help?
        if "help" in text:
            return JsonResponse({"text": MESSAGES["help"].format(user_name=user_name), "response_type": "in_channel"})
        else:
            # Temporarily commenting out the following because Cleverbot now has ads
            # # Say something clever
            # response = get_clever_response(user_id, text)
            # response = append_image_response(text, response)
            # return JsonResponse({"text": response, "username": "changetip-cleverbot"})
            return JsonResponse({"text": MESSAGES["help"].format(user_name=user_name), "response_type": "in_channel"})
    receiver = mention_match.group(1)

    # Submit the tip
    team_domain = request.POST.get("team_domain")
    tip_data = {
        "sender": "%s@%s" % (user_name, team_domain),
        "receiver": "%s@%s" % (receiver, team_domain),
        "message": text,
        "context_uid": SlackBot().unique_id(request.POST.copy()),
        "meta": {}
    }
    for meta_field in ["token", "team_id", "channel_id", "channel_name", "user_id", "user_name", "command"]:
        tip_data["meta"][meta_field] = request.POST.get(meta_field)

    out = submit_tip(tip_data)

    return JsonResponse({"text": out, "response_type": "in_channel"})

def outgoing_webhook(request):
    # Do we have this user?
    user_name = request.POST.get("user_name")
    user_id = request.POST.get("user_id")
    slack_sender, created = SlackUser.objects.get_or_create(
        name=user_name,
        team_id=request.POST.get("team_id"),
        user_id=request.POST.get("user_id"),
    )

    def formatted_response(response_text):
        if random.random() < .2:
            # Every 5th message or so will encourage users to upgrade to Slash commands
            response_text += " "
            response_text += MESSAGES['upgrade_to_slash_commands']
        return JsonResponse({"text": response_text, "response_type": "in_channel"})

    if created:
        return formatted_response(MESSAGES["greeting"].format(user_name=user_name, get_started=MESSAGES["get_started"]))

    text = request.POST.get("text", "")

    # Check for mention in the format of <@$userid> (only grab first)
    mention_match = re.search('<@(U[A-Z0-9]+)>', text)
    if not mention_match:
        # Do they want help?
        if "help" in text:
            return formatted_response(MESSAGES["help_webhooks"].format(user_name=user_name))
        else:
            return formatted_response(MESSAGES["help_webhooks"].format(user_name=user_name))
            # Temporarily commenting out the following because Cleverbot now has ads
            # # Say something clever
            # response = get_clever_response(user_id, text)
            # response = append_image_response(text, response)
            # return JsonResponse({"text": response, "username": "changetip-cleverbot"})

    slack_receiver = SlackUser.objects.filter(team_id = slack_sender.team_id, user_id=mention_match.group(1)).first()
    if not slack_receiver:
        return formatted_response(MESSAGES["unknown_receiver"].format(user_name=user_name))

    # Substitute the @username back in (for each mention)
    for at_user_id in re.findall('(<@U[A-Z0-9]+>)', text):
        user_id_match = re.search('<@(U[A-Z0-9]+)>', at_user_id)
        if not user_id_match:
            continue
        user_id = user_id_match.group(1)
        if not user_id:
            continue
        slack_user = SlackUser.objects.filter(team_id = slack_sender.team_id, user_id=user_id).first()
        if not slack_user:
            continue
        text = text.replace(at_user_id, '@%s' % slack_user.name)

    # Submit the tip
    team_domain = request.POST.get("team_domain")
    tip_data = {
        "sender": "%s@%s" % (slack_sender.name, team_domain),
        "receiver": "%s@%s" % (slack_receiver.name, team_domain),
        "message": text,
        "context_uid": SlackBot().unique_id(request.POST.copy()),
        "meta": {}
    }
    for meta_field in ["token", "team_id", "channel_id", "channel_name", "user_id", "user_name", "command"]:
        tip_data["meta"][meta_field] = request.POST.get(meta_field)

    out = submit_tip(tip_data)

    return formatted_response(out)

def submit_tip(tip_data):
    """
    Sends the tip to the Changecoin API and returns an output message
    """

    text = tip_data['message']
    out = ""

    bot = SlackBot()
    response = bot.send_tip(**tip_data)

    try:
        if response.get("error_code") == "invalid_sender":
            out = MESSAGES["get_started"]
        elif response.get("error_code") == "duplicate_context_uid":
            out = MESSAGES["duplicate"]
        elif response.get("error_message"):
            if response.get("error_code") in ["tip_limit", "wallet_error", "pocket_error"]:
                out = "This tip cannot be completed"
            else:
                out = response.get("error_message")
        elif response.get("state") in ["ok", "accepted"]:
            tip = response["tip"]

            if tip["status"] == "out for delivery":
                out += MESSAGES["out_for_delivery"].format(amount_display=tip["amount_display"], receiver=tip["receiver"])
            elif tip["status"] == "finished":
                out += MESSAGES["finished"].format(amount_display=tip["amount_display"], receiver=tip["receiver"], img_url=tip['meta'].get('tip_img_url', ''))

        out = append_image_response(text, out)

        if "+debug" in text:
            out += "\n```\n%s\n```" % json.dumps(response, indent=2)

    except Exception as e:
        if "+debug" in text:
            return "output formatting error with: {}".format(e)

    return out

def get_clever_response(user_id, text):
    # Remember conversations per user
    cache_key = "clever_response:%s" % user_id
    cb = cache.get(cache_key)
    if not cb:
        cb = cleverbot.Cleverbot()
    text = re.sub('changetip', '', text, 1, re.I).strip('@: ')
    response = cb.ask(text)
    cache.set(cache_key, cb, 3600)
    return response

def append_image_response(text, response):
    image_response = ImageResponse().get_image_response(text, 1500000)

    if image_response[0]:
        response += " Plus %s #%s image: %s" % (image_response[1], image_response[0], image_response[2])
    return response

def home(request):
    return HttpResponse("OK")