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

import sys
import os
import time

import path_utils
import svn_wrapper

def is_non_generic(char_input, list_select):
    for c in list_select:
        if c == char_input:
            return False
    return True

def is_nonnumber(thechar):
    return is_non_generic(thechar, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])

def is_nonspaceortabs(thechar):
    return is_non_generic(thechar, [" ", "\t"])

def _add_to_warnings(warnings, latest_msg):
    if warnings is None:
        return latest_msg
    return "%s%s%s" % (warnings, os.linesep, latest_msg)

def has_string_in_list(the_list, the_str):
    for li in the_list:
        if the_str in li:
            return True
    return False

def extract_file_from_status_line(the_line):

    if len(the_line) < 2:
        return None

    c = 0
    while c < len(the_line):
        c += 1
        if is_nonspaceortabs(the_line[c]):
            return the_line[c:]

    return None

def status_filter_function_unversioned(the_line):
    if the_line is None:
        return None
    if len(the_line) == 0:
        return None
    if the_line[0] != "?":
        return None
    the_line = the_line[1:]

    for i in range(len(the_line)):
        if is_nonspaceortabs(the_line[i]):
            return the_line[i:]

def rev_single_entry_filter(log_entry):

    if log_entry is None:
        return None
    if len(log_entry) == 0:
        return None

    na = log_entry.find("r")
    if na == -1:
        return None
    nb = log_entry.find(" ", na)
    the_rev = log_entry[na:nb]
    return the_rev

def rev_entries_filter(log_entries_list):

    rev_list = []

    for le in log_entries_list:
        rle = rev_single_entry_filter(le)
        if rle is not None:
            rev_list.append(rle)

    return rev_list

def generic_parse(str_line, separator):
    if str_line is None:
        return None
    n = str_line.find(separator)
    if n == -1:
        return None
    return str_line[:n]

def revision_filter_function(the_output):

    find_string = "Revision: "
    n = the_output.find(find_string)
    revision_left = the_output[n + len(find_string):]
    revision = ""
    for i in range(len(revision_left)):
        if is_nonnumber(revision_left[i]):
            revision = revision_left[0:i]
            break
    return revision

def detect_separator(the_string):

    if the_string is None:
        return None
    if len(the_string) == 0:
        return None

    rep_char = the_string[0]
    rep_line = ""
    for i in range(len(the_string)):
        if is_non_generic(the_string[i], [rep_char]):
            rep_line = the_string[0:i]
            return rep_line

def get_list_unversioned(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r
    unversioned_files = [status_filter_function_unversioned(x) for x in r.split(os.linesep) if x != ""]
    unversioned_files = [path_utils.concat_path(repo, x) for x in unversioned_files if x is not None] # mvtodo: there has to be a better way to do this
    return True, unversioned_files

def get_previous_list(repo, previous_number):

    v, r = svn_wrapper.log(repo, str(previous_number))
    if not v:
        return False, r
    log_out = r

    sep_line = detect_separator(log_out)
    log_entries_pre = log_out.split(sep_line)
    log_entries = []
    for le in log_entries_pre:
        if le != "":
            log_entries.append(le)

    prev_list = rev_entries_filter(log_entries)
    return True, prev_list

def get_modified_files(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r

    mod_list = []

    for line in r.split(os.linesep):

        if len(line.strip()) == 0:
            break
        item_status = line[0]

        if item_status == "M":
            mod_file = extract_file_from_status_line(line)
            if mod_file is None:
                return False, "Unable to detect file from status line: [%s]" % line
            mod_list.append(path_utils.concat_path(repo, mod_file))

    return True, mod_list

def get_added_files(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r

    add_list = []

    for line in r.split(os.linesep):

        if len(line.strip()) == 0:
            break
        item_status = line[0]

        if item_status == "A":
            add_file = extract_file_from_status_line(line)
            if add_file is None:
                return False, "Unable to detect file from status line: [%s]" % line
            add_list.append(path_utils.concat_path(repo, add_file))

    return True, add_list

def get_head_revision(repo):

    v, r = svn_wrapper.info(repo)
    if not v:
        return False, r
    head_rev = revision_filter_function(r)
    return True, head_rev

def is_svn_repo(repo):

    if not os.path.exists(repo):
        return False, "svn_lib.is_svn_repo failed: %s does not exist." % repo

    # should ideally use "svnlook info the_path" but that wouldn't work with some repositories
    the_svn_obj = path_utils.concat_path(repo, ".svn")
    if os.path.exists(the_svn_obj) and os.path.isdir(the_svn_obj):
        return True, "svn"
    return True, False

def is_head_clear(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r
    st_items = r.split(os.linesep)

    clear_st = ["X", "I"]
    for i in st_items:
        if i == "":
            break
        st_current_item = i[0]
        if not st_current_item in clear_st:
            return True, False

    return True, True

def revert(local_repo, repo_item):
    return svn_wrapper.revert(local_repo, repo_item)

def _parse_externals_update_message(output_message):

    MATCH_PHRASE_BEGIN = "Fetching external item into '"
    MATCH_PHRASE_END = "External at revision "

    om_lines = [x for x in output_message.split(os.linesep) if len(x) > 0]
    if len(om_lines) < 1:
        return None
    om_lines = om_lines[1:] # get rid of the "Updating '.':"
    if len(om_lines) < 2:
        return None
    if not MATCH_PHRASE_BEGIN in om_lines[0]:
        return None

    messages = []
    current_external_path = None
    current_external_messages = []

    for l in om_lines:

        if MATCH_PHRASE_BEGIN in l:

            # new external
            if current_external_path is not None:
                messages.append( (current_external_path, current_external_messages.copy()) )
                current_external_messages.clear()
            current_external_path = l[len(MATCH_PHRASE_BEGIN):len(l)-2]

        elif MATCH_PHRASE_END in l:

            # last (current) external just ended
            current_external_messages.append(l)
            messages.append( (current_external_path, current_external_messages.copy()) )
            current_external_messages.clear()
            current_external_path = None

        else:

            # abnormal / warnings / error messages
            current_external_messages.append(l)

    messages.append( (current_external_path, current_external_messages) ) # append the last entry

    return messages

def _check_valid_codes(output_message, valid_codes):

    om_lines = [x for x in output_message.split(os.linesep) if len(x) > 0]
    if len(om_lines) < 1:
        return False
    last_line = om_lines[len(om_lines)-1]

    if last_line == ".":
        if len(om_lines) < 2:
            return False
        om_lines = om_lines[:len(om_lines)-1]
        last_line = om_lines[len(om_lines)-1]

    for vc in valid_codes:
        if vc in last_line:
            return True
    return False

def _update_autorepair_check_return(output_message):
    return _check_valid_codes(output_message, ["E205011", "W000104"])

def _update_and_cleanup(local_repo):

    # cleanup
    v, r = svn_wrapper.cleanup(local_repo)
    if not v:
        return False, r

    # update
    v, r = svn_wrapper.update(local_repo)
    if v:
        return True, None

    # check update's result
    if not _update_autorepair_check_return(r):
        return False, r # failed, irrecoverably. give up.

    return True, ("update_autorepair warning: update operation failed but was accepted for repairing (at %s)." % local_repo, r)

def update_autorepair(local_repo, do_recursion):

    warnings = None
    iterations = 0
    MAX_ITERATIONS = 6

    while True:

        # loop sentinel
        iterations += 1
        if iterations > MAX_ITERATIONS:
            return False, "update_autorepair: max iterations [%s] exceeded (at %s)" % (MAX_ITERATIONS, local_repo)

        v, r = _update_and_cleanup(local_repo)
        if not v:
            return False, r # failed, irrecoverably. give up.
        if r is None:
            break # both cleanup and update worked. we're done.

        # failed but its possible to attempt to autorepair it.
        warnings = _add_to_warnings(warnings, r[0])
        output_message = r[1]

        if not do_recursion:
            continue

        externals_result = _parse_externals_update_message(output_message)
        if externals_result is None:
            return False, "Unparseable output message (can't parse the status of externals): [%s]" % output_message

        # try to autorepair externals that failed
        for er in externals_result:

            external_path = er[0]
            external_messages = er[1]

            if has_string_in_list(external_messages, "W155004"):
                externals_full_path = path_utils.concat_path(local_repo, external_path)
                v, r = update_autorepair(externals_full_path, False)
                if not v:
                    return False, r
                if r is not None:
                    warnings = _add_to_warnings(warnings, r)

    return True, warnings

def _checkout_autorepair_check_return(output_message):
    return _check_valid_codes(output_message, ["E205011", "W000104"])

def checkout_with_update(remote_link, local_repo):

    warnings = None

    v, r = svn_wrapper.checkout(remote_link, local_repo)
    if not v:
        if not _checkout_autorepair_check_return(r):
            return False, r
        else:
            warnings = _add_to_warnings(warnings, "checkout_autorepair warning: checkout operation failed but was accepted for repairing (at %s)." % local_repo)

    v, r = update_autorepair(local_repo, True)
    if r is not None:
        warnings = _add_to_warnings(warnings, r)
    return v, warnings

def checkout_autoretry(feedback_object, remote_link, local_repo):

    warnings = None
    iterations = 0
    MAX_ITERATIONS = 6

    while True:

        # loop sentinel
        iterations += 1
        if iterations > MAX_ITERATIONS:
            return False, "repeated_checkout: max iterations [%s] exceeded (at %s)" % (MAX_ITERATIONS, local_repo)

        v, r = checkout_with_update(remote_link, local_repo)
        if v:
            # this iteration worked. its done
            warnings = _add_to_warnings(warnings, r)
            return True, warnings

        # failed iteration. reset and start over
        warnings = _add_to_warnings(warnings, "Iteration [%d] failed and was sleep-retried." % iterations)
        path_utils.deletefolder_ignoreerrors(local_repo)
        SLEEP_TIME = 15 # minutes
        feedback_object("Iteration number [%d] has failed. Will sleep for [%d] minutes before retrying." % (iterations, SLEEP_TIME))
        time.sleep(SLEEP_TIME * 60)
        feedback_object("Iteration number [%d] will resume now." % iterations)

def patch_as_head(repo, patch_file, override_head_check):

    if not override_head_check:
        v, r = is_head_clear(repo)
        if not v:
            return False, r
        if not r:
            return False, "Cannot patch - head is not clear"

    v, r = svn_wrapper.patch(repo, patch_file)
    if not v:
        return False, r

    return True, None
<commit_msg>svn_lib: fix missing returns<commit_after>#!/usr/bin/env python3

import sys
import os
import time

import path_utils
import svn_wrapper

def is_non_generic(char_input, list_select):
    for c in list_select:
        if c == char_input:
            return False
    return True

def is_nonnumber(thechar):
    return is_non_generic(thechar, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])

def is_nonspaceortabs(thechar):
    return is_non_generic(thechar, [" ", "\t"])

def _add_to_warnings(warnings, latest_msg):
    if warnings is None:
        return latest_msg
    return "%s%s%s" % (warnings, os.linesep, latest_msg)

def has_string_in_list(the_list, the_str):
    for li in the_list:
        if the_str in li:
            return True
    return False

def extract_file_from_status_line(the_line):

    if len(the_line) < 2:
        return None

    c = 0
    while c < len(the_line):
        c += 1
        if is_nonspaceortabs(the_line[c]):
            return the_line[c:]

    return None

def status_filter_function_unversioned(the_line):

    if the_line is None:
        return None
    if len(the_line) == 0:
        return None
    if the_line[0] != "?":
        return None
    the_line = the_line[1:]

    for i in range(len(the_line)):
        if is_nonspaceortabs(the_line[i]):
            return the_line[i:]

    return None

def rev_single_entry_filter(log_entry):

    if log_entry is None:
        return None
    if len(log_entry) == 0:
        return None

    na = log_entry.find("r")
    if na == -1:
        return None
    nb = log_entry.find(" ", na)
    the_rev = log_entry[na:nb]
    return the_rev

def rev_entries_filter(log_entries_list):

    rev_list = []

    for le in log_entries_list:
        rle = rev_single_entry_filter(le)
        if rle is not None:
            rev_list.append(rle)

    return rev_list

def generic_parse(str_line, separator):
    if str_line is None:
        return None
    n = str_line.find(separator)
    if n == -1:
        return None
    return str_line[:n]

def revision_filter_function(the_output):

    find_string = "Revision: "
    n = the_output.find(find_string)
    revision_left = the_output[n + len(find_string):]
    revision = ""
    for i in range(len(revision_left)):
        if is_nonnumber(revision_left[i]):
            revision = revision_left[0:i]
            break
    return revision

def detect_separator(the_string):

    if the_string is None:
        return None
    if len(the_string) == 0:
        return None

    rep_char = the_string[0]
    rep_line = ""
    for i in range(len(the_string)):
        if is_non_generic(the_string[i], [rep_char]):
            rep_line = the_string[0:i]
            return rep_line

    return None

def get_list_unversioned(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r
    unversioned_files = [status_filter_function_unversioned(x) for x in r.split(os.linesep) if x != ""]
    unversioned_files = [path_utils.concat_path(repo, x) for x in unversioned_files if x is not None] # mvtodo: there has to be a better way to do this
    return True, unversioned_files

def get_previous_list(repo, previous_number):

    v, r = svn_wrapper.log(repo, str(previous_number))
    if not v:
        return False, r
    log_out = r

    sep_line = detect_separator(log_out)
    log_entries_pre = log_out.split(sep_line)
    log_entries = []
    for le in log_entries_pre:
        if le != "":
            log_entries.append(le)

    prev_list = rev_entries_filter(log_entries)
    return True, prev_list

def get_modified_files(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r

    mod_list = []

    for line in r.split(os.linesep):

        if len(line.strip()) == 0:
            break
        item_status = line[0]

        if item_status == "M":
            mod_file = extract_file_from_status_line(line)
            if mod_file is None:
                return False, "Unable to detect file from status line: [%s]" % line
            mod_list.append(path_utils.concat_path(repo, mod_file))

    return True, mod_list

def get_added_files(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r

    add_list = []

    for line in r.split(os.linesep):

        if len(line.strip()) == 0:
            break
        item_status = line[0]

        if item_status == "A":
            add_file = extract_file_from_status_line(line)
            if add_file is None:
                return False, "Unable to detect file from status line: [%s]" % line
            add_list.append(path_utils.concat_path(repo, add_file))

    return True, add_list

def get_head_revision(repo):

    v, r = svn_wrapper.info(repo)
    if not v:
        return False, r
    head_rev = revision_filter_function(r)
    return True, head_rev

def is_svn_repo(repo):

    if not os.path.exists(repo):
        return False, "svn_lib.is_svn_repo failed: %s does not exist." % repo

    # should ideally use "svnlook info the_path" but that wouldn't work with some repositories
    the_svn_obj = path_utils.concat_path(repo, ".svn")
    if os.path.exists(the_svn_obj) and os.path.isdir(the_svn_obj):
        return True, "svn"
    return True, False

def is_head_clear(repo):

    v, r = svn_wrapper.status(repo)
    if not v:
        return False, r
    st_items = r.split(os.linesep)

    clear_st = ["X", "I"]
    for i in st_items:
        if i == "":
            break
        st_current_item = i[0]
        if not st_current_item in clear_st:
            return True, False

    return True, True

def revert(local_repo, repo_item):
    return svn_wrapper.revert(local_repo, repo_item)

def _parse_externals_update_message(output_message):

    MATCH_PHRASE_BEGIN = "Fetching external item into '"
    MATCH_PHRASE_END = "External at revision "

    om_lines = [x for x in output_message.split(os.linesep) if len(x) > 0]
    if len(om_lines) < 1:
        return None
    om_lines = om_lines[1:] # get rid of the "Updating '.':"
    if len(om_lines) < 2:
        return None
    if not MATCH_PHRASE_BEGIN in om_lines[0]:
        return None

    messages = []
    current_external_path = None
    current_external_messages = []

    for l in om_lines:

        if MATCH_PHRASE_BEGIN in l:

            # new external
            if current_external_path is not None:
                messages.append( (current_external_path, current_external_messages.copy()) )
                current_external_messages.clear()
            current_external_path = l[len(MATCH_PHRASE_BEGIN):len(l)-2]

        elif MATCH_PHRASE_END in l:

            # last (current) external just ended
            current_external_messages.append(l)
            messages.append( (current_external_path, current_external_messages.copy()) )
            current_external_messages.clear()
            current_external_path = None

        else:

            # abnormal / warnings / error messages
            current_external_messages.append(l)

    messages.append( (current_external_path, current_external_messages) ) # append the last entry

    return messages

def _check_valid_codes(output_message, valid_codes):

    om_lines = [x for x in output_message.split(os.linesep) if len(x) > 0]
    if len(om_lines) < 1:
        return False
    last_line = om_lines[len(om_lines)-1]

    if last_line == ".":
        if len(om_lines) < 2:
            return False
        om_lines = om_lines[:len(om_lines)-1]
        last_line = om_lines[len(om_lines)-1]

    for vc in valid_codes:
        if vc in last_line:
            return True
    return False

def _update_autorepair_check_return(output_message):
    return _check_valid_codes(output_message, ["E205011", "W000104"])

def _update_and_cleanup(local_repo):

    # cleanup
    v, r = svn_wrapper.cleanup(local_repo)
    if not v:
        return False, r

    # update
    v, r = svn_wrapper.update(local_repo)
    if v:
        return True, None

    # check update's result
    if not _update_autorepair_check_return(r):
        return False, r # failed, irrecoverably. give up.

    return True, ("update_autorepair warning: update operation failed but was accepted for repairing (at %s)." % local_repo, r)

def update_autorepair(local_repo, do_recursion):

    warnings = None
    iterations = 0
    MAX_ITERATIONS = 6

    while True:

        # loop sentinel
        iterations += 1
        if iterations > MAX_ITERATIONS:
            return False, "update_autorepair: max iterations [%s] exceeded (at %s)" % (MAX_ITERATIONS, local_repo)

        v, r = _update_and_cleanup(local_repo)
        if not v:
            return False, r # failed, irrecoverably. give up.
        if r is None:
            break # both cleanup and update worked. we're done.

        # failed but its possible to attempt to autorepair it.
        warnings = _add_to_warnings(warnings, r[0])
        output_message = r[1]

        if not do_recursion:
            continue

        externals_result = _parse_externals_update_message(output_message)
        if externals_result is None:
            return False, "Unparseable output message (can't parse the status of externals): [%s]" % output_message

        # try to autorepair externals that failed
        for er in externals_result:

            external_path = er[0]
            external_messages = er[1]

            if has_string_in_list(external_messages, "W155004"):
                externals_full_path = path_utils.concat_path(local_repo, external_path)
                v, r = update_autorepair(externals_full_path, False)
                if not v:
                    return False, r
                if r is not None:
                    warnings = _add_to_warnings(warnings, r)

    return True, warnings

def _checkout_autorepair_check_return(output_message):
    return _check_valid_codes(output_message, ["E205011", "W000104"])

def checkout_with_update(remote_link, local_repo):

    warnings = None

    v, r = svn_wrapper.checkout(remote_link, local_repo)
    if not v:
        if not _checkout_autorepair_check_return(r):
            return False, r
        else:
            warnings = _add_to_warnings(warnings, "checkout_autorepair warning: checkout operation failed but was accepted for repairing (at %s)." % local_repo)

    v, r = update_autorepair(local_repo, True)
    if r is not None:
        warnings = _add_to_warnings(warnings, r)
    return v, warnings

def checkout_autoretry(feedback_object, remote_link, local_repo):

    warnings = None
    iterations = 0
    MAX_ITERATIONS = 6

    while True:

        # loop sentinel
        iterations += 1
        if iterations > MAX_ITERATIONS:
            return False, "repeated_checkout: max iterations [%s] exceeded (at %s)" % (MAX_ITERATIONS, local_repo)

        v, r = checkout_with_update(remote_link, local_repo)
        if v:
            # this iteration worked. its done
            warnings = _add_to_warnings(warnings, r)
            return True, warnings

        # failed iteration. reset and start over
        warnings = _add_to_warnings(warnings, "Iteration [%d] failed and was sleep-retried." % iterations)
        path_utils.deletefolder_ignoreerrors(local_repo)
        SLEEP_TIME = 15 # minutes
        feedback_object("Iteration number [%d] has failed. Will sleep for [%d] minutes before retrying." % (iterations, SLEEP_TIME))
        time.sleep(SLEEP_TIME * 60)
        feedback_object("Iteration number [%d] will resume now." % iterations)

    return True, warnings

def patch_as_head(repo, patch_file, override_head_check):

    if not override_head_check:
        v, r = is_head_clear(repo)
        if not v:
            return False, r
        if not r:
            return False, "Cannot patch - head is not clear"

    v, r = svn_wrapper.patch(repo, patch_file)
    if not v:
        return False, r

    return True, None
<|endoftext|>


<commit_before>""" In this class, you will find a generic Graph super class
that is to be extended to implement undirected and directed graphs.
"""

class Graph(object):
    """
    Initializes the graph object with a list of vertices
    and edge adjacency list that consists of out going edges
    at index 0 and in going edges at index 1.
    """
    def __init__(self):
        self.vertices = set()
        self.edge_adj = []
        self.out_edges = {}
        self.in_edges = {}
        self.edge_adj.append(self.out_edges)
        self.edge_adj.append(self.in_edges)
        self.edge_count = 0
        self.vertex_count = 0

    def vertex_size(self):
        """ Returns the number of vertices in the graph. """
        return self.vertex_count

    def edge_size(self):
        """ Returns the number of edges in the graph. """
        return self.edge_count

    def get_out_edges(self):
        """ Returns the out edges of the graph. """
        return self.edge_adj[0]

    def get_in_edges(self):
        """ Returns the in edges of the graph. """
        return self.edge_adj[1]

    def get_vertices(self):
        """ Returns the vertices in the graph. """
        return self.vertices

    def get_successor(self, vertex):
        """ Returns the successors of the specified vertex v. """
        return self.get_out_edges()[vertex]

    def get_predecessor(self, vertex):
        """ Returns the predecessors of the specified vertex v. """
        return self.get_in_edges()[vertex]

    def contains(self, vertex):
        """ Returns true iff I contain the vertex. """
        return vertex in self.get_vertices()

    def contains_edge(self, u, v):
        """ Returns true iff I contain the edges
        from u to v. """
        return self.contains(u) and self.contains(v) and u in self.get_out_edges() and v in self.get_successor(u)

    def add(self, vertex):
        """ Adds the vertex to the graph and properly initializes
        the vertex in the out_edges and in_edges list for adding edges.
        """
        self.vertices.add(vertex)
        self.get_in_edges()[vertex] = []
        self.get_out_edges()[vertex] = []
        self.vertex_count += 1

    def add_edge(self, u, v):
        """ Adds the edge from edge u to v. Meant to be overriden
        by the Graph subclasses mainly undirected and directed graphs.
        """

    def remove(self, vertex):
        """ Removes the vertex from the graph and all of its adjacent
        edges whether it be in or out edges.
        """

    def removeEdge(self, u, v):
        """ Removes the edge (u, v) from the graph as specified by the
        graph type. If the graph is of the type UndirectedGraph, then the edge
        (u, v) and (v, u) should be removed from out_edges and in_edges. If the
        graph is of the type DirectedGraph, then only the edge (u, v) should be
        removed.
        """

class UndirectedGraph(Graph):
    """ Representation of an undirected graph. """

    def add_edge(self, u, v):
        if not self.contains_edge(u, v):
            self.get_predecessor(u).append(v)
            self.get_successor(u).append(v)
            self.get_predecessor(v).append(u)
            self.get_successor(v).append(u)
            self.edge_count += 1

    def remove(self, vertex):
        if self.contains(vertex):
            successor = self.get_successor(vertex)
            self.vertices.remove(vertex)
            self.out_edges.pop(vertex, None)
            self.in_edges.pop(vertex, None)
            for v in successor:
                if v != vertex:
                    self.get_successor(v).remove(vertex)
                    self.get_predecessor(v).remove(vertex)

    def removeEdge(self, u, v):
        if self.contains_edge(u, v):
            self.get_successor(u).remove(v)
            self.get_predecessor(u).remove(v)
            self.get_successor(v).remove(u)
            self.get_predecessor(v).remove(u)

class DirectedGraph(Graph):
    """ Representation of a directed graph. """

    def add_edge(self, u, v):
        if not self.contains_edge(u, v):
            self.get_successor(u).append(v)
            self.get_predecessor(v).append(u)
            self.edge_count += 1

    def remove(self, vertex):
        if self.contains(vertex):
            successor = self.get_successor(vertex)
            predecessor = self.get_predecessor(vertex)
            self.vertices.remove(vertex)
            self.out_edges.pop(vertex, None)
            self.in_edges.pop(vertex, None)
            for v in successor:
                if v != vertex:
                    self.get_predecessor(v).remove(vertex)
            for v in predecessor:
                if v != vertex:
                    self.get_successor(v).remove(vertex)

    def removeEdge(self, u, v):
        if self.contains_edge(u, v):
            self.get_successor(u).remove(v)
            self.get_predecessor(v).remove(u)
<commit_msg>Added basic outline of the WeightedGraph class.<commit_after>""" In this module, you will find a generic Graph super class
that is to be extended to implement undirected and directed graphs.
"""

class Graph(object):
    """
    Initializes the graph object with a list of vertices
    and edge adjacency list that consists of out going edges
    at index 0 and in going edges at index 1.
    """
    def __init__(self):
        self.vertices = set()
        self.edge_adj = []
        self.out_edges = {}
        self.in_edges = {}
        self.edge_adj.append(self.out_edges)
        self.edge_adj.append(self.in_edges)
        self.edge_count = 0
        self.vertex_count = 0

    def vertex_size(self):
        """ Returns the number of vertices in the graph. """
        return self.vertex_count

    def edge_size(self):
        """ Returns the number of edges in the graph. """
        return self.edge_count

    def get_out_edges(self):
        """ Returns the out edges of the graph. """
        return self.edge_adj[0]

    def get_in_edges(self):
        """ Returns the in edges of the graph. """
        return self.edge_adj[1]

    def get_vertices(self):
        """ Returns the vertices in the graph. """
        return self.vertices

    def get_successor(self, vertex):
        """ Returns the successors of the specified vertex v. """
        return self.get_out_edges()[vertex]

    def get_predecessor(self, vertex):
        """ Returns the predecessors of the specified vertex v. """
        return self.get_in_edges()[vertex]

    def contains(self, vertex):
        """ Returns true iff I contain the vertex. """
        return vertex in self.get_vertices()

    def contains_edge(self, u, v):
        """ Returns true iff I contain the edges
        from u to v. """
        return self.contains(u) and self.contains(v) and u in self.get_out_edges() and v in self.get_successor(u)

    def add(self, vertex):
        """ Adds the vertex to the graph and properly initializes
        the vertex in the out_edges and in_edges list for adding edges.
        """
        self.vertices.add(vertex)
        self.get_in_edges()[vertex] = []
        self.get_out_edges()[vertex] = []
        self.vertex_count += 1

    def add_edge(self, u, v):
        """ Adds the edge from edge u to v. Meant to be overriden
        by the Graph subclasses mainly undirected and directed graphs.
        """

    def remove(self, vertex):
        """ Removes the vertex from the graph and all of its adjacent
        edges whether it be in or out edges.
        """

    def removeEdge(self, u, v):
        """ Removes the edge (u, v) from the graph as specified by the
        graph type. If the graph is of the type UndirectedGraph, then the edge
        (u, v) and (v, u) should be removed from out_edges and in_edges. If the
        graph is of the type DirectedGraph, then only the edge (u, v) should be
        removed.
        """

class UndirectedGraph(Graph):
    """ Representation of an undirected graph. """

    def add_edge(self, u, v):
        if not self.contains_edge(u, v):
            self.get_predecessor(u).append(v)
            self.get_successor(u).append(v)
            self.get_predecessor(v).append(u)
            self.get_successor(v).append(u)
            self.edge_count += 1

    def remove(self, vertex):
        if self.contains(vertex):
            successor = self.get_successor(vertex)
            self.vertices.remove(vertex)
            self.out_edges.pop(vertex, None)
            self.in_edges.pop(vertex, None)
            for v in successor:
                if v != vertex:
                    self.get_successor(v).remove(vertex)
                    self.get_predecessor(v).remove(vertex)

    def removeEdge(self, u, v):
        if self.contains_edge(u, v):
            self.get_successor(u).remove(v)
            self.get_predecessor(u).remove(v)
            self.get_successor(v).remove(u)
            self.get_predecessor(v).remove(u)

class DirectedGraph(Graph):
    """ Representation of a directed graph. """

    def add_edge(self, u, v):
        if not self.contains_edge(u, v):
            self.get_successor(u).append(v)
            self.get_predecessor(v).append(u)
            self.edge_count += 1

    def remove(self, vertex):
        if self.contains(vertex):
            successor = self.get_successor(vertex)
            predecessor = self.get_predecessor(vertex)
            self.vertices.remove(vertex)
            self.out_edges.pop(vertex, None)
            self.in_edges.pop(vertex, None)
            for v in successor:
                if v != vertex:
                    self.get_predecessor(v).remove(vertex)
            for v in predecessor:
                if v != vertex:
                    self.get_successor(v).remove(vertex)

    def removeEdge(self, u, v):
        if self.contains_edge(u, v):
            self.get_successor(u).remove(v)
            self.get_predecessor(v).remove(u)

class WeightedGraph(object):
    """
    Initializes a weighted graph. In effect, all edges
    have a weight. If not specified, it will default to 0.
    This class can work with either directed graphs or undirected
    graphs depending on the graph given to the constructor.
    """
    def __init__(self, graph):
        self.graph = graph

    def add_edge(self, u, v, weight=0):
        """
        Adds the edge 'u:v' to the graph with the specified
        weight. If a weight is not given, then the default value
        is 0.
        """

    def remove(self, vertex):
        """
        Removes the vertex and all edges connected to the vertex
        from the graph, along with all their edge weights.
        """

    def removeEdge(self, u, v):
        """
        Removes the edge 'u:v' from the graph. Removes the edge weight from
        self as well.
        """

    def set_weight(self, u, v, weight):
        """
        Sets the weight of the edge 'u:v' in graph to the specified weight.
        """
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import with_statement

import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

import unittest
from decimal import Decimal
import flask
from datetime import datetime
import flask_babel as babel
from flask_babel import gettext, ngettext, lazy_gettext, get_translations
from babel.support import NullTranslations
from flask_babel._compat import text_type

class IntegrationTestCase(unittest.TestCase):
    def test_no_request_context(self):
        b = babel.Babel()
        app = flask.Flask(__name__)
        b.init_app(app)

        with app.app_context():
            assert isinstance(get_translations(), NullTranslations)

    def test_multiple_directories(self):
        """
        Ensure we can load translations from multiple directories.
        """
        b = babel.Babel()
        app = flask.Flask(__name__)

        app.config.update({
            'BABEL_TRANSLATION_DIRECTORIES': ';'.join((
                'translations',
                'renamed_translations'
            )),
            'BABEL_DEFAULT_LOCALE': 'de_DE'
        })

        b.init_app(app)

        with app.test_request_context():
            translations = b.list_translations()

            assert(len(translations) == 2)
            assert(str(translations[0]) == 'de')
            assert(str(translations[1]) == 'de')

            assert gettext(
                u'Hello %(name)s!',
                name='Peter'
            ) == 'Hallo Peter!'

    def test_lazy_old_style_formatting(self):
        lazy_string = lazy_gettext(u'Hello %(name)s')
        assert lazy_string % {u'name': u'test'} == u'Hello test'

        lazy_string = lazy_gettext(u'test')
        assert u'Hello %s' % lazy_string == u'Hello test'

class DateFormattingTestCase(unittest.TestCase):

    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        d = datetime(2010, 4, 12, 13, 46)

        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '1:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
            assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '3:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE'
            assert babel.format_datetime(d, 'long') == \
                '12. April 2010 um 15:46:00 MESZ'

    def test_init_app(self):
        b = babel.Babel()
        app = flask.Flask(__name__)
        b.init_app(app)
        d = datetime(2010, 4, 12, 13, 46)

        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '1:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
            assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '3:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE'
            assert babel.format_datetime(d, 'long') == \
                '12. April 2010 um 15:46:00 MESZ'

    def test_custom_formats(self):
        app = flask.Flask(__name__)
        app.config.update(
            BABEL_DEFAULT_LOCALE='en_US',
            BABEL_DEFAULT_TIMEZONE='Pacific/Johnston'
        )
        b = babel.Babel(app)
        b.date_formats['datetime'] = 'long'
        b.date_formats['datetime.long'] = 'MMMM d, yyyy h:mm:ss a'
        d = datetime(2010, 4, 12, 13, 46)

        with app.test_request_context():
            assert babel.format_datetime(d) == 'April 12, 2010 3:46:00 AM'

    def test_custom_locale_selector(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app)
        d = datetime(2010, 4, 12, 13, 46)

        the_timezone = 'UTC'
        the_locale = 'en_US'

        @b.localeselector
        def select_locale():
            return the_locale

        @b.timezoneselector
        def select_timezone():
            return the_timezone

        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'

        the_locale = 'de_DE'
        the_timezone = 'Europe/Vienna'

        with app.test_request_context():
            assert babel.format_datetime(d) == '12.04.2010, 15:46:00'

    def test_refreshing(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        d = datetime(2010, 4, 12, 13, 46)
        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'
            app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
            babel.refresh()
            assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'

    def test_force_locale(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app)

        @b.localeselector
        def select_locale():
            return 'de_DE'

        with app.test_request_context():
            assert str(babel.get_locale()) == 'de_DE'
            with babel.force_locale('en_US'):
                assert str(babel.get_locale()) == 'en_US'
            assert str(babel.get_locale()) == 'de_DE'

class NumberFormattingTestCase(unittest.TestCase):

    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        n = 1099

        with app.test_request_context():
            assert babel.format_number(n) == u'1,099'
            assert babel.format_decimal(Decimal('1010.99')) == u'1,010.99'
            assert babel.format_currency(n, 'USD') == '$1,099.00'
            assert babel.format_percent(0.19) == '19%'
            assert babel.format_scientific(10000) == u'1E4'

class GettextTestCase(unittest.TestCase):

    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app, default_locale='de_DE')

        with app.test_request_context():
            assert gettext(u'Hello %(name)s!', name='Peter') == 'Hallo Peter!'
            assert ngettext(u'%(num)s Apple', u'%(num)s Apples', 3) == \
                u'3 Äpfel'
            assert ngettext(u'%(num)s Apple', u'%(num)s Apples', 1) == \
                u'1 Apfel'

    def test_template_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app, default_locale='de_DE')

        t = lambda x: flask.render_template_string('{{ %s }}' % x)

        with app.test_request_context():
            assert t("gettext('Hello %(name)s!', name='Peter')") == \
                u'Hallo Peter!'
            assert t("ngettext('%(num)s Apple', '%(num)s Apples', 3)") == \
                u'3 Äpfel'
            assert t("ngettext('%(num)s Apple', '%(num)s Apples', 1)") == \
                u'1 Apfel'
            assert flask.render_template_string('''
                {% trans %}Hello {{ name }}!{% endtrans %}
            ''', name='Peter').strip() == 'Hallo Peter!'
            assert flask.render_template_string('''
                {% trans num=3 %}{{ num }} Apple
                {%- pluralize %}{{ num }} Apples{% endtrans %}
            ''', name='Peter').strip() == u'3 Äpfel'

    def test_lazy_gettext(self):
        app = flask.Flask(__name__)
        babel.Babel(app, default_locale='de_DE')
        yes = lazy_gettext(u'Yes')
        with app.test_request_context():
            assert text_type(yes) == 'Ja'
            assert yes.__html__() == 'Ja'
        app.config['BABEL_DEFAULT_LOCALE'] = 'en_US'
        with app.test_request_context():
            assert text_type(yes) == 'Yes'
            assert yes.__html__() == 'Yes'

    def test_list_translations(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app, default_locale='de_DE')
        translations = b.list_translations()
        assert len(translations) == 1
        assert str(translations[0]) == 'de'

    def test_no_formatting(self):
        """
        Ensure we don't format strings unless a variable is passed.
        """
        app = flask.Flask(__name__)
        babel.Babel(app)

        with app.test_request_context():
            assert gettext(u'Test %s') == u'Test %s'
            assert gettext(u'Test %(name)s', name=u'test') == u'Test test'
            assert gettext(u'Test %s') % 'test' == u'Test test'

if __name__ == '__main__':
    unittest.main()
<commit_msg>Add test for pickling & unpickling lazy strings<commit_after># -*- coding: utf-8 -*-
from __future__ import with_statement

import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

import pickle

import unittest
from decimal import Decimal
import flask
from datetime import datetime
import flask_babel as babel
from flask_babel import gettext, ngettext, lazy_gettext, get_translations
from babel.support import NullTranslations
from flask_babel._compat import text_type

class IntegrationTestCase(unittest.TestCase):
    def test_no_request_context(self):
        b = babel.Babel()
        app = flask.Flask(__name__)
        b.init_app(app)

        with app.app_context():
            assert isinstance(get_translations(), NullTranslations)

    def test_multiple_directories(self):
        """
        Ensure we can load translations from multiple directories.
        """
        b = babel.Babel()
        app = flask.Flask(__name__)

        app.config.update({
            'BABEL_TRANSLATION_DIRECTORIES': ';'.join((
                'translations',
                'renamed_translations'
            )),
            'BABEL_DEFAULT_LOCALE': 'de_DE'
        })

        b.init_app(app)

        with app.test_request_context():
            translations = b.list_translations()

            assert(len(translations) == 2)
            assert(str(translations[0]) == 'de')
            assert(str(translations[1]) == 'de')

            assert gettext(
                u'Hello %(name)s!',
                name='Peter'
            ) == 'Hallo Peter!'

    def test_lazy_old_style_formatting(self):
        lazy_string = lazy_gettext(u'Hello %(name)s')
        assert lazy_string % {u'name': u'test'} == u'Hello test'

        lazy_string = lazy_gettext(u'test')
        assert u'Hello %s' % lazy_string == u'Hello test'

    def test_lazy_pickling(self):
        lazy_string = lazy_gettext(u'Foo')
        pickled = pickle.dumps(lazy_string)
        unpickled = pickle.loads(pickled)

        assert unpickled == lazy_string

class DateFormattingTestCase(unittest.TestCase):

    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        d = datetime(2010, 4, 12, 13, 46)

        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '1:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
            assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '3:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE'
            assert babel.format_datetime(d, 'long') == \
                '12. April 2010 um 15:46:00 MESZ'

    def test_init_app(self):
        b = babel.Babel()
        app = flask.Flask(__name__)
        b.init_app(app)
        d = datetime(2010, 4, 12, 13, 46)

        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '1:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
            assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'
            assert babel.format_date(d) == 'Apr 12, 2010'
            assert babel.format_time(d) == '3:46:00 PM'

        with app.test_request_context():
            app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE'
            assert babel.format_datetime(d, 'long') == \
                '12. April 2010 um 15:46:00 MESZ'

    def test_custom_formats(self):
        app = flask.Flask(__name__)
        app.config.update(
            BABEL_DEFAULT_LOCALE='en_US',
            BABEL_DEFAULT_TIMEZONE='Pacific/Johnston'
        )
        b = babel.Babel(app)
        b.date_formats['datetime'] = 'long'
        b.date_formats['datetime.long'] = 'MMMM d, yyyy h:mm:ss a'
        d = datetime(2010, 4, 12, 13, 46)

        with app.test_request_context():
            assert babel.format_datetime(d) == 'April 12, 2010 3:46:00 AM'

    def test_custom_locale_selector(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app)
        d = datetime(2010, 4, 12, 13, 46)

        the_timezone = 'UTC'
        the_locale = 'en_US'

        @b.localeselector
        def select_locale():
            return the_locale

        @b.timezoneselector
        def select_timezone():
            return the_timezone

        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'

        the_locale = 'de_DE'
        the_timezone = 'Europe/Vienna'

        with app.test_request_context():
            assert babel.format_datetime(d) == '12.04.2010, 15:46:00'

    def test_refreshing(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        d = datetime(2010, 4, 12, 13, 46)
        with app.test_request_context():
            assert babel.format_datetime(d) == 'Apr 12, 2010, 1:46:00 PM'
            app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
            babel.refresh()
            assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'

    def test_force_locale(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app)

        @b.localeselector
        def select_locale():
            return 'de_DE'

        with app.test_request_context():
            assert str(babel.get_locale()) == 'de_DE'
            with babel.force_locale('en_US'):
                assert str(babel.get_locale()) == 'en_US'
            assert str(babel.get_locale()) == 'de_DE'

class NumberFormattingTestCase(unittest.TestCase):

    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        n = 1099

        with app.test_request_context():
            assert babel.format_number(n) == u'1,099'
            assert babel.format_decimal(Decimal('1010.99')) == u'1,010.99'
            assert babel.format_currency(n, 'USD') == '$1,099.00'
            assert babel.format_percent(0.19) == '19%'
            assert babel.format_scientific(10000) == u'1E4'

class GettextTestCase(unittest.TestCase):

    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app, default_locale='de_DE')

        with app.test_request_context():
            assert gettext(u'Hello %(name)s!', name='Peter') == 'Hallo Peter!'
            assert ngettext(u'%(num)s Apple', u'%(num)s Apples', 3) == \
                u'3 Äpfel'
            assert ngettext(u'%(num)s Apple', u'%(num)s Apples', 1) == \
                u'1 Apfel'

    def test_template_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app, default_locale='de_DE')

        t = lambda x: flask.render_template_string('{{ %s }}' % x)

        with app.test_request_context():
            assert t("gettext('Hello %(name)s!', name='Peter')") == \
                u'Hallo Peter!'
            assert t("ngettext('%(num)s Apple', '%(num)s Apples', 3)") == \
                u'3 Äpfel'
            assert t("ngettext('%(num)s Apple', '%(num)s Apples', 1)") == \
                u'1 Apfel'
            assert flask.render_template_string('''
                {% trans %}Hello {{ name }}!{% endtrans %}
            ''', name='Peter').strip() == 'Hallo Peter!'
            assert flask.render_template_string('''
                {% trans num=3 %}{{ num }} Apple
                {%- pluralize %}{{ num }} Apples{% endtrans %}
            ''', name='Peter').strip() == u'3 Äpfel'

    def test_lazy_gettext(self):
        app = flask.Flask(__name__)
        babel.Babel(app, default_locale='de_DE')
        yes = lazy_gettext(u'Yes')
        with app.test_request_context():
            assert text_type(yes) == 'Ja'
            assert yes.__html__() == 'Ja'
        app.config['BABEL_DEFAULT_LOCALE'] = 'en_US'
        with app.test_request_context():
            assert text_type(yes) == 'Yes'
            assert yes.__html__() == 'Yes'

    def test_list_translations(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app, default_locale='de_DE')
        translations = b.list_translations()
        assert len(translations) == 1
        assert str(translations[0]) == 'de'

    def test_no_formatting(self):
        """
        Ensure we don't format strings unless a variable is passed.
        """
        app = flask.Flask(__name__)
        babel.Babel(app)

        with app.test_request_context():
            assert gettext(u'Test %s') == u'Test %s'
            assert gettext(u'Test %(name)s', name=u'test') == u'Test test'
            assert gettext(u'Test %s') % 'test' == u'Test test'

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


<commit_before>import discord
from discord.ext import commands
from utils import checks
import datetime

def time():
    return datetime.datetime.now().strftime("[%b/%d/%Y %H:%M:%S]")

class Config:
    def __init__(self, bot):
        self.bot = bot

    @commands.group(name="prefix", invoke_without_command=True)
    async def _prefix(self, ctx):
        """Show's prefix"""
        server = await self.bot.get_server_data(ctx.guild.id)
        await ctx.send("The prefix for the bot on this server is: `{}`\n"
                       "You can set a new one with `{}prefix set 'new_prefix'`".format(server["prefix"], server["prefix"]))
        self.bot.cmd_log(ctx, "Prefix check")

    @prefix.command()
    @checks.perms_manage_guild()
    async def set(self, ctx, *, prefix: str):
        """Updates the bot's prefix"""
        server = await self.bot.get_server_data(ctx.guild.id)
        server["prefix"] = prefix
        await self.bot.update_prefix_cache(ctx.guild.id, prefix)
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("Updated bot prefix to: {}".format(server["prefix"]))
        self.bot.cmd_log(ctx, "Prefix updated to {}".format(prefix))

    @commands.group(invoke_without_command=True)
    async def logging(self, ctx):
        """Shows status of server logging"""
        server = await self.bot.get_server_data(ctx.guild.id)
        if server["loggingOn"] is False:
            await ctx.send("`Logging for this server is turned off`")
        else:
            print(server["loggingChannel"])
            channel = ctx.guild.get_channel(int(server["loggingChannel"]))
            await ctx.send("`Logging for this server is turned on in channel #{}`".format(channel))
        self.bot.cmd_log(ctx, "Logging check")

    @logging.command()
    @checks.perms_manage_guild()
    async def enable(self, ctx):
        server = await self.bot.get_server_data(ctx.guild.id)
        if server["loggingChannel"] == "":
            channel = ctx.channel.id
        server["loggingOn"] = True
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("`Logging has been enabled`")
        self.bot.cmd_log(ctx, "Server logging enabled")

    @logging.command()
    @checks.perms_manage_guild()
    async def disable(self, ctx):
        server = await self.bot.get_server_data(ctx.guild.id)
        server["loggingOn"] = False
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("`Logging has been disabled`")
        self.bot.cmd_log(ctx, "Server logging disabled")

    @logging.command()
    @checks.perms_manage_guild()
    async def set(self, ctx):
        server = await self.bot.get_server_data(ctx.guild.id)
        server["loggingChannel"] = ctx.channel.id
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("`Logging channel has been set to #{}`".format(ctx.channel))

    async def on_member_join(self, member):
        server = await self.bot.get_server_data(member.guild.id)
        if server["loggingOn"] is True:
            channel = member.guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** joined {}".format(time(), member, member.guild))

    async def on_member_remove(self, member):
        server = await self.bot.get_server_data(member.guild.id)
        if server["loggingOn"] is True:
            channel = member.guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** left {}".format(time(), member, member.guild))

    async def on_member_ban(self, member):
        server = await self.bot.get_server_data(member.guild.id)
        if server["loggingOn"] is True:
            channel = member.guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** was banned from {}".format(time(), member, member.guild))

    async def on_member_unban(self, guild, user):
        server = await self.bot.get_server_data(guild.id)
        if server["loggingOn"] is True:
            channel = guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** was unbanned from {}".format(time(), user, guild))

def setup(bot):
    bot.add_cog(Config(bot))
<commit_msg>I'm dumb lol<commit_after>import discord
from discord.ext import commands
from utils import checks
import datetime

def time():
    return datetime.datetime.now().strftime("[%b/%d/%Y %H:%M:%S]")

class Config:
    def __init__(self, bot):
        self.bot = bot

    @commands.group(invoke_without_command=True)
    async def prefix(self, ctx):
        """Show's prefix"""
        server = await self.bot.get_server_data(ctx.guild.id)
        await ctx.send("The prefix for the bot on this server is: `{}`\n"
                       "You can set a new one with `{}prefix set 'new_prefix'`".format(server["prefix"], server["prefix"]))
        self.bot.cmd_log(ctx, "Prefix check")

    @prefix.command()
    @checks.perms_manage_guild()
    async def set(self, ctx, *, new_prefix: str):
        """Updates the bot's prefix"""
        server = await self.bot.get_server_data(ctx.guild.id)
        server["prefix"] = new_prefix
        await self.bot.update_prefix_cache(ctx.guild.id, new_prefix)
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("Updated bot prefix to: {}".format(server["prefix"]))
        self.bot.cmd_log(ctx, "Prefix updated to {}".format(new_prefix))

    @commands.group(invoke_without_command=True)
    async def logging(self, ctx):
        """Shows status of server logging"""
        server = await self.bot.get_server_data(ctx.guild.id)
        if server["loggingOn"] is False:
            await ctx.send("`Logging for this server is turned off`")
        else:
            print(server["loggingChannel"])
            channel = ctx.guild.get_channel(int(server["loggingChannel"]))
            await ctx.send("`Logging for this server is turned on in channel #{}`".format(channel))
        self.bot.cmd_log(ctx, "Logging check")

    @logging.command()
    @checks.perms_manage_guild()
    async def enable(self, ctx):
        server = await self.bot.get_server_data(ctx.guild.id)
        if server["loggingChannel"] == "":
            channel = ctx.channel.id
        server["loggingOn"] = True
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("`Logging has been enabled`")
        self.bot.cmd_log(ctx, "Server logging enabled")

    @logging.command()
    @checks.perms_manage_guild()
    async def disable(self, ctx):
        server = await self.bot.get_server_data(ctx.guild.id)
        server["loggingOn"] = False
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("`Logging has been disabled`")
        self.bot.cmd_log(ctx, "Server logging disabled")

    @logging.command()
    @checks.perms_manage_guild()
    async def set(self, ctx):
        server = await self.bot.get_server_data(ctx.guild.id)
        server["loggingChannel"] = ctx.channel.id
        await self.bot.update_server_data(ctx.guild.id, server)
        await ctx.send("`Logging channel has been set to #{}`".format(ctx.channel))

    async def on_member_join(self, member):
        server = await self.bot.get_server_data(member.guild.id)
        if server["loggingOn"] is True:
            channel = member.guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** joined {}".format(time(), member, member.guild))

    async def on_member_remove(self, member):
        server = await self.bot.get_server_data(member.guild.id)
        if server["loggingOn"] is True:
            channel = member.guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** left {}".format(time(), member, member.guild))

    async def on_member_ban(self, member):
        server = await self.bot.get_server_data(member.guild.id)
        if server["loggingOn"] is True:
            channel = member.guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** was banned from {}".format(time(), member, member.guild))

    async def on_member_unban(self, guild, user):
        server = await self.bot.get_server_data(guild.id)
        if server["loggingOn"] is True:
            channel = guild.get_channel(server["loggingChannel"])
            await channel.send("`{}` **{}** was unbanned from {}".format(time(), user, guild))

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


<commit_before>from tapiriik.sync import Sync
from tapiriik.sync.requests_lib import patch_requests_with_default_timeout
from tapiriik.database import db
import time
import datetime
import os
import signal
import sys
import subprocess
import socket

Run = True

oldCwd = os.getcwd()
WorkerVersion = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=os.path.dirname(__file__)).communicate()[0].strip()
os.chdir(oldCwd)

def sync_interrupt(signal, frame):
    global Run
    Run = False

signal.signal(signal.SIGINT, sync_interrupt)

def sync_heartbeat():
	db.sync_workers.update({"Process": os.getpid()}, {"$set": {"Heartbeat": datetime.datetime.utcnow()}})

print("Sync worker starting at " + datetime.datetime.now().ctime() + " pid " + str(os.getpid()))
db.sync_workers.update({"Process": os.getpid()}, {"Process": os.getpid(), "Heartbeat": datetime.datetime.utcnow(), "Version": WorkerVersion, "Host": socket.gethostname()}, upsert=True)
sys.stdout.flush()

patch_requests_with_default_timeout(timeout=60)

while Run:
    Sync.PerformGlobalSync(heartbeat_callback=sync_heartbeat)

    time.sleep(1)
    sync_heartbeat()

print("Sync worker shutting down cleanly")
db.sync_workers.remove({"Process": os.getpid()})
sys.stdout.flush()
<commit_msg>Track sync worker uptime.<commit_after>from tapiriik.sync import Sync
from tapiriik.sync.requests_lib import patch_requests_with_default_timeout
from tapiriik.database import db
import time
import datetime
import os
import signal
import sys
import subprocess
import socket

Run = True

oldCwd = os.getcwd()
WorkerVersion = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=os.path.dirname(__file__)).communicate()[0].strip()
os.chdir(oldCwd)

def sync_interrupt(signal, frame):
    global Run
    Run = False

signal.signal(signal.SIGINT, sync_interrupt)

def sync_heartbeat():
	db.sync_workers.update({"Process": os.getpid()}, {"$set": {"Heartbeat": datetime.datetime.utcnow()}})

print("Sync worker starting at " + datetime.datetime.now().ctime() + " pid " + str(os.getpid()))
db.sync_workers.update({"Process": os.getpid()}, {"Process": os.getpid(), "Heartbeat": datetime.datetime.utcnow(), "Startup":  datetime.datetime.utcnow(),  "Version": WorkerVersion, "Host": socket.gethostname()}, upsert=True)
sys.stdout.flush()

patch_requests_with_default_timeout(timeout=60)

while Run:
    Sync.PerformGlobalSync(heartbeat_callback=sync_heartbeat)

    time.sleep(1)
    sync_heartbeat()

print("Sync worker shutting down cleanly")
db.sync_workers.remove({"Process": os.getpid()})
sys.stdout.flush()
<|endoftext|>


<commit_before>import os
import pytest
import tinymongo as tm

# setup the db
db_name = os.path.abspath('./test_db')
try:
    for f in os.listdir(os.path.join('.', db_name)):
        print('removing file ', f)
        os.remove(os.path.join(db_name, f))
except FileNotFoundError:
    pass

try:
    if len(os.listdir(db_name)) == 0:
        os.rmdir(db_name)
except FileNotFoundError:
    pass

tiny_client = tm.TinyMongoClient(db_name)
tiny_database = tiny_client.tinyDatabase
tiny_collection = tiny_database.tinyCollection

@pytest.fixture()
def collection(request):
    # setup the db, clear if necessary
    # todo: the 'drop()' function from pymongo should work in future revisions
    tiny_collection.delete_many({})    # should delete all records in the collection

    # insert 100 integers, strings, floats, booleans, arrays, and objects
    for num in range(100):
        new_obj = {}
        new_obj['count'] = num
        new_obj['countStr'] = str(num)
        new_obj['countFloat'] = float(num) + 0.1
        new_obj['countBool'] = True if num & 1 else False
        new_obj['countArray'] = [num + i for i in range(5)]
        # todo: add object to the db

        tiny_collection.insert_one(new_obj)

    def fin():
        tiny_client.close()

    request.addfinalizer(finalizer=fin)

    return tiny_collection

def test_initialize_db(collection):
    """
    Ensure that the initial db is of the correct size

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({})

    count = 0
    for doc in c:
        count += 1

    assert count == 100
    assert c.count() == 100

def test_greater_than(collection):
    """
    Testing the greater than operator

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$gte': 50}})

    assert c.count() == 50

def test_sort_wrong_input_type(collection):
    """
    Testing the sort method in the positive direction

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find()  # find all
    with pytest.raises(ValueError):
        c.sort('count')

def test_sort_positive(collection):
    """
    Testing the sort method in the positive direction

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find()  # find all
    c.sort({'count': 1})
    assert c[0]['count'] == 0

def test_sort_negative(collection):
    """
    Testing the sort method in the positive direction

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find()  # find all
    c.sort({'count': -1})
    assert c[0]['count'] == 99

def test_empty_find(collection):
    """
    Tests 'find' method when empty
    :param collection:
    :return:
    """
    c = collection.find()
    assert c.count() == 100

def test_find_one(collection):
    """
    Testing the retrieval of an item using the 'find_one' method

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find_one({'count': 3})

    assert c['countStr'] == '3'

def test_gte_lt(collection):
    """
    Testing the >= and < queries
    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$gte': 50, '$lt': 51}})
    assert c.count() == 1
    assert c[0]['countStr'] == '50'

def test_gt_lte(collection):
    """
    Testing the < and >= queries
    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$gt': 50, '$lte': 51}})
    assert c.count() == 1
    assert c[0]['countStr'] == '51'

def test_ne(collection):
    """
    Testing the < and >= queries
    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$ne': 50}})
    assert c.count() == 99

    for item in c:
        assert item['countStr'] != '50'

def test_update_one_set(collection):
    """
    Testing the update_one method of the collection

    :param collection: pytest fixture that returns the collection
    :return:
    """
    cu = collection.update_one({'count': 3}, {'$set': {'countStr': 'three'}})
    assert cu is True

    c = collection.find_one({'count': 3})
    assert c['countStr'] == 'three'

def test_delete_one(collection):
    """
    Testing the 'delete_one' method

    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.delete_one({'count': 3})

    c = collection.find({})

    assert c.count() == 99

def test_delete_all(collection):
    """
    Testing the 'delete_many' method to remove all

    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.delete_many({})

    c = collection.find({})

    assert c.count() == 0

def test_delete_many(collection):
    """
    Testing the 'delete_many' method to remove some items

    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.delete_many({'count': {'$gte': 50}})

    c = collection.find({})

    assert c.count() == 50

def test_insert_one(collection):
    """
    Testing the 'insert_one' method
    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.insert_one({'my_object_name': 'my object value', 'count': 1000})

    c = collection.find({})

    assert c.count() == 101
    assert collection.find({'my_object_name': 'my object value'})['count'] == 1000

def test_insert_many(collection):
    """
    Testing the 'insert_many' method
    :param collection: pytest fixture that returns the collection
    :return:
    """
    items = []
    for i in range(10):
        value = 1000 + i
        items.append({'count': value, 'countStr': str(value)})

    collection.insert_many(items)

    c = collection.find({})

    assert c.count() == 110

def test_insert_one_with_list_input(collection):
    with pytest.raises(ValueError):
        collection.insert_one([{'my_object_name': 'my object value', 'count': 1000}])

<commit_msg>Slight elaboration on sort tests<commit_after>import os
import pytest
import tinymongo as tm

# setup the db
db_name = os.path.abspath('./test_db')
try:
    for f in os.listdir(os.path.join('.', db_name)):
        print('removing file ', f)
        os.remove(os.path.join(db_name, f))
except FileNotFoundError:
    pass

try:
    if len(os.listdir(db_name)) == 0:
        os.rmdir(db_name)
except FileNotFoundError:
    pass

tiny_client = tm.TinyMongoClient(db_name)
tiny_database = tiny_client.tinyDatabase
tiny_collection = tiny_database.tinyCollection

@pytest.fixture()
def collection(request):
    # setup the db, clear if necessary
    # todo: the 'drop()' function from pymongo should work in future revisions
    tiny_collection.delete_many({})    # should delete all records in the collection

    # insert 100 integers, strings, floats, booleans, arrays, and objects
    for num in range(100):
        new_obj = {}
        new_obj['count'] = num
        new_obj['countStr'] = str(num)
        new_obj['countFloat'] = float(num) + 0.1
        new_obj['countBool'] = True if num & 1 else False
        new_obj['countArray'] = [num + i for i in range(5)]
        # todo: add object to the db

        tiny_collection.insert_one(new_obj)

    def fin():
        tiny_client.close()

    request.addfinalizer(finalizer=fin)

    return tiny_collection

def test_initialize_db(collection):
    """
    Ensure that the initial db is of the correct size

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({})

    count = 0
    for doc in c:
        count += 1

    assert count == 100
    assert c.count() == 100

def test_greater_than(collection):
    """
    Testing the greater than operator

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$gte': 50}})

    assert c.count() == 50

def test_sort_wrong_input_type(collection):
    """
    Testing the sort method in the positive direction

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find()  # find all
    with pytest.raises(ValueError):
        c.sort('count')

def test_sort_positive(collection):
    """
    Testing the sort method in the positive direction

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find()  # find all
    c.sort({'count': 1})
    assert c[0]['count'] == 0
    assert c[1]['count'] == 1

def test_sort_negative(collection):
    """
    Testing the sort method in the positive direction

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find()  # find all
    c.sort({'count': -1})
    assert c[0]['count'] == 99
    assert c[1]['count'] == 98

def test_empty_find(collection):
    """
    Tests 'find' method when empty
    :param collection:
    :return:
    """
    c = collection.find()
    assert c.count() == 100

def test_find_one(collection):
    """
    Testing the retrieval of an item using the 'find_one' method

    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find_one({'count': 3})

    assert c['countStr'] == '3'

def test_gte_lt(collection):
    """
    Testing the >= and < queries
    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$gte': 50, '$lt': 51}})
    assert c.count() == 1
    assert c[0]['countStr'] == '50'

def test_gt_lte(collection):
    """
    Testing the < and >= queries
    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$gt': 50, '$lte': 51}})
    assert c.count() == 1
    assert c[0]['countStr'] == '51'

def test_ne(collection):
    """
    Testing the < and >= queries
    :param collection: pytest fixture that returns the collection
    :return:
    """
    c = collection.find({'count': {'$ne': 50}})
    assert c.count() == 99

    for item in c:
        assert item['countStr'] != '50'

def test_update_one_set(collection):
    """
    Testing the update_one method of the collection

    :param collection: pytest fixture that returns the collection
    :return:
    """
    cu = collection.update_one({'count': 3}, {'$set': {'countStr': 'three'}})
    assert cu is True

    c = collection.find_one({'count': 3})
    assert c['countStr'] == 'three'

def test_delete_one(collection):
    """
    Testing the 'delete_one' method

    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.delete_one({'count': 3})

    c = collection.find({})

    assert c.count() == 99

def test_delete_all(collection):
    """
    Testing the 'delete_many' method to remove all

    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.delete_many({})

    c = collection.find({})

    assert c.count() == 0

def test_delete_many(collection):
    """
    Testing the 'delete_many' method to remove some items

    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.delete_many({'count': {'$gte': 50}})

    c = collection.find({})

    assert c.count() == 50

def test_insert_one(collection):
    """
    Testing the 'insert_one' method
    :param collection: pytest fixture that returns the collection
    :return:
    """
    collection.insert_one({'my_object_name': 'my object value', 'count': 1000})

    c = collection.find({})

    assert c.count() == 101
    assert collection.find({'my_object_name': 'my object value'})['count'] == 1000

def test_insert_many(collection):
    """
    Testing the 'insert_many' method
    :param collection: pytest fixture that returns the collection
    :return:
    """
    items = []
    for i in range(10):
        value = 1000 + i
        items.append({'count': value, 'countStr': str(value)})

    collection.insert_many(items)

    c = collection.find({})

    assert c.count() == 110

def test_insert_one_with_list_input(collection):
    with pytest.raises(ValueError):
        collection.insert_one([{'my_object_name': 'my object value', 'count': 1000}])

<|endoftext|>


<commit_before># coding: utf-8
# Created on: 13.09.2016
# Author: Roman Miroshnychenko aka Roman V.M. (romanvm@yandex.ua)
#
# Copyright (c) 2016 Roman Miroshnychenko
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import sys
import time
from unittest import TestCase, main
from subprocess import Popen
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

cwd = os.path.dirname(os.path.abspath(__file__))
db_py = os.path.join(cwd, 'db.py')

class SeleniumTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        if sys.platform == 'win32':
            cls.browser = webdriver.Firefox()
        else:
            options = webdriver.ChromeOptions()
            options.add_argument('headless')
            options.add_argument('disable-gpu')
            cls.browser = webdriver.Chrome(options=options)
        cls.browser.get('http://127.0.0.1:5555')
        cls.stdin = cls.browser.find_element_by_id('stdin')
        cls.send_btn = cls.browser.find_element_by_id('send_btn')

    @classmethod
    def tearDownClass(cls):
        cls.stdin.clear()
        cls.stdin.send_keys('q')
        cls.send_btn.click()
        time.sleep(1)
        cls.db_proc.kill()
        cls.browser.quit()

class WebPdbTestCase(SeleniumTestCase):
    """
    This class provides basic functionality testing for Web-PDB
    """
    @classmethod
    def setUpClass(cls):
        cls.db_proc = Popen(['python', db_py], shell=False)
        time.sleep(1)
        super(WebPdbTestCase, cls).setUpClass()

    def test_1_set_trace(self):
        """
        Test back-end/front-end interaction during debugging
        """
        filename_tag = self.browser.find_element_by_id('filename')
        self.assertEqual(filename_tag.text, 'db.py')
        curr_line_tag = self.browser.find_element_by_id('curr_line')
        self.assertEqual(curr_line_tag.text, '14')
        curr_file_tag = self.browser.find_element_by_id('curr_file_code')
        self.assertIn('foo = \'foo\'', curr_file_tag.text)
        globals_tag = self.browser.find_element_by_id('globals')
        self.assertIn('foo = \'foo\'', globals_tag.text)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('-> bar = \'bar\'', stdout_tag.text)
        # Test if Prismjs syntax coloring actually works
        self.assertIn('foo = \'foo\'',
                      self.browser.page_source)

    def test_2_next_command(self):
        """
        Test sending PDB commands
        """
        self.stdin.clear()
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        curr_line_tag = self.browser.find_element_by_id('curr_line')
        self.assertEqual(curr_line_tag.text, '15')
        globals_tag = self.browser.find_element_by_id('globals')
        self.assertIn('bar = \'bar\'', globals_tag.text)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('-> ham = \'spam\'', stdout_tag.text)
        self.assertEqual(self.stdin.get_attribute('value'), '')

    def test_3_history(self):
        """
        Test for the recent commands history
        """
        self.stdin.clear()
        self.stdin.send_keys('h')
        self.send_btn.click()
        time.sleep(1)
        self.stdin.send_keys(Keys.ARROW_UP)
        self.assertEqual(self.stdin.get_attribute('value'), 'h')
        self.stdin.send_keys(Keys.ARROW_UP)
        self.assertEqual(self.stdin.get_attribute('value'), 'n')

    def test_4_breakpints(self):
        """
        Test for highlighting breakpoints
        """
        self.stdin.clear()
        self.stdin.send_keys('b 20')
        self.send_btn.click()
        time.sleep(1)
        line_numbers_rows = self.browser.find_element_by_css_selector('span.line-numbers-rows')
        line_spans = line_numbers_rows.find_elements_by_tag_name('span')
        self.assertEqual(line_spans[19].get_attribute('class'), 'breakpoint')

    def test_5_unicode_literal(self):
        """
        Test for displaying unicode literals
        """
        self.stdin.clear()
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('-> name =', stdout_tag.text)

    def test_6_entering_unicode_string(self):
        """
        Test for entering unicode literal via console
        """
        self.stdin.clear()
        self.stdin.send_keys(u'p u\'python - питон\'')
        self.send_btn.click()
        time.sleep(1)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('u\'python -', stdout_tag.text)

    def test_7_local_vars(self):
        """
        Test for displaying local variables
        """
        self.stdin.clear()
        self.stdin.send_keys('c')
        self.send_btn.click()
        time.sleep(1)
        locals_tag = self.browser.find_element_by_id('locals')
        self.assertIn('spam = \'spam\'', locals_tag.text)
        globals_tag = self.browser.find_element_by_id('globals')
        self.assertNotEqual(globals_tag.text, locals_tag.text)

class PatchStdStreamsTestCase(SeleniumTestCase):
    """
    This class tests patching sys.std* streams
    """
    @classmethod
    def setUpClass(cls):
        cls.db_proc = Popen(['python', os.path.join(cwd, 'db_ps.py')], shell=False)
        time.sleep(1)
        super(PatchStdStreamsTestCase, cls).setUpClass()

    def test_patching_std_streams(self):
        """
        Test if std streams are correctly redirected to the web-console
        """
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('Enter something:', stdout_tag.text)
        self.stdin.send_keys('spam')
        self.send_btn.click()
        time.sleep(1)
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        self.assertIn('You have entered: spam', stdout_tag.text)

class CatchPostMortemTestCase(SeleniumTestCase):
    """
    This class for catching exceptions
    """
    @classmethod
    def setUpClass(cls):
        cls.db_proc = Popen(['python', os.path.join(cwd, 'db_pm.py')], shell=False)
        time.sleep(1)
        super(CatchPostMortemTestCase, cls).setUpClass()

    def test_catch_post_mortem(self):
        """
        Test if catch_post_mortem context manager catches exceptions
        """
        curr_line_tag = self.browser.find_element_by_id('curr_line')
        self.assertEqual(curr_line_tag.text, '14')
        curr_file_tag = self.browser.find_element_by_id('curr_file_code')
        self.assertIn('assert False, \'Oops!\'', curr_file_tag.text)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('AssertionError', stdout_tag.text)

if __name__ == '__main__':
    main()
<commit_msg>Correctly test entering and displaying Unicode strings<commit_after># coding: utf-8
# Created on: 13.09.2016
# Author: Roman Miroshnychenko aka Roman V.M. (romanvm@yandex.ua)
#
# Copyright (c) 2016 Roman Miroshnychenko
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import sys
import time
from unittest import TestCase, main
from subprocess import Popen
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

cwd = os.path.dirname(os.path.abspath(__file__))
db_py = os.path.join(cwd, 'db.py')

class SeleniumTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        if sys.platform == 'win32':
            cls.browser = webdriver.Firefox()
        else:
            options = webdriver.ChromeOptions()
            options.add_argument('headless')
            options.add_argument('disable-gpu')
            cls.browser = webdriver.Chrome(options=options)
        cls.browser.get('http://127.0.0.1:5555')
        cls.stdin = cls.browser.find_element_by_id('stdin')
        cls.send_btn = cls.browser.find_element_by_id('send_btn')

    @classmethod
    def tearDownClass(cls):
        cls.stdin.clear()
        cls.stdin.send_keys('q')
        cls.send_btn.click()
        time.sleep(1)
        cls.db_proc.kill()
        cls.browser.quit()

class WebPdbTestCase(SeleniumTestCase):
    """
    This class provides basic functionality testing for Web-PDB
    """
    @classmethod
    def setUpClass(cls):
        cls.db_proc = Popen(['python', db_py], shell=False)
        time.sleep(1)
        super(WebPdbTestCase, cls).setUpClass()

    def test_1_set_trace(self):
        """
        Test back-end/front-end interaction during debugging
        """
        filename_tag = self.browser.find_element_by_id('filename')
        self.assertEqual(filename_tag.text, 'db.py')
        curr_line_tag = self.browser.find_element_by_id('curr_line')
        self.assertEqual(curr_line_tag.text, '14')
        curr_file_tag = self.browser.find_element_by_id('curr_file_code')
        self.assertIn('foo = \'foo\'', curr_file_tag.text)
        globals_tag = self.browser.find_element_by_id('globals')
        self.assertIn('foo = \'foo\'', globals_tag.text)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('-> bar = \'bar\'', stdout_tag.text)
        # Test if Prismjs syntax coloring actually works
        self.assertIn('foo = \'foo\'',
                      self.browser.page_source)

    def test_2_next_command(self):
        """
        Test sending PDB commands
        """
        self.stdin.clear()
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        curr_line_tag = self.browser.find_element_by_id('curr_line')
        self.assertEqual(curr_line_tag.text, '15')
        globals_tag = self.browser.find_element_by_id('globals')
        self.assertIn('bar = \'bar\'', globals_tag.text)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('-> ham = \'spam\'', stdout_tag.text)
        self.assertEqual(self.stdin.get_attribute('value'), '')

    def test_3_history(self):
        """
        Test for the recent commands history
        """
        self.stdin.clear()
        self.stdin.send_keys('h')
        self.send_btn.click()
        time.sleep(1)
        self.stdin.send_keys(Keys.ARROW_UP)
        self.assertEqual(self.stdin.get_attribute('value'), 'h')
        self.stdin.send_keys(Keys.ARROW_UP)
        self.assertEqual(self.stdin.get_attribute('value'), 'n')

    def test_4_breakpints(self):
        """
        Test for highlighting breakpoints
        """
        self.stdin.clear()
        self.stdin.send_keys('b 20')
        self.send_btn.click()
        time.sleep(1)
        line_numbers_rows = self.browser.find_element_by_css_selector('span.line-numbers-rows')
        line_spans = line_numbers_rows.find_elements_by_tag_name('span')
        self.assertEqual(line_spans[19].get_attribute('class'), 'breakpoint')

    def test_5_unicode_literal(self):
        """
        Test for displaying unicode literals
        """
        self.stdin.clear()
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn(u'-> name = u\'Монти\'', stdout_tag.text)

    def test_6_entering_unicode_string(self):
        """
        Test for entering unicode literal via console
        """
        self.stdin.clear()
        self.stdin.send_keys(u'p u\'python - питон\'')
        self.send_btn.click()
        time.sleep(1)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn(u'u\'python - питон\'', stdout_tag.text)

    def test_7_local_vars(self):
        """
        Test for displaying local variables
        """
        self.stdin.clear()
        self.stdin.send_keys('c')
        self.send_btn.click()
        time.sleep(1)
        locals_tag = self.browser.find_element_by_id('locals')
        self.assertIn('spam = \'spam\'', locals_tag.text)
        globals_tag = self.browser.find_element_by_id('globals')
        self.assertNotEqual(globals_tag.text, locals_tag.text)

class PatchStdStreamsTestCase(SeleniumTestCase):
    """
    This class tests patching sys.std* streams
    """
    @classmethod
    def setUpClass(cls):
        cls.db_proc = Popen(['python', os.path.join(cwd, 'db_ps.py')], shell=False)
        time.sleep(1)
        super(PatchStdStreamsTestCase, cls).setUpClass()

    def test_patching_std_streams(self):
        """
        Test if std streams are correctly redirected to the web-console
        """
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('Enter something:', stdout_tag.text)
        self.stdin.send_keys('spam')
        self.send_btn.click()
        time.sleep(1)
        self.stdin.send_keys('n')
        self.send_btn.click()
        time.sleep(1)
        self.assertIn('You have entered: spam', stdout_tag.text)

class CatchPostMortemTestCase(SeleniumTestCase):
    """
    This class for catching exceptions
    """
    @classmethod
    def setUpClass(cls):
        cls.db_proc = Popen(['python', os.path.join(cwd, 'db_pm.py')], shell=False)
        time.sleep(1)
        super(CatchPostMortemTestCase, cls).setUpClass()

    def test_catch_post_mortem(self):
        """
        Test if catch_post_mortem context manager catches exceptions
        """
        curr_line_tag = self.browser.find_element_by_id('curr_line')
        self.assertEqual(curr_line_tag.text, '14')
        curr_file_tag = self.browser.find_element_by_id('curr_file_code')
        self.assertIn('assert False, \'Oops!\'', curr_file_tag.text)
        stdout_tag = self.browser.find_element_by_id('stdout')
        self.assertIn('AssertionError', stdout_tag.text)

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


<commit_before># coding=utf8
from src.com.mailsystem.orm import Department, User, Address, UserAddress, State, Mail, MailStateHistory
from src.com.mailsystem.orm.Database import Database

departments = [
    Department(name="PHY"),
    Department(name="CH"),
    Department(name="LAW"),
    Department(name="FI"),
    Department(name="CS"),
    Department(name="ECO"),
    Department(name="ART"),
    Department(name="ENV"),
    Department(name="ADM")
]
#"physics", "chemistry", "law", "finance", "computer science", "economy", "art", "environment", "administration"]

states = [
    State(name = "Deposited"),
    State(name = "Post-Transit"),
    State(name = "Waiting at address"),
    State(name = "Received")
]

# chinese_names = [
#     "张伟", "王伟","王芳","李伟","王秀英","李秀英","李娜","张秀英","刘伟","张敏",
#     "李静","张丽","王静","王丽","李强","张静","李敏","王敏","王磊","李军","刘洋",
#     "王勇","张勇","王艳","李杰","张磊","王强","王军","张杰","李娟","张艳","张涛",
#     "王涛","李明","李艳","王超","李勇","王娟","刘杰","王秀兰","李霞","刘敏","张军",
#     "李丽","张强","王平","王刚","王杰","李桂英","刘芳"
# ]

chinese_names = ["lina","mia","lifei","hefei"]

adresses = [
    Address(name="Zijing 1"),
    Address(name="Zijing 2"),
    Address(name="Zijing 3"),
    Address(name="Zijing 4"),
    Address(name="Zijing 5"),
    Address(name="Zijing 6"),
    Address(name="Zijing 7"),
    Address(name="Zijing 8"),
    Address(name="Zijing 9"),
    Address(name="Zijing 10"),
    Address(name="Zijing 11"),
    Address(name="Zijing 12"),
    Address(name="Zijing 13"),
    Address(name="Zijing 14"),
    Address(name="Zijing 15"),
    Address(name="Zijing 16"),
    Address(name="Zijing 17"),
    Address(name="Zijing 18"),
    Address(name="Zijing 19"),
    Address(name="Zijing 20"),
    Address(name="Zijing 21"),
    Address(name="Zijing 22"),
    Address(name="Zijing 23"),
    Address(name="Zijing 24"),
    Address(name="Lab of PHY"),
    Address(name="Lab of CH"),
    Address(name="Lab of LAW"),
    Address(name="Lab of FI"),
    Address(name="Lab of CS"),
    Address(name="Lab of ECO"),
    Address(name="Lab of ART"),
    Address(name="Lab of ENV"),
    Address(name="Lab of ADM")
]

db_users = Database('thumailusers', 'thumail', 'thumail', 'localhost', 5432)
s = db_users.session()
for adress in adresses:
    s.add(adress)

email_shift = 0
for department in departments:
    s.add(department)
    for username in chinese_names:
        mail = "w_" + str(email_shift) + "@mail.tsinghua.edu.cn"
        email_shift = email_shift + 1
        u = User(name=username.decode('utf8'), email=mail, department=department)
        s.add(u)
        for adress in adresses:
            s.add(UserAddress(address=adress, user=u))
s.commit()
print "Finish"
<commit_msg>populate v1 working<commit_after># coding=utf8
from src.com.mailsystem.orm import Department, User, Address, UserAddress, State, Mail, MailStateHistory
from src.com.mailsystem.orm.Database import Database

departments = [
    Department(name="PHY"),
    Department(name="CH"),
    Department(name="LAW"),
    Department(name="FI"),
    Department(name="CS"),
    Department(name="ECO"),
    Department(name="ART"),
    Department(name="ENV"),
    Department(name="ADM")
]
#"physics", "chemistry", "law", "finance", "computer science", "economy", "art", "environment", "administration"]

states = [
    State(name = "Deposited"),
    State(name = "Post-Transit"),
    State(name = "Waiting at address"),
    State(name = "Received")
]

chinese_names = [
    "张伟", "王伟","王芳","李伟","王秀英","李秀英","李娜","张秀英","刘伟","张敏",
    "李静","张丽","王静","王丽","李强","张静","李敏","王敏","王磊","李军","刘洋",
    "王勇","张勇","王艳","李杰","张磊","王强","王军","张杰","李娟","张艳","张涛",
    "王涛","李明","李艳","王超","李勇","王娟","刘杰","王秀兰","李霞","刘敏","张军",
    "李丽","张强","王平","王刚","王杰","李桂英","刘芳"
]

adresses = [
    Address(name="Zijing 1"),
    Address(name="Zijing 2"),
    Address(name="Zijing 3"),
    Address(name="Zijing 4"),
    Address(name="Zijing 5"),
    Address(name="Zijing 6"),
    Address(name="Zijing 7"),
    Address(name="Zijing 8"),
    Address(name="Zijing 9"),
    Address(name="Zijing 10"),
    Address(name="Zijing 11"),
    Address(name="Zijing 12"),
    Address(name="Zijing 13"),
    Address(name="Zijing 14"),
    Address(name="Zijing 15"),
    Address(name="Zijing 16"),
    Address(name="Zijing 17"),
    Address(name="Zijing 18"),
    Address(name="Zijing 19"),
    Address(name="Zijing 20"),
    Address(name="Zijing 21"),
    Address(name="Zijing 22"),
    Address(name="Zijing 23"),
    Address(name="Zijing 24"),
    Address(name="Lab of PHY"),
    Address(name="Lab of CH"),
    Address(name="Lab of LAW"),
    Address(name="Lab of FI"),
    Address(name="Lab of CS"),
    Address(name="Lab of ECO"),
    Address(name="Lab of ART"),
    Address(name="Lab of ENV"),
    Address(name="Lab of ADM")
]

db_users = Database('thumailusers', 'thumail', 'thumail', 'localhost', 5432)
s = db_users.session()
for adress in adresses:
    s.add(adress)

email_shift = 0
for department in departments:
    s.add(department)
    for username in chinese_names:
        mail = "w_" + str(email_shift) + "@mail.tsinghua.edu.cn"
        email_shift = email_shift + 1
        u = User(name=username.decode('utf8'), email=mail, department=department)
        s.add(u)
        for adress in adresses:
            s.add(UserAddress(address=adress, user=u))

s.commit()
print "Finish"
<|endoftext|>