<commit_before># import readline and set tab-completion based on what OS we are in
import readline
# MACOS uses "libedit" for readline functionality and has a different command
# for enabling tab completion
if 'libedit' in readline.__doc__:
    readline.parse_and_bind("bind ^I rl_complete")
# whereas Unix (and maybe Windows) have the same command
else:
    readline.parse_and_bind("tab: complete")
# library for shared functions
import re
from csv import DictWriter

def ask_user_questions(question_sequence, use_template=True, return_list=False):
    '''Given a sequence of items (can be a list or a dictionary, anything
    that supports iteration), prints prompts for every item in the shell
    so that the user can input a value for every item.
    Returns a dictionary of (item_name : user_input) pairings.
    '''
    # define question prompt template and return variable
    q_template = 'Please enter the {} below:\n'

    if use_template:
        question_sequence = (q_template.format(q) for q in question_sequence)

    answers = (input(question) for question in question_sequence)
    if return_list:
        return list(answers)
    return dict(zip(question_sequence, answers))

def ask_unique_question(question):
    return ask_user_questions([question],
        use_template=False,
        return_list=True)[0]

# define regular expression that checks for "yes" answers
YES_RGX = re.compile('y(:?e[sa]|up)?', re.IGNORECASE)

def is_yes(user_input):
    return bool(YES_RGX.match(user_input))

def is_DA1_file(filename):
    '''Checks if a file name has DA1 extension.
    Currently accepts both ".da1" and ".DA1" files.
    Retunrs a boolean (True or False).
    '''
    return filename.endswith('.da1') or filename.endswith('.DA1')

def write_to_csv(file_name, data, header, **kwargs):
    '''Writes data to file specified by filename.

    :type file_name: string
    :param file_name: name of the file to be created
    :type data: iterable
    :param data: some iterable of dictionaries each of which
    must not contain keys absent in the 'header' argument
    :type header: list
    :param header: list of columns to appear in the output
    :type **kwargs: dict
    :param **kwargs: parameters to be passed to DictWriter.
    For instance, restvals specifies what to set empty cells to by default or
    'dialect' loads a whole host of parameters associated with a certain csv
    dialect (eg. "excel").
    '''
    with open(file_name, 'w') as f:
        output = DictWriter(f, header, **kwargs)
        output.writeheader()
        output.writerows(data)

def write_to_txt(file_name, data, mode='w', AddNewLines=False, **kwargs):
    '''Writes data to a text file.

    :type fName: string
    :param fName: name of the file to be created
    :type data: iterable
    :param data: some iterable of strings or lists of strings (not a string)
    :type addNewLines: bool
    :param addNewLines: determines if it's necessary to add newline chars to
    members of list
    :type kwargs: dict
    :param kwargs: key word args to be passed to list_to_plain_text, if needed
    '''
    if AddNewLines:
        data = add_newlines(data, **kwargs)
    with open(file_name, mode=mode) as f:
        f.writelines(data)

def create_row_dict(fields, item):
    # IK: this should go into a separate file, I think
    length_difference = len(fields) - len(item)
    error_message = 'There are more items than labels for them: {0}'
    if length_difference < 0:
        print('Here are the column labels', fields)
        print('Here are the items', item)
        raise Exception(error_message.format(length_difference))
    elif length_difference > 0:
        item = item + ('NA',) * length_difference

    return dict(zip(fields, item))

def get_subj_num(file_name):
    '''Given a filename string returns any substring that consists of digits.
    If multiple such substrings are found, returns the first one.
    If no such substrings are found, returns empty string.
    '''
    subj_n_rgx = re.compile('\d+')
    # we don't want to risk finding digits from file extensions
    extensionless = file_name.split('.')[0]
    matches = subj_n_rgx.findall(extensionless)

    if not matches:
        warning = "Unable to find subject number in this file name: \n{0}"
        print(warning.format(file_name))
        return ''

    elif len(matches) > 1:
        warning = "Found several numbers in '{0}', using the first one out of: \n{1}"
        print(warning.format(file_name, matches))

    return matches[0]<commit_msg>get_subj_number can now handle being passes file paths not just file names<commit_after>import os
# import readline and set tab-completion based on what OS we are in
import readline
# MACOS uses "libedit" for readline functionality and has a different command
# for enabling tab completion
if 'libedit' in readline.__doc__:
    readline.parse_and_bind("bind ^I rl_complete")
# whereas Unix (and maybe Windows) have the same command
else:
    readline.parse_and_bind("tab: complete")
# library for shared functions
import re
from csv import DictWriter

def ask_user_questions(question_sequence, use_template=True, return_list=False):
    '''Given a sequence of items (can be a list or a dictionary, anything
    that supports iteration), prints prompts for every item in the shell
    so that the user can input a value for every item.
    Returns a dictionary of (item_name : user_input) pairings.
    '''
    # define question prompt template and return variable
    q_template = 'Please enter the {} below:\n'

    if use_template:
        question_sequence = (q_template.format(q) for q in question_sequence)

    answers = (input(question) for question in question_sequence)
    if return_list:
        return list(answers)
    return dict(zip(question_sequence, answers))

def ask_unique_question(question):
    return ask_user_questions([question],
        use_template=False,
        return_list=True)[0]

# define regular expression that checks for "yes" answers
YES_RGX = re.compile('y(:?e[sa]|up)?', re.IGNORECASE)

def is_yes(user_input):
    return bool(YES_RGX.match(user_input))

def is_DA1_file(filename):
    '''Checks if a file name has DA1 extension.
    Currently accepts both ".da1" and ".DA1" files.
    Retunrs a boolean (True or False).
    '''
    return filename.endswith('.da1') or filename.endswith('.DA1')

def write_to_csv(file_name, data, header, **kwargs):
    '''Writes data to file specified by filename.

    :type file_name: string
    :param file_name: name of the file to be created
    :type data: iterable
    :param data: some iterable of dictionaries each of which
    must not contain keys absent in the 'header' argument
    :type header: list
    :param header: list of columns to appear in the output
    :type **kwargs: dict
    :param **kwargs: parameters to be passed to DictWriter.
    For instance, restvals specifies what to set empty cells to by default or
    'dialect' loads a whole host of parameters associated with a certain csv
    dialect (eg. "excel").
    '''
    with open(file_name, 'w') as f:
        output = DictWriter(f, header, **kwargs)
        output.writeheader()
        output.writerows(data)

def write_to_txt(file_name, data, mode='w', AddNewLines=False, **kwargs):
    '''Writes data to a text file.

    :type fName: string
    :param fName: name of the file to be created
    :type data: iterable
    :param data: some iterable of strings or lists of strings (not a string)
    :type addNewLines: bool
    :param addNewLines: determines if it's necessary to add newline chars to
    members of list
    :type kwargs: dict
    :param kwargs: key word args to be passed to list_to_plain_text, if needed
    '''
    if AddNewLines:
        data = add_newlines(data, **kwargs)
    with open(file_name, mode=mode) as f:
        f.writelines(data)

def create_row_dict(fields, item):
    # IK: this should go into a separate file, I think
    length_difference = len(fields) - len(item)
    error_message = 'There are more items than labels for them: {0}'
    if length_difference < 0:
        print('Here are the column labels', fields)
        print('Here are the items', item)
        raise Exception(error_message.format(length_difference))
    elif length_difference > 0:
        item = item + ('NA',) * length_difference

    return dict(zip(fields, item))

def get_subj_num(file_path):
    '''Given a filename string returns any substring that consists of digits.
    If multiple such substrings are found, returns the first one.
    If no such substrings are found, returns empty string and warns the user.
    '''
    subj_n_rgx = re.compile('\d+')
    # first we make sure we're dealing with file's name, not full path to it
    file_name = os.path.basename(file_path)
    # we don't want to risk finding digits from file extensions
    extensionless = file_name.split('.')[0]
    matches = subj_n_rgx.findall(extensionless)

    if not matches:
        warning = "Unable to find subject number in this file name: \n{0}"
        print(warning.format(file_name))
        return ''

    elif len(matches) > 1:
        warning = "Found several numbers in '{0}', using the first one out of: \n{1}"
        print(warning.format(file_name, matches))

    return matches[0]<|endoftext|>


<commit_before>from countries.models import Country
import pandas as pd
from django.utils.termcolors import colorize

def load_countries():
    df = pd.read_csv('https://raw.githubusercontent.com/Valuehorizon/valuehorizon-countries/master/data/data-2016-06-01.csv')
    df = df.fillna("")
    for indexvalue in df.index:

        # Getting raw data from csv
        code2 = df.ix[indexvalue]["Alpha-2 code"]
        code3 = df.ix[indexvalue]["Alpha-3 code"]
        full_name = df.ix[indexvalue]["Full name"]
        if full_name == "":
            full_name = None
        num_code = df.ix[indexvalue]["Numeric code"]
        remark1 = df.ix[indexvalue]["Remark part 1"]
        remark2 = df.ix[indexvalue]["Remark part 2"]
        remark3 = df.ix[indexvalue]["Remark part 3"]
        remarks = df.ix[indexvalue]["Remarks"]
        com_name = df.ix[indexvalue]["Common name"]
        territory = df.ix[indexvalue]["Territory name"]

        # Getting ISO Status
        iso_dict = dict((v, k) for k, v in dict(Country.ISO_STATUS_CHOICES).iteritems())
        iso_raw = df.ix[indexvalue]["Status"]
        iso_stat = iso_dict[iso_raw]

        if df.ix[indexvalue]["Independent"] == "Yes":
            independent = True
        else:
            independent = False

        try:
            # Update data for existing country
            code_check = Country.objects.get(symbol_alpha2_code=code2)
            print "Country Code Already Exists for %s..." % str(com_name)
            code_check.name = full_name
            code_check.symbol_alpha3_code = code3
            code_check.is_independent = independent
            code_check.numeric_code = num_code
            code_check.remark_1 = remark1
            code_check.remark_2 = remark2
            code_check.remark_3 = remark3
            code_check.territory_name = territory
            code_check.iso_status = iso_stat
            code_check.common_name = com_name
            code_check.save()
        except Country.DoesNotExist:
            # Country does not exist..Add new country data
            print colorize("New Country Code Found...Save it!!", fg="red")
            print 'Creating Line'
            country_data = Country(name=full_name,
                                   symbol_alpha2_code=code2,
                                   symbol_alpha3_code=code3,
                                   is_independent=independent,
                                   numeric_code=num_code,
                                   remark_1=remark1,
                                   remark_2=remark2,
                                   remark_3=remark3,
                                   territory_name=territory,
                                   iso_status=iso_stat,
                                   common_name=com_name
                                   )
            print 'Done Creating Line'
            country_data.save()
            print colorize('Done Saving Line', fg="red")
<commit_msg>Changed data loader<commit_after>from countries.models import Country
import pandas as pd
from django.utils.termcolors import colorize

def load_countries():
    df = pd.read_csv('https://raw.githubusercontent.com/Valuehorizon/valuehorizon-countries/master/data/data-2016-06-01.csv')
    df = df.fillna("")
    for indexvalue in df.index:

        # Getting raw data from csv
        code2 = df.ix[indexvalue]["Alpha-2 code"]
        code3 = df.ix[indexvalue]["Alpha-3 code"]
        full_name = df.ix[indexvalue]["Short name lower case"]
        if full_name == "":
            full_name = None
        num_code = df.ix[indexvalue]["Numeric code"]
        remark1 = df.ix[indexvalue]["Remark part 1"]
        remark2 = df.ix[indexvalue]["Remark part 2"]
        remark3 = df.ix[indexvalue]["Remark part 3"]
        remarks = df.ix[indexvalue]["Remarks"]
        com_name = df.ix[indexvalue]["Common name"]
        territory = df.ix[indexvalue]["Territory name"]

        # Getting ISO Status
        iso_dict = dict((v, k) for k, v in dict(Country.ISO_STATUS_CHOICES).iteritems())
        iso_raw = df.ix[indexvalue]["Status"]
        iso_stat = iso_dict[iso_raw]

        if df.ix[indexvalue]["Independent"] == "Yes":
            independent = True
        else:
            independent = False

        try:
            # Update data for existing country
            code_check = Country.objects.get(symbol_alpha2_code=code2)
            print "Country Code Already Exists for %s..." % str(com_name)
            code_check.name = full_name
            code_check.symbol_alpha3_code = code3
            code_check.is_independent = independent
            code_check.numeric_code = num_code
            code_check.remark_1 = remark1
            code_check.remark_2 = remark2
            code_check.remark_3 = remark3
            code_check.territory_name = territory
            code_check.iso_status = iso_stat
            code_check.common_name = com_name
            code_check.save()
        except Country.DoesNotExist:
            # Country does not exist..Add new country data
            print colorize("New Country Code Found...Save it!!", fg="red")
            print 'Creating Line'
            country_data = Country(name=full_name,
                                   symbol_alpha2_code=code2,
                                   symbol_alpha3_code=code3,
                                   is_independent=independent,
                                   numeric_code=num_code,
                                   remark_1=remark1,
                                   remark_2=remark2,
                                   remark_3=remark3,
                                   territory_name=territory,
                                   iso_status=iso_stat,
                                   common_name=com_name
                                   )
            print 'Done Creating Line'
            country_data.save()
            print colorize('Done Saving Line', fg="red")
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

import irc.bot

class Enum:
    def __init__(self, *args, **kwargs):
        """ either you can call it like that: Enum(a=1, b=2) #1
            or like that: Enum({'a': 1, 'b': 2}) #2
        """
        if len(args) == 1:  #2
            if type(args[0])==dict and len(kwargs)==0:
                self.internal_dict = args[0]
            else:
                raise ValueError('uncorrect')
        elif len(kwargs)>0: #1
            if len(args)==0:
                self.internal_dict = kwargs
            else:
                raise ValueError('uncorrect')
    def __getattr__(self, name):
        return self.internal_dict.__getitem__(name)

class ServerSpec(irc.bot.ServerSpec):
    def __init__(self, host, nickname, realname, port, password):
        super().__init__(host, port, password)
        self.nickname = nickname
        self.realname = realname
<commit_msg>Adding the `unpack` function<commit_after># -*- coding: utf-8 -*-

import irc.bot

class Enum:
    def __init__(self, *args, **kwargs):
        """ either you can call it like that: Enum(a=1, b=2) #1
            or like that: Enum({'a': 1, 'b': 2}) #2
        """
        if len(args) == 1:  #2
            if type(args[0])==dict and len(kwargs)==0:
                self.internal_dict = args[0]
            else:
                raise ValueError('uncorrect')
        elif len(kwargs)>0: #1
            if len(args)==0:
                self.internal_dict = kwargs
            else:
                raise ValueError('uncorrect')
    def __getattr__(self, name):
        return self.internal_dict.__getitem__(name)

class ServerSpec(irc.bot.ServerSpec):
    def __init__(self, host, nickname, realname, port, password):
        super().__init__(host, port, password)
        self.nickname = nickname
        self.realname = realname

def unpack(raw):
    unpacked = raw.split(sep=' ')
    cmd = unpacked[0].lower()
    args = None
    if len(unpacked) > 1:
        args = unpacked[1:]
    return (cmd, args)
<|endoftext|>


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

"""
A simple GPG2 interface to batch encrypt/decrypt files.
"""

# TODO:
# * Show interactive GPG prompts in popup windows instead of making user type in the
# terminal. Might involve some subprocess pipe trickery.
# * Make output messages more helpful
# * Functionality for one-click secure wipes
# * Make the UI less ugly

import subprocess
import Tkinter
import tkFileDialog
import tkSimpleDialog
import os
import datetime

GPG = 'gpg2'
SERVER_KEY = ''  # replace with gpg key ID of server key, eventually
DECRYPTED_PREFIX = 'decrypted'

class GpgApp(object):

    def __init__(self, master):
        frame = Tkinter.Frame(master)
        frame.pack()
        # create the main notification text box with a scrollbar
        scrollbar = Tkinter.Scrollbar(master)
        scrollbar.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)
        self.text = Tkinter.Text(master, yscrollcommand=scrollbar.set)
        self.text.pack()
        scrollbar.config(command=self.text.yview)
        self.sane_insert('Welcome to the decryption and encryption interface!\n')
        self.sane_insert('To encrypt and decrypt files, go to the File menu.')
        self.sane_insert('Please remember to check the Terminal window for passphrase prompts.\n')
        # add a file menu
        menu = Tkinter.Menu(master)
        root.config(menu=menu)
        filemenu = Tkinter.Menu(menu, tearoff=0)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Decrypt files", command=self.batch_decrypt)
        filemenu.add_command(label="Encrypt files", command=self.batch_encrypt)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.do_exit)

    def sane_insert(self, text):
        """Insert text sanely into the UI notification box"""
        self.text.config(state=Tkinter.NORMAL)
        self.text.insert(Tkinter.END, text+'\n')
        self.text.config(state=Tkinter.DISABLED)

    def get_recipient(self):
        prompt = "Enter the email address to encrypt files to: "
        recipient = tkSimpleDialog.askstring("Encrypt files", prompt)
        return recipient

    def batch_decrypt(self):
        fin = tkFileDialog.askopenfilenames()
        if not fin:
            return
        dirname = self.get_timestamped_folder('decrypted')
        for f in fin:
            self.decrypt_file(f, dirname+os.path.basename(f)+'_decrypted')
        self.sane_insert('Wrote decrypted files to '+dirname)

    def batch_encrypt(self, recipient=None):
        recipient = self.get_recipient()
        if recipient is None:
            self.sane_insert("You must specify an email address for encryption")
            return
        fin = tkFileDialog.askopenfilenames()
        if not fin:
            return
        dirname = self.get_timestamped_folder('encrypted')
        for f in fin:
            self.encrypt_file(f, dirname+os.path.basename(f)+'_encrypted', recipient)
        self.sane_insert('Wrote encrypted files to '+dirname)

    def encrypt_file(self, input_file, output_file, recipient):
        args = [GPG, '--output', output_file, '--recipient', recipient, '-sea', input_file]
        self.do_subprocess(args)

    def decrypt_file(self, input_file, output_file):
        args = [GPG, '--output', output_file, '--decrypt', input_file]
        self.do_subprocess(args)

    def get_timestamped_folder(self, prefix):
        """Create a timestamped folder for encrypted/decrypted files"""
        timestring = datetime.datetime.now().strftime("%Y%m%d_%H%M")
        dirname = prefix+'_'+timestring+'/'
        if not os.path.isdir(dirname):
            os.mkdir(dirname)
        return dirname

    def do_subprocess(self, cmd):
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         stdin=subprocess.PIPE)
        out, err = proc.communicate()
        if err: self.sane_insert(err)

    def do_exit(self):
        """Close the window and quit"""
        root.destroy()

root = Tkinter.Tk()
root.title("a simple GnuPG interface")
app = GpgApp(root)
root.mainloop()
<commit_msg>Start switching from tkinter to pygtk<commit_after>#!/usr/bin/env python

"""
A simple GPG2 interface to batch encrypt/decrypt files.
"""

# TODO:
# * Show interactive GPG prompts in popup windows instead of making user type in the
# terminal. Might involve some subprocess pipe trickery.
# * Make output messages more helpful
# * Functionality for one-click secure wipes
# * Make the UI less ugly

import subprocess
import os
import datetime
import pygtk
pygtk.require('2.0')
import gtk

GPG = 'gpg2'
SERVER_KEY = ''  # replace with gpg key ID of server key, eventually
DECRYPTED_PREFIX = 'decrypted'
DECRYPT_BUTTON_TEXT = 'Decrypt files'
ENCRYPT_BUTTON_TEXT = 'Encrypt files'

class GpgApp(object):

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.exit)
        self.vbox = gtk.VBox()
        self.vbox.pack_start(self.init_text())
        self.hbox = gtk.HBox()
        self.init_buttons()
        self.vbox.pack_start(self.hbox)
        self.window.add(self.vbox)
        self.window.show_all()

    def delete_event(self, widget, event, data=None):
        return False

    def init_text(self):
        start_text = """Welcome to the GPG interface!\n
                        Click on the buttons below to encrypt and decrypt files. \n
                        You can select multiple files at once.\n"""
        textbox = gtk.TextView()
        text = gtk.TextBuffer()
        text.set_text(start_text)
        textbox.set_buffer(text)
        return textbox

    def init_buttons(self):
        self.encrypt_button = gtk.Button(ENCRYPT_BUTTON_TEXT)
        self.decrypt_button = gtk.Button(DECRYPT_BUTTON_TEXT)
        self.hbox.pack_start(self.decrypt_button)
        self.hbox.pack_start(self.encrypt_button)

    def notify_popup(self, message, level=gtk.MESSAGE_INFO):
        d = gtk.MessageDialog(parent=self.window, type=level,
                              buttons=gtk.BUTTONS_OK)
        d.set_markup(message)

    def get_recipient(self):
        prompt = "Enter the email address to encrypt files to: "
        recipient = tkSimpleDialog.askstring("Encrypt files", prompt)
        return recipient

    def batch_decrypt(self):
        fin = tkFileDialog.askopenfilenames()
        if not fin:
            return
        dirname = self.get_timestamped_folder('decrypted')
        for f in fin:
            self.decrypt_file(f, dirname+os.path.basename(f)+'_decrypted')
        self.notify_popup('Wrote decrypted files to '+dirname)

    def batch_encrypt(self, recipient=None):
        recipient = self.get_recipient()
        if recipient is None:
            self.notify_popup("You must specify an email address for encryption")
            return
        fin = tkFileDialog.askopenfilenames()
        if not fin:
            return
        dirname = self.get_timestamped_folder('encrypted')
        for f in fin:
            self.encrypt_file(f, dirname+os.path.basename(f)+'_encrypted', recipient)
        self.notify_popup('Wrote encrypted files to '+dirname)

    def encrypt_file(self, input_file, output_file, recipient):
        args = [GPG, '--output', output_file, '--recipient', recipient, '-sea', input_file]
        self.do_subprocess(args)

    def decrypt_file(self, input_file, output_file):
        args = [GPG, '--output', output_file, '--decrypt', input_file]
        self.do_subprocess(args)

    def get_timestamped_folder(self, prefix):
        """Create a timestamped folder for encrypted/decrypted files"""
        timestring = datetime.datetime.now().strftime("%Y%m%d_%H%M")
        dirname = prefix+'_'+timestring+'/'
        if not os.path.isdir(dirname):
            os.mkdir(dirname)
        return dirname

    def do_subprocess(self, cmd):
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         stdin=subprocess.PIPE)
        out, err = proc.communicate()
        if err: self.notify_popup(err, level=gtk.MESSAGE_ERROR)

    def exit(self, widget, data=None):
        """Close the window and quit"""
        gtk.main_quit()

    def main(self):
        gtk.main()

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


<commit_before>"""Execute files of Python code."""

import imp, os, sys

def run_python_file(filename, args):
    """Run a python file as if it were the main program on the command line.

    `filename` is the path to the file to execute, it need not be a .py file.
    `args` is the argument array to present as sys.argv, including the first
    element representing the file being executed.

    """
    # Create a module to serve as __main__
    old_main_mod = sys.modules['__main__']
    main_mod = imp.new_module("__main__")
    sys.modules['__main__'] = main_mod
    main_mod.__dict__.update({
        '__name__': '__main__',
        '__file__': filename,
        })

    # Set sys.argv and the first path element properly.
    old_argv = sys.argv
    old_path0 = sys.path[0]
    sys.argv = args
    sys.path[0] = os.path.dirname(filename)

    try:
        source = open(filename).read()
        exec compile(source, filename, "exec") in main_mod.__dict__
    finally:
        # Restore the old __main__
        sys.modules['__main__'] = old_main_mod

        # Restore the old argv and path
        sys.argv = old_argv
        sys.path[0] = old_path0
<commit_msg>Simplify the construction of the __main__ module in run_python_file.<commit_after>"""Execute files of Python code."""

import imp, os, sys

def run_python_file(filename, args):
    """Run a python file as if it were the main program on the command line.

    `filename` is the path to the file to execute, it need not be a .py file.
    `args` is the argument array to present as sys.argv, including the first
    element representing the file being executed.

    """
    # Create a module to serve as __main__
    old_main_mod = sys.modules['__main__']
    main_mod = imp.new_module('__main__')
    sys.modules['__main__'] = main_mod
    main_mod.__file__ = filename

    # Set sys.argv and the first path element properly.
    old_argv = sys.argv
    old_path0 = sys.path[0]
    sys.argv = args
    sys.path[0] = os.path.dirname(filename)

    try:
        source = open(filename).read()
        exec compile(source, filename, "exec") in main_mod.__dict__
    finally:
        # Restore the old __main__
        sys.modules['__main__'] = old_main_mod

        # Restore the old argv and path
        sys.argv = old_argv
        sys.path[0] = old_path0
<|endoftext|>


<commit_before>import datetime

def get_semester(date: datetime.datetime) -> str:
    """
    Semesters are coded B161 (winter 2016/2017), B162 (summer 2016/2017) etc.

    They are obtained by comparing dates:
        January-February year X -> winter semester of year (X-1)/X
        March-September year X  -> summer semester of year (X-1)/X
        October-December year X  -> winter semester of year X/(X+1)
    :return: String representing the semester, such as B161.
    """
    year = date.year % 1000
    month = date.month

    if month in [1, 2]:
        return f"B{year-1}1"
    elif month in [3, 4, 5, 6, 7, 8, 9]:
        return f"B{year-1}2"
    elif month in [10, 11, 12]:
        return f"B{year}1"

def semester_id_to_str(semester_id):
    year = semester_id[1:3]
    wintersummer_flag = int(semester_id[3])

    year_full = 2000 + int(year)
    winsum_str = "zimní" if wintersummer_flag == 1 else "letní"

    return f'{winsum_str.capitalize()} semestr {year_full}/{year_full+1}'

def timestamp_to_date_str(timestamp: float) -> str:
    return datetime.datetime.fromtimestamp(timestamp).strftime("%d.%m.%Y %H:%M")

def sanitize_fn(fn: str) -> str:
    return "".join([c for c in fn if c.isalpha() or c.isdigit() or c == ' ']).rstrip()
<commit_msg>Change date format<commit_after>import datetime

def get_semester(date: datetime.datetime) -> str:
    """
    Semesters are coded B161 (winter 2016/2017), B162 (summer 2016/2017) etc.

    They are obtained by comparing dates:
        January-February year X -> winter semester of year (X-1)/X
        March-September year X  -> summer semester of year (X-1)/X
        October-December year X  -> winter semester of year X/(X+1)
    :return: String representing the semester, such as B161.
    """
    year = date.year % 1000
    month = date.month

    if month in [1, 2]:
        return f"B{year-1}1"
    elif month in [3, 4, 5, 6, 7, 8, 9]:
        return f"B{year-1}2"
    elif month in [10, 11, 12]:
        return f"B{year}1"

def semester_id_to_str(semester_id):
    year = semester_id[1:3]
    wintersummer_flag = int(semester_id[3])

    year_full = 2000 + int(year)
    winsum_str = "zimní" if wintersummer_flag == 1 else "letní"

    return f'{winsum_str.capitalize()} semestr {year_full}/{year_full+1}'

def timestamp_to_date_str(timestamp: float) -> str:
    return datetime.datetime.fromtimestamp(timestamp).strftime("%d.%m.%Y")

def sanitize_fn(fn: str) -> str:
    return "".join([c for c in fn if c.isalpha() or c.isdigit() or c == ' ']).rstrip()
<|endoftext|>


<commit_before>import argparse, sys
from svtools.vcf.file import Vcf
from svtools.vcf.variant import Variant

class UpdateInfo(object):
    def __init__(self, vcf_stream):
        self.vcf_stream = vcf_stream

    def execute(self, output_handle=sys.stdout):
        in_header = True
        header = []
        breakend_dict = {} # cache to hold unmatched generic breakends for genotyping
        vcf = Vcf()
        vcf_out = output_handle

        # read input VCF
        for line in self.vcf_stream:
            if in_header:
                if line.startswith('##'):
                    header.append(line)
                    continue
                elif line.startswith('#CHROM'):
                    v = line.rstrip().split('\t')
                    header.append('\t'.join(v[:8]))

                    in_header = False
                    vcf.add_header(header)

                    vcf.add_info('AF', 'A', 'Float', 'Allele Frequency, for each ALT allele, in the same order as listed')
                    vcf.add_info('NSAMP', '1', 'Integer', 'Number of samples with non-reference genotypes')

                    # write header
                    vcf_out.write(vcf.get_header(include_samples=False))
                    vcf_out.write('\t' + '\t'.join(v[8:]) + '\n')
                continue

            v = line.rstrip().split('\t')
            var = Variant(v[:8], vcf)

            # extract genotypes from VCF
            num_alt = len(var.alt.split(','))
            alleles = [0] * (num_alt + 1)
            num_samp = 0

            for i in xrange(9,len(v)):
                gt_string = v[i].split(':')[0]

                if '.' in  gt_string:
                    continue
                gt = gt_string.split('/')
                if len(gt) == 1:
                    gt = gt_string.split('|')
                gt = map(int, gt)

                for i in xrange(len(gt)):
                    alleles[gt[i]] += 1

                # iterate the number of non-reference samples
                if sum(gt) > 0:
                    num_samp += 1

            allele_sum = float(sum(alleles))
            allele_freq = ['.'] * len(alleles)

            # populate AF
            if allele_sum > 0:
                for i in xrange(len(alleles)):
                    allele_freq[i] = alleles[i] / allele_sum
                var.info['AF'] = ','.join(map(str, ['%.4g' % a for a in allele_freq[1:]]))
            else:
                var.info['AF'] = ','.join(map(str, allele_freq[1:]))

            # populate NSAMP
            var.info['NSAMP'] = num_samp

            # after all samples have been processed, write
            vcf_out.write(var.get_var_string()
                          + '\t'
                          + '\t'.join(v[8:])
                          + '\n')
        vcf_out.close()

def description():
    return 'Add allele frequency information to a VCF file'

def add_arguments_to_parser(parser):
    parser.add_argument(metavar='vcf', dest='input_vcf', nargs='?', default=None, help='VCF input')
    parser.set_defaults(entry_point=run_from_args)

def command_parser():
    parser = argparse.ArgumentParser(description=description())
    add_arguments_to_parser(parser)
    return parser

def run_from_args(args):
    handle = None
    if args.input_vcf == None:
        if sys.stdin.isatty():
            parser.print_help()
            exit(1)
        else:
            handle = sys.stdin
    else:
        handle = open(args.input_vcf, 'r')
    updater = UpdateInfo(handle)
    updater.execute()
    if handle != sys.stdin:
        handle.close()

if __name__ == '__main__':
    parser = command_parser()
    args = parser.parse_args()
    sys.exit(args.entry_point(args))
<commit_msg>stub-in MSQ calculation from vcfpase<commit_after>import argparse, sys
from svtools.vcf.file import Vcf
from svtools.vcf.variant import Variant

class UpdateInfo(object):
    def __init__(self, vcf_stream):
        self.vcf_stream = vcf_stream

    def calc_msq(self, var):
            # Below is what was in vcfpaste, but what if multiple ALTs?
            # Do we only expect 1 ALT per line?
            # NOTE SQ is defined as: 'Phred-scaled probability that this site is variant (non-reference in this sample'
            # Likely want average sample quality across all non-0/0 genotypes rather than just those containing 1
            gt = [var.genotype(s).get_format('GT') for s in var.sample_list]
            positive_gt = filter(lambda x: x == '0/1' or x == '1/1', gt)
            num_pos = len(positive_gt)
            sum_sq = 0.0
            try:
                sum_sq += sum([float(var.genotype(s).get_format('SQ')) for s in var.sample_list \
                if var.genotype(s).get_format('GT') == '1/1' or var.genotype(s).get_format('GT') == '0/1'])
            except ValueError:
                sum_sq += 0
            if num_pos > 0:
                msq = '%0.2f' % (sum_sq / num_pos)
            else:
                msq = '.'
            return msq

    def execute(self, output_handle=sys.stdout):
        in_header = True
        header = []
        vcf = Vcf()
        vcf_out = output_handle

        # read input VCF
        for line in self.vcf_stream:
            if in_header:
                if line.startswith('##'):
                    header.append(line)
                    continue
                elif line.startswith('#CHROM'):
                    v = line.rstrip().split('\t')
                    header.append('\t'.join(v[:8]))

                    in_header = False
                    vcf.add_header(header)

                    vcf.add_info('AF', 'A', 'Float', 'Allele Frequency, for each ALT allele, in the same order as listed')
                    vcf.add_info('NSAMP', '1', 'Integer', 'Number of samples with non-reference genotypes')
                    vcf.add_info('MSQ', '1', 'Float', 'Mean sample quality of positively genotyped samples')

                    # write header
                    vcf_out.write(vcf.get_header(include_samples=False))
                    vcf_out.write('\t' + '\t'.join(v[8:]) + '\n')
                continue

            v = line.rstrip().split('\t')
            var = Variant(v[:8], vcf)

            # extract genotypes from VCF
            num_alt = len(var.alt.split(','))
            alleles = [0] * (num_alt + 1)
            num_samp = 0

            for i in xrange(9,len(v)):
                gt_string = v[i].split(':', 1)[0]

                if '.' in  gt_string:
                    continue
                gt = gt_string.split('/')
                if len(gt) == 1:
                    gt = gt_string.split('|')
                gt = map(int, gt)

                for i in xrange(len(gt)):
                    alleles[gt[i]] += 1

                # iterate the number of non-reference samples
                if sum(gt) > 0:
                    num_samp += 1

            allele_sum = float(sum(alleles))
            allele_freq = ['.'] * len(alleles)

            # populate AF
            if allele_sum > 0:
                for i in xrange(len(alleles)):
                    allele_freq[i] = alleles[i] / allele_sum
                var.info['AF'] = ','.join(map(str, ['%.4g' % a for a in allele_freq[1:]]))
            else:
                var.info['AF'] = ','.join(map(str, allele_freq[1:]))

            # populate NSAMP
            var.info['NSAMP'] = num_samp
            var.info['MSQ'] = self.calc_msq(var)

            # after all samples have been processed, write
            vcf_out.write(var.get_var_string()
                          + '\t'
                          + '\t'.join(v[8:])
                          + '\n')
        vcf_out.close()

def description():
    return 'Add allele frequency information to a VCF file'

def add_arguments_to_parser(parser):
    parser.add_argument(metavar='vcf', dest='input_vcf', nargs='?', default=None, help='VCF input')
    parser.set_defaults(entry_point=run_from_args)

def command_parser():
    parser = argparse.ArgumentParser(description=description())
    add_arguments_to_parser(parser)
    return parser

def run_from_args(args):
    handle = None
    if args.input_vcf == None:
        if sys.stdin.isatty():
            parser.print_help()
            exit(1)
        else:
            handle = sys.stdin
    else:
        handle = open(args.input_vcf, 'r')
    updater = UpdateInfo(handle)
    updater.execute()
    if handle != sys.stdin:
        handle.close()

if __name__ == '__main__':
    parser = command_parser()
    args = parser.parse_args()
    sys.exit(args.entry_point(args))
<|endoftext|>


<commit_before>import numpy as np
import os.path
import scipy.io
import h5py
import cPickle as pkl

def name_level(n_levels):
    x_name = []
    ytrue_name = []
    for i in range(0,n_levels):
        x_name.append(str( "level_" + str(i)))
        ytrue_name.append(str("ytrue_" + str(i)))
    return x_name, ytrue_name

def format_level(iterable, receptive_field):
    indicies = range(receptive_field-1, -1, -1)
    for i in range(len(indicies)):
        indicies[i] = -1* 2**indicies[i]
    indicies.append(0)
    indicies_pos = range(0, receptive_field)
    for i in range(len(indicies_pos)):
        indicies_pos[i] = 2**indicies_pos[i]

    indicies = indicies + indicies_pos

    level = []
    for i in range(len(iterable)):
        l = []
        for index in indicies:
            l.extend( iterable[ (i+index)%len(iterable) ])
        level = np.append(level, l)

    return level

def load_matlab(data_location, receptive_field):
    read_file = data_location + "/matlab_song_r" + str(receptive_field) + ".mat"
    #matlab_input = scipy.io.loadmat(read_file)
    matlab_input = h5py.File(read_file)
    print matlab_input.get('receptive_field')[0,0]

    r_field = int(matlab_input.get('receptive_field')[0,0])
    n_levels = int(matlab_input.get('n_levels')[0,0])

    #x_data = [matlab_input[element[0]][:] for element in matlab_input['inputs_formatted']]
    #ytrue_data = [matlab_input[element[0]][:] for element in matlab_input['targets']]

    #np.set_printoptions(threshold=np.inf)

    print "Reading", read_file, " receptive field:", r_field, "levels:", n_levels
    for i in range(n_levels):
        x_data = [matlab_input[element[i]][:] for element in matlab_input['inputs_formatted']]
        ytrue_data = [matlab_input[element[i]][:] for element in matlab_input['targets']]
        x_data = x_data[0].transpose()
        ytrue_data = ytrue_data[0].transpose()
        store_file = data_location + "/xytrue_" + str(i) + "_r" + str(receptive_field) + ".pkl"
        print "Read level", i, "x:", x_data.shape, "ytrue:", ytrue_data.shape
        data_list = [ x_data, ytrue_data ]
        with open(store_file, "wb") as output_file:
            pkl.dump(data_list, output_file)

def read_data(data_location, receptive_field, level):
    store_file = data_location + "/xytrue_" + str(level) + "_r" + str(receptive_field) + ".pkl"
    try:
        os.path.isfile(store_file)
    except IOError:
        print "Failed to load:", store_file

    with open(store_file, "rb") as input_file:
        data_list = pkl.load(input_file)
    x_data = data_list[0]
    ytrue_data = data_list[1]
    return x_data, ytrue_data

def read_seed(seed_file, receptive_field):
    try:
        matlab_input = scipy.io.loadmat(seed_file)
    except IOError:
        print "Failed to load:", seed_file
    print "Opened:", seed_file
    seed_data = matlab_input['seed']
    print "Read seed:", seed_data.shape
    return seed_data

def write_song(song, data_location, level, receptive_field):
    song_name = "song_" + str(level+1) + "_r" + str(receptive_field)
    song_file = data_location + "/" + song_name + ".mat"
    scipy.io.savemat(song_file, mdict={ song_name: song})
    print "Saved song:", song_file
    return song_name

<commit_msg>util.py error checking added<commit_after>import numpy as np
import os.path
import scipy.io
import h5py
import cPickle as pkl

def name_level(n_levels):
    x_name = []
    ytrue_name = []
    for i in range(0,n_levels):
        x_name.append(str( "level_" + str(i)))
        ytrue_name.append(str("ytrue_" + str(i)))
    return x_name, ytrue_name

def format_level(iterable, receptive_field):
    indicies = range(receptive_field-1, -1, -1)
    for i in range(len(indicies)):
        indicies[i] = -1* 2**indicies[i]
    indicies.append(0)
    indicies_pos = range(0, receptive_field)
    for i in range(len(indicies_pos)):
        indicies_pos[i] = 2**indicies_pos[i]

    indicies = indicies + indicies_pos

    level = []
    for i in range(len(iterable)):
        l = []
        for index in indicies:
            l.extend( iterable[ (i+index)%len(iterable) ])
        level = np.append(level, l)

    return level

def load_matlab(data_location, receptive_field):
    read_file = data_location + "/matlab_song_r" + str(receptive_field) + ".mat"

    try:
        os.path.isfile(read_file)
    except IOError:
        print "Failed to load:", store_file

    with h5py.File(read_file) as matlab_input:
        r_field = int(matlab_input.get('receptive_field')[0,0])
        n_levels = int(matlab_input.get('n_levels')[0,0])

        print "Reading", read_file, " receptive field:", r_field, "levels:", n_levels
        for i in range(n_levels):
            x_data = [matlab_input[element[i]][:] for element in matlab_input['inputs_formatted']]
            ytrue_data = [matlab_input[element[i]][:] for element in matlab_input['targets']]
            x_data = x_data[0].transpose()
            ytrue_data = ytrue_data[0].transpose()
            store_file = data_location + "/xytrue_" + str(i) + "_r" + str(receptive_field) + ".pkl"
            print "Read level", i, "x:", x_data.shape, "ytrue:", ytrue_data.shape
            data_list = [ x_data, ytrue_data ]
            with open(store_file, "wb") as output_file:
                pkl.dump(data_list, output_file)

def read_data(data_location, receptive_field, level):
    store_file = data_location + "/xytrue_" + str(level) + "_r" + str(receptive_field) + ".pkl"
    try:
        os.path.isfile(store_file)
    except IOError:
        print "Failed to load:", store_file

    with open(store_file, "rb") as input_file:
        data_list = pkl.load(input_file)
    x_data = data_list[0]
    ytrue_data = data_list[1]
    return x_data, ytrue_data

def read_seed(seed_file, receptive_field):
    try:
        matlab_input = scipy.io.loadmat(seed_file)
    except IOError:
        print "Failed to load:", seed_file
    print "Opened:", seed_file
    seed_data = matlab_input['seed']
    print "Read seed:", seed_data.shape
    return seed_data

# https://stackoverflow.com/questions/36362831/creating-a-mat-file-of-v7-3-in-python
def write_song(song, data_location, level, receptive_field):
    song_name = "song_" + str(level+1) + "_r" + str(receptive_field)
    song_file = data_location + "/" + song_name + ".mat"
    scipy.io.savemat(song_file, mdict={ song_name: song})
    print "Saved song:", song_file
    return song_name

<|endoftext|>


<commit_before>"""Snipppets of potentially reusable code that don't deserve their
own library."""

import bisect
import contextlib
import os
import unittest
from functools import wraps

class Location:
    def __init__(self, name, line, col):
        self.name = name
        self.line = line
        self.col = col

    def __str__(self):
        return "{}:{}.{}".format(self.name, self.line, self.col)

class Locator:
    """Locator provides a way to convert an absolute offset in a
    string into a Location object.

    """

    def __init__(self, data, name='<string>'):
        self.name = name
        self.line_offsets = [0]
        for line_len in map(len, data.splitlines(True)):
            self.line_offsets.append(self.line_offsets[-1] + line_len)

    def locate(self, offset):
        """Return a Location() object for the given offset."""
        line = bisect.bisect_right(self.line_offsets, offset)
        col = offset - self.line_offsets[line - 1]
        return Location(self.name, line, col)

def import_from_dir(module_name, dir_name):
    """Import a module form a specific directory.

    Sometimes you might want to load a package from a specific
    directory. For example, you may be loading a plugin of some
    description.

    This function ensures that only modules from a specific
    directory are loaded to avoid any chance of loading a
    module of the same name from somewhere else.

    After loading the module is removed from sys.modules to
    avoid other namespace clashes.

    """
    saved_sys_path = sys.path
    saved_module = None
    if module_name in sys.modules:
        saved_module = sys.modules[module_name]
    try:
        module = __import__(module_name)
        return module
    finally:
        sys.path = saved_sys_path
        if saved_module:
            sys.modules[module_name] = saved_module
        else:
            del sys.modules[module_name]

def dict_inverse(dct, exact=False):
    """Given an input dictionary (`dct`), create a new dictionary
    where the keys are indexed by the values. In the original
    dictionary multiple keys may reference the same value, so the
    values in the new dictionary is a list of keys. The order of keys
    in the list is undefined.

    Example:

    > dict_inverse({1: 'a', 2: 'a', 3: 'c'})
    { 'a': [1, 2], 'c': [3]

    If `dct` has an exact inverse mapping `exact` can be passed as
    True. In this case, the values will be just the original key (not
    a list).

    Example:

    > dict_inverse({1: 'a', 2: 'b', 3: 'c'}, exact=True)
    { 'a': 1, 'b': 2, 'c': 3}

    Note: No checking is done when exact is True, so in the case
    where there are multiple keys mapping the same value it is
    undefined as to which key the value will map to.

    """
    if exact:
        return {value: key for key, value in dct.items()}

    r = {}
    for key, value in dct.items():
        r.setdefault(value, []).append(key)
    return r

class _GeneratorSimpleContextManager(contextlib._GeneratorContextManager):
    """Helper for @simplecontextmanager decorator."""

    def __exit__(self, type, value, traceback):
        if type is None:
            try:
                next(self.gen)
            except StopIteration:
                return
            else:
                raise RuntimeError("generator didn't stop")
        else:
            if value is None:
                # Need to force instantiation so we can reliably
                # tell if we get the same exception back
                value = type()

            try:
                next(self.gen)
            except StopIteration as exc:
                # Suppress the exception *unless* it's the same exception that
                # was passed to throw().  This prevents a StopIteration
                # raised inside the "with" statement from being suppressed
                return exc is not value
            else:
                raise RuntimeError("generator didn't stop")
            finally:
                return False

def simplecontextmanager(func):
    """@simplecontextmanager decorator.

    Typical usage:

        @simplecontextmanager
        def some_generator(<arguments>):
            <setup>
            yield <value>
            <cleanup>

    This makes this:

        with some_generator(<arguments>) as <variable>:
            <body>

    equivalent to this:

        <setup>
        try:
            <variable> = <value>
            <body>
        finally:
            <cleanup>

    """
    @wraps(func)
    def helper(*args, **kwds):
        return _GeneratorSimpleContextManager(func, *args, **kwds)
    return helper

@simplecontextmanager
def chdir(path):
    """Current-working directory context manager.

    Makes the current working directory the specified `path` for the
    duration of the context.

    Example:

    with chdir("newdir"):
        # Do stuff in the new directory
        pass

    """
    cwd = os.getcwd()
    os.chdir(path)
    yield
    os.chdir(cwd)

@simplecontextmanager
def umask(new_mask):
    """unmask context manager.

    Makes `new_mask` the current mask, and restores the previous umask
    after the context closes.

    """
    cur_mask = os.umask(new_mask)
    yield
    os.umask(cur_mask)

@simplecontextmanager
def update_env(env):
    """os.environ context manager.

    Updates os.environ with the specified `env` for the duration of the context.

    """
    old_env = {}
    for key in env:
        old_env[key] = os.environ.get(key)
        os.environ[key] = env[key]

    yield

    for key in old_env:
        if old_env[key] is None:
            del os.environ[key]
        else:
            os.environ[key] = old_env[key]

class TestUtil(unittest.TestCase):

    def test_chdir(self):
        cur = os.getcwd()
        with chdir('/'):
            assert os.getcwd() == '/'
        assert os.getcwd() == cur

    def test_dict_inverse(self):
        assert dict_inverse({1: 'a', 2: 'a', 3: 'c'}) == {'a': [1, 2], 'c': [3]}
        assert dict_inverse({1: 'a', 2: 'b', 3: 'c'}, True) == {'a': 1, 'b': 2, 'c': 3}

    def test_simplecontextmanager(self):
        before = None
        after = None

        @simplecontextmanager
        def foo():
            nonlocal before
            nonlocal after
            after = None
            before = True
            yield 1
            after = True

        with foo() as x:
            assert x == 1
            assert before
            assert after is None
        assert before
        assert after

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
                raise Exception('check')
        except Exception as exc:
            assert exc.args == ('check', )
            assert before
            assert after
        else:
            assert False

    def test_simplecontextmanager_double_yield(self):
        before = None
        after = None

        @simplecontextmanager
        def foo():
            nonlocal before
            nonlocal after
            after = None
            before = True
            yield 1
            yield 2
            after = True

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
        except RuntimeError as exc:
            assert exc.args == ("generator didn't stop", )
        else:
            assert False

    def test_simplecontextmanager_raise(self):
        before = None
        after = None

        @simplecontextmanager
        def foo():
            nonlocal before
            nonlocal after
            after = None
            before = True
            yield 1
            raise Exception("with")

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
        except Exception as exc:
            assert exc.args == ('with', )
            assert before
            assert after is None
        else:
            assert False

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
                raise Exception("check")
        except Exception as exc:
            assert exc.args == ('check', )
            assert before
            assert after is None
        else:
            assert False
<commit_msg>Add tempdir with context<commit_after>"""Snipppets of potentially reusable code that don't deserve their
own library."""

import bisect
import contextlib
import os
import shutil
import tempfile
import unittest
from functools import wraps

class Location:
    def __init__(self, name, line, col):
        self.name = name
        self.line = line
        self.col = col

    def __str__(self):
        return "{}:{}.{}".format(self.name, self.line, self.col)

class Locator:
    """Locator provides a way to convert an absolute offset in a
    string into a Location object.

    """

    def __init__(self, data, name='<string>'):
        self.name = name
        self.line_offsets = [0]
        for line_len in map(len, data.splitlines(True)):
            self.line_offsets.append(self.line_offsets[-1] + line_len)

    def locate(self, offset):
        """Return a Location() object for the given offset."""
        line = bisect.bisect_right(self.line_offsets, offset)
        col = offset - self.line_offsets[line - 1]
        return Location(self.name, line, col)

def import_from_dir(module_name, dir_name):
    """Import a module form a specific directory.

    Sometimes you might want to load a package from a specific
    directory. For example, you may be loading a plugin of some
    description.

    This function ensures that only modules from a specific
    directory are loaded to avoid any chance of loading a
    module of the same name from somewhere else.

    After loading the module is removed from sys.modules to
    avoid other namespace clashes.

    """
    saved_sys_path = sys.path
    saved_module = None
    if module_name in sys.modules:
        saved_module = sys.modules[module_name]
    try:
        module = __import__(module_name)
        return module
    finally:
        sys.path = saved_sys_path
        if saved_module:
            sys.modules[module_name] = saved_module
        else:
            del sys.modules[module_name]

def dict_inverse(dct, exact=False):
    """Given an input dictionary (`dct`), create a new dictionary
    where the keys are indexed by the values. In the original
    dictionary multiple keys may reference the same value, so the
    values in the new dictionary is a list of keys. The order of keys
    in the list is undefined.

    Example:

    > dict_inverse({1: 'a', 2: 'a', 3: 'c'})
    { 'a': [1, 2], 'c': [3]

    If `dct` has an exact inverse mapping `exact` can be passed as
    True. In this case, the values will be just the original key (not
    a list).

    Example:

    > dict_inverse({1: 'a', 2: 'b', 3: 'c'}, exact=True)
    { 'a': 1, 'b': 2, 'c': 3}

    Note: No checking is done when exact is True, so in the case
    where there are multiple keys mapping the same value it is
    undefined as to which key the value will map to.

    """
    if exact:
        return {value: key for key, value in dct.items()}

    r = {}
    for key, value in dct.items():
        r.setdefault(value, []).append(key)
    return r

class _GeneratorSimpleContextManager(contextlib._GeneratorContextManager):
    """Helper for @simplecontextmanager decorator."""

    def __exit__(self, type, value, traceback):
        if type is None:
            try:
                next(self.gen)
            except StopIteration:
                return
            else:
                raise RuntimeError("generator didn't stop")
        else:
            if value is None:
                # Need to force instantiation so we can reliably
                # tell if we get the same exception back
                value = type()

            try:
                next(self.gen)
            except StopIteration as exc:
                # Suppress the exception *unless* it's the same exception that
                # was passed to throw().  This prevents a StopIteration
                # raised inside the "with" statement from being suppressed
                return exc is not value
            else:
                raise RuntimeError("generator didn't stop")
            finally:
                return False

def simplecontextmanager(func):
    """@simplecontextmanager decorator.

    Typical usage:

        @simplecontextmanager
        def some_generator(<arguments>):
            <setup>
            yield <value>
            <cleanup>

    This makes this:

        with some_generator(<arguments>) as <variable>:
            <body>

    equivalent to this:

        <setup>
        try:
            <variable> = <value>
            <body>
        finally:
            <cleanup>

    """
    @wraps(func)
    def helper(*args, **kwds):
        return _GeneratorSimpleContextManager(func, *args, **kwds)
    return helper

@simplecontextmanager
def chdir(path):
    """Current-working directory context manager.

    Makes the current working directory the specified `path` for the
    duration of the context.

    Example:

    with chdir("newdir"):
        # Do stuff in the new directory
        pass

    """
    cwd = os.getcwd()
    os.chdir(path)
    yield
    os.chdir(cwd)

@simplecontextmanager
def umask(new_mask):
    """unmask context manager.

    Makes `new_mask` the current mask, and restores the previous umask
    after the context closes.

    """
    cur_mask = os.umask(new_mask)
    yield
    os.umask(cur_mask)

@simplecontextmanager
def update_env(env):
    """os.environ context manager.

    Updates os.environ with the specified `env` for the duration of the context.

    """
    old_env = {}
    for key in env:
        old_env[key] = os.environ.get(key)
        os.environ[key] = env[key]

    yield

    for key in old_env:
        if old_env[key] is None:
            del os.environ[key]
        else:
            os.environ[key] = old_env[key]

@simplecontextmanager
def tempdir():
    tmpdir = tempfile.mkdtemp()
    yield tmpdir
    shutil.rmtree(tmpdir)

class TestUtil(unittest.TestCase):

    def test_chdir(self):
        cur = os.getcwd()
        with chdir('/'):
            assert os.getcwd() == '/'
        assert os.getcwd() == cur

    def test_dict_inverse(self):
        assert dict_inverse({1: 'a', 2: 'a', 3: 'c'}) == {'a': [1, 2], 'c': [3]}
        assert dict_inverse({1: 'a', 2: 'b', 3: 'c'}, True) == {'a': 1, 'b': 2, 'c': 3}

    def test_simplecontextmanager(self):
        before = None
        after = None

        @simplecontextmanager
        def foo():
            nonlocal before
            nonlocal after
            after = None
            before = True
            yield 1
            after = True

        with foo() as x:
            assert x == 1
            assert before
            assert after is None
        assert before
        assert after

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
                raise Exception('check')
        except Exception as exc:
            assert exc.args == ('check', )
            assert before
            assert after
        else:
            assert False

    def test_simplecontextmanager_double_yield(self):
        before = None
        after = None

        @simplecontextmanager
        def foo():
            nonlocal before
            nonlocal after
            after = None
            before = True
            yield 1
            yield 2
            after = True

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
        except RuntimeError as exc:
            assert exc.args == ("generator didn't stop", )
        else:
            assert False

    def test_simplecontextmanager_raise(self):
        before = None
        after = None

        @simplecontextmanager
        def foo():
            nonlocal before
            nonlocal after
            after = None
            before = True
            yield 1
            raise Exception("with")

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
        except Exception as exc:
            assert exc.args == ('with', )
            assert before
            assert after is None
        else:
            assert False

        try:
            with foo() as x:
                assert x == 1
                assert before
                assert after is None
                raise Exception("check")
        except Exception as exc:
            assert exc.args == ('check', )
            assert before
            assert after is None
        else:
            assert False

    def test_tempdir(self):
        tempdir_name = None
        with tempdir() as t:
            tempdir_name = t
            assert os.path.exists(tempdir_name)

        assert not os.path.exists(tempdir_name)

        try:
            with tempdir() as t:
                tempdir_name = t
                assert os.path.exists(tempdir_name)
                raise Exception('tempdir_with_fail')
        except Exception as exc:
            assert exc.args == ('tempdir_with_fail', )
        else:
            assert False

        assert not os.path.exists(tempdir_name)
<|endoftext|>


<commit_before># -*- encoding: utf-8 -*-
##############################################################################
#
#    Author: Mag Guevara. Copyright ClearCorp SA
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import orm, osv, fields
from copy import copy
from tools.translate import _

class AccountMulticompanyRelation(orm.Model):

    _name = "account.multicompany.relation"
    _description = "Account multicompany relation"

    _columns = {
        'name':fields.char('Name',size=64,required=True,help='Name for the mirror object relation'),
        'origin_account':fields.many2one('account.account','Original Account',required=True,help='Indicate the original account where the transaction is taking place'),
        'targ_account':fields.many2one('account.account','Target Account',required=True,help='Indicate the target account where the transaction of the original account has to be seen, this is an account from another company'),
        'origin_journal':fields.many2one('account.journal','Original Journal',required=True,help='Indicate the original journal where the transaction is taking place'),
        'targ_journal':fields.many2one('account.journal','Target Journal',required=True,help='Indicate the original account where the transaction is taking place'),
        'origin_analytic_account':fields.many2one('account.analytic.account','Original Analytic Account',required=False,help='Indicate the original analytic account where the transaction is taking place'),
        'targ_analytic_account':fields.many2one('account.analytic.account','Target Analytic Account',required=False,help='Indicate the target analytic account where the transaction of the original analytic account has to be seen, this is an analytic account from another company'),
    }

    _sql_constraints = [
        (
            'unique_name',
            'unique(name)',
            'The name must be unique'
        ),
        (
            'unique_mirror_relation',
            'unique(origin_account,origin_journal,origin_analytic_account)',
            'A relation exists already'
        )
    ]

    def _check_unique_mirror_relation(self, cr, uid, ids, context=None):
        exist = False
        all_mirrors_ids = self.search(cr, uid, [], context)
        all_mirrors = self.browse(cr, uid, all_mirrors_ids, context)
        for mirror_id in ids:
            mirror = self.browse(cr, uid, mirror_id, context)
            if not mirror.origin_analytic_account:
                for current_mirror in all_mirrors:
                    if current_mirror.origin_account.id == mirror.origin_account.id and current_mirror.origin_journal.id == mirror.origin_journal.id:
                        if not current_mirror.origin_analytic_account:
                            return False
        return True

    _constraints = [
        (
            _check_unique_mirror_relation,
            'A relation exists already', ['origin_analytic_account']
        )
    ]

class AccountMoveLine(orm.Model):

    _inherit = 'account.move.line'

    _columns = {
                'move_mirror_rel_id':fields.many2one('account.move','Move Multicompany Relation'),
                }

    def copy(self, cr, uid, id, default={}, context=None):
        default.update({
            'move_mirror_rel_id':False,
        })

class AccountMove(orm.Model):

    _inherit = 'account.move'

    def button_cancel(self, cr, uid, ids, context=None):
        self.pool.get('account.move.reconcile')
        for move in self.browse(cr, uid, ids, context=context):
            if not move.journal_id.update_posted:
                raise osv.except_osv(_('Error !'), _('You can not modify a posted entry of this journal !\nYou should set the journal to allow cancelling entries if you want to do that.'))

            #Set user administrator to run this portion of code
            uid = 1
            for line in move.line_id:
                if line.move_mirror_rel_id:
                    move_mirror = self.browse(cr, uid, line.move_mirror_rel_id.id, context=context)
                    if not move_mirror.journal_id.update_posted:
                        raise osv.except_osv(_('Error !'), _('You can not modify a posted multicompany mirror entry of this journal !\nYou should set the journal to allow cancelling entries if you want to do that.'))

            move_reconcile_obj = self.pool.get('account.move.reconcile')

            for line in move.line_id:
                if line.move_mirror_rel_id:
                    move_mirror = self.browse(cr, uid, line.move_mirror_rel_id.id, context=context)

                    for line_mirror in move_mirror.line_id:
                        if line_mirror.reconcile_id:
                            reconcile = line_mirror.reconcile_id
                            if len(reconcile.line_id) > 2:
                                self.pool.get('account.move.line').write(cr,uid,reconcile.line_id,{'reconcile_id': False, 'reconcile_partial_id':reconcile.id})
                                self.pool.get('account.move.line').write(cr,uid,line_mirror.id,{'reconcile_partial_id': False})
                            else:
                                move_reconcile_obj.unlink(cr,uid,[reconcile.id],context=context)

                        elif line_mirror.reconcile_partial_id:
                            reconcile = line_mirror.reconcile_partial_id
                            if len(reconcile.line_partial_ids) > 2:
                                self.pool.get('account.move.line').write(cr,uid,line_mirror.id,{'reconcile_partial_id': False })
                            else:
                                move_reconcile_obj.unlink(cr,uid,[reconcile.id],context=context)

                    cr.execute('UPDATE account_move '\
                               'SET state=%s '\
                               'WHERE id IN %s', ('draft', tuple([move_mirror.id]),))
                    self.button_cancel(cr,uid,[move_mirror.id],context=context)
                    self.unlink(cr,uid,[move_mirror.id],context=context)

        result = super(AccountMove, self).button_cancel(cr, uid, ids, context=context)
        return True

    def post(self, cr, uid, ids, context=None):
        result = super(AccountMove, self).post(cr, uid, ids, context=context)

        for move_id_original in ids:
            if self.pool.get('account.move').search(cr, 1, [('move_reverse_id', '=', move_id_original)], context=context):
                continue

            original_move = self.pool.get('account.move').browse(cr, 1, move_id_original, context=context)

            if original_move.line_id:
                mirror_selected = False

                for line in original_move.line_id:
                    if line.move_mirror_rel_id:
                        if original_move.move_reverse_id:
                            self.pool.get('account.move').reverse(cr, 1, [line.move_mirror_rel_id.id], context={})
                        continue
                    mirror_selected_list_ids = self.pool.get('account.multicompany.relation').search(cr, 1, [('origin_account', '=', line.account_id.id), ('origin_journal', '=', line.journal_id.id)], context=context)
                    move_id = False
                    if len(mirror_selected_list_ids) > 0:
                        mirror_selected_list = self.pool.get('account.multicompany.relation').browse(cr, 1, mirror_selected_list_ids, context=context)

                        for mirror in mirror_selected_list:
                            if line.account_id and line.account_id.id == mirror.origin_account.id and line.journal_id.id == mirror.origin_journal.id:
                                if mirror.origin_analytic_account:
                                    if line.analytic_account_id and line.analytic_account_id.id == mirror.origin_analytic_account:
                                        mirror_selected = mirror
                                        break
                                elif not mirror_selected:
                                    mirror_selected = mirror

                        if mirror_selected:
                            origin_journal = mirror_selected.origin_journal
                            origin_account = mirror_selected.origin_account
                            targ_journal =  mirror_selected.targ_journal
                            targ_account = mirror_selected.targ_account
                        else:
                            return result

                        #Set period for target move with the correct company
                        if context == None:
                            context_copy = {'company_id': targ_account.company_id.id}
                        else:
                            context_copy = copy(context)
                            context_copy.update({'company_id': targ_account.company_id.id})

                        periods = self.pool.get('account.period').find(cr, 1, dt=original_move.date, context=context_copy)
                        if periods:
                            move_period = periods[0]

                        move = {
                                'name':'MCR: ' + original_move.name,
                                'ref':original_move.ref,
                                'journal_id':targ_journal.id,
                                'period_id':move_period or False,
                                'to_check':False,
                                'partner_id':original_move.partner_id.id,
                                'date':original_move.date,
                                'narration':original_move.narration,
                                'company_id':targ_account.company_id.id,
                                }
                        move_id = self.pool.get('account.move').create(cr, 1, move)
                        self.pool.get('account.move.line').write(cr, uid, [line.id], {'move_mirror_rel_id' : move_id})

                        analytic_account_id = ''
                        if line.analytic_account_id and line.analytic_account_id == mirror_selected.origin_analytic_account:
                            analytic_account_id = mirror_selected.targ_analytic_account.id

                        move_line_one = {
                                         'name':line.name,
                                         'debit':line.credit,
                                         'credit':line.debit,
                                         'account_id':targ_account.id,
                                         'move_id': move_id,
                                         'amount_currency':line.amount_currency * -1,
                                         'period_id':move_period or False,
                                         'journal_id':targ_journal.id,
                                         'partner_id':line.partner_id.id,
                                         'currency_id':line.currency_id.id,
                                         'date_maturity':line.date_maturity,
                                         'date':line.date,
                                         'date_created':line.date_created,
                                         'state':'valid',
                                         'analytic_account_id':analytic_account_id,
                                         'company_id':targ_account.company_id.id,
                                         }

                        self.pool.get('account.move.line').create(cr, 1, move_line_one)
                        if line.debit != 0.0:
                            move_line_two_account_id = targ_journal.default_credit_account_id
                        else:
                            move_line_two_account_id = targ_journal.default_debit_account_id

                        move_line_two = {
                                         'name':line.name,
                                         'debit':line.debit,
                                         'credit':line.credit,
                                         'account_id':move_line_two_account_id.id,
                                         'move_id': move_id,
                                         'amount_currency':line.amount_currency,
                                         'journal_id':targ_journal.id,
                                         'period_id':move_period or False,
                                         'partner_id':line.partner_id.id,
                                         'currency_id':line.currency_id.id,
                                         'date_maturity':line.date_maturity,
                                         'date':line.date,
                                         'date_created':line.date_created,
                                         'state':'valid',
                                         'analytic_account_id':analytic_account_id,
                                         'company_id':targ_account.company_id.id,
                                         }
                        self.pool.get('account.move.line').create(cr, 1, move_line_two)

                        #Posted mirror
                        self.pool.get('account.move').post(cr, 1, [move_id], context={})
                    if move_id and original_move.move_reverse_id:
                        self.pool.get('account.move').reverse(cr, 1, [move_id], context={})
        return result

    def unlink(self, cr, uid, ids, context=None, check=True):
        for move in self.browse(cr, 1, ids, context=context):
            for line in move.line_id:
                if line.move_mirror_rel_id:
                    self.pool.get('account.move').button_cancel(cr, 1, [line.move_mirror_rel_id.id])
                    result = super(AccountMove, self).unlink(cr, 1, [line.move_mirror_rel_id.id], context=context, check=check)
        result = super(AccountMove, self).unlink(cr, 1, ids, context=context, check=check)
        return result
<commit_msg>[FIX] some code improvements, started refactor of MCR selection in account_multicompany_relation.py<commit_after># -*- encoding: utf-8 -*-
##############################################################################
#
#    Author: Mag Guevara. Copyright ClearCorp SA
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import orm, osv, fields
from copy import copy
from tools.translate import _

class AccountMulticompanyRelation(orm.Model):

    _name = "account.multicompany.relation"
    _description = "Account multicompany relation"

    _columns = {
        'name':fields.char('Name',size=64,required=True,help='Name for the mirror object relation'),
        'origin_account':fields.many2one('account.account','Original Account',required=True,help='Indicate the original account where the transaction is taking place'),
        'targ_account':fields.many2one('account.account','Target Account',required=True,help='Indicate the target account where the transaction of the original account has to be seen, this is an account from another company'),
        'origin_journal':fields.many2one('account.journal','Original Journal',required=True,help='Indicate the original journal where the transaction is taking place'),
        'targ_journal':fields.many2one('account.journal','Target Journal',required=True,help='Indicate the original account where the transaction is taking place'),
        'origin_analytic_account':fields.many2one('account.analytic.account','Original Analytic Account',required=False,help='Indicate the original analytic account where the transaction is taking place'),
        'targ_analytic_account':fields.many2one('account.analytic.account','Target Analytic Account',required=False,help='Indicate the target analytic account where the transaction of the original analytic account has to be seen, this is an analytic account from another company'),
    }

    _sql_constraints = [
        (
            'unique_name',
            'unique(name)',
            'The name must be unique'
        ),
    ]

    def _check_unique_mirror_relation(self, cr, uid, ids, context=None):
        for relation in self.browse(cr, uid, ids, context=context):
            relation_ids = self.search(cr, uid, [('origin_account','=',relation.origin_account),
                                                 ('origin_journal','=',relation.origin_journal),
                                                 ('origin_analytic_account','=',relation.origin_analytic_account)], context=context)
            if len(relation_ids) >= 2:
                return False
            elif len(relation_ids) == 1 and not relation_ids[0] == relation.id:
                return False
        return True

    _constraints = [
        (
            _check_unique_mirror_relation,
            'The same relation already exists', ['origin_account','origin_journal','origin_analytic_account']
        )
    ]

class AccountMoveLine(orm.Model):

    _inherit = 'account.move.line'

    _columns = {
                'move_mirror_rel_id':fields.many2one('account.move','Move Multicompany Relation'),
                }

    def copy(self, cr, uid, id, default={}, context=None):
        default.update({
            'move_mirror_rel_id':False,
        })

class AccountMove(orm.Model):

    _inherit = 'account.move'

    def button_cancel(self, cr, uid, ids, context=None):
        self.pool.get('account.move.reconcile')
        for move in self.browse(cr, uid, ids, context=context):
            if not move.journal_id.update_posted:
                raise osv.except_osv(_('Error !'), _('You can not modify a posted entry of this journal !\nYou should set the journal to allow cancelling entries if you want to do that.'))

            #Set user administrator to run this portion of code
            uid = 1
            for line in move.line_id:
                if line.move_mirror_rel_id:
                    move_mirror = self.browse(cr, uid, line.move_mirror_rel_id.id, context=context)
                    if not move_mirror.journal_id.update_posted:
                        raise osv.except_osv(_('Error !'), _('You can not modify a posted multicompany mirror entry of this journal !\nYou should set the journal to allow cancelling entries if you want to do that.'))

            move_reconcile_obj = self.pool.get('account.move.reconcile')

            for line in move.line_id:
                if line.move_mirror_rel_id:
                    move_mirror = self.browse(cr, uid, line.move_mirror_rel_id.id, context=context)

                    for line_mirror in move_mirror.line_id:
                        if line_mirror.reconcile_id:
                            reconcile = line_mirror.reconcile_id
                            if len(reconcile.line_id) > 2:
                                self.pool.get('account.move.line').write(cr,uid,reconcile.line_id,{'reconcile_id': False, 'reconcile_partial_id':reconcile.id})
                                self.pool.get('account.move.line').write(cr,uid,line_mirror.id,{'reconcile_partial_id': False})
                            else:
                                move_reconcile_obj.unlink(cr,uid,[reconcile.id],context=context)

                        elif line_mirror.reconcile_partial_id:
                            reconcile = line_mirror.reconcile_partial_id
                            if len(reconcile.line_partial_ids) > 2:
                                self.pool.get('account.move.line').write(cr,uid,line_mirror.id,{'reconcile_partial_id': False })
                            else:
                                move_reconcile_obj.unlink(cr,uid,[reconcile.id],context=context)

                    cr.execute('UPDATE account_move '\
                               'SET state=%s '\
                               'WHERE id IN %s', ('draft', tuple([move_mirror.id]),))
                    self.button_cancel(cr,uid,[move_mirror.id],context=context)
                    self.unlink(cr,uid,[move_mirror.id],context=context)

        result = super(AccountMove, self).button_cancel(cr, uid, ids, context=context)
        return True

    def post(self, cr, uid, ids, context=None):
        result = super(AccountMove, self).post(cr, uid, ids, context=context)

        for move_id_original in ids:
            account_move_obj = self.pool.get('account.move')
            account_move_line_obj = self.pool.get('account.move.line')
            account_multicompany_relation_obj = self.pool.get('account.multicompany.relation')
            #Continue if this is a reversion move
            if account_move_obj.search(cr, 1, [('move_reverse_id', '=', move_id_original)], context=context):
                continue

            original_move = account_move_obj.browse(cr, 1, move_id_original, context=context)
            if original_move.line_id:
                mirror_selected = False
                for line in original_move.line_id:
                    if line.move_mirror_rel_id:
                        if original_move.move_reverse_id:
                            account_move_obj.reverse(cr, 1, [line.move_mirror_rel_id.id], context={})
                        continue

                    #Get parent accounts for line account
                    parent_account_ids = []
                    parent_account = line.account_id.parent_account_id
                    while parent_account:
                        parent_account_ids.append(parent_account.id)
                        parent_account = parent_account.parent_account_id
                    mirror_selected_list_ids = account_multicompany_relation_obj.search(cr, 1, [('origin_account', 'in', parent_account_ids), ('origin_journal', '=', line.journal_id.id)], context=context)
                    move_id = False
                    if len(mirror_selected_list_ids) > 0:
                        mirror_selected_list = account_multicompany_relation_obj.browse(cr, 1, mirror_selected_list_ids, context=context)

                        for mirror in mirror_selected_list:
                            if line.account_id and line.account_id.id == mirror.origin_account.id and line.journal_id.id == mirror.origin_journal.id:
                                if mirror.origin_analytic_account:
                                    if line.analytic_account_id and line.analytic_account_id.id == mirror.origin_analytic_account:
                                        mirror_selected = mirror
                                        break
                                elif not mirror_selected:
                                    mirror_selected = mirror

                        if mirror_selected:
                            origin_journal = mirror_selected.origin_journal
                            origin_account = mirror_selected.origin_account
                            targ_journal =  mirror_selected.targ_journal
                            targ_account = mirror_selected.targ_account
                        else:
                            continue

                        #Set period for target move with the correct company
                        if context == None:
                            context_copy = {'company_id': targ_account.company_id.id}
                        else:
                            context_copy = copy(context)
                            context_copy.update({'company_id': targ_account.company_id.id})

                        periods = self.pool.get('account.period').find(cr, 1, dt=original_move.date, context=context_copy)
                        if periods:
                            move_period = periods[0]

                        move = {
                            'name':'MCR: ' + original_move.name,
                            'ref':original_move.ref,
                            'journal_id':targ_journal.id,
                            'period_id':move_period or False,
                            'to_check':False,
                            'partner_id':original_move.partner_id.id,
                            'date':original_move.date,
                            'narration':original_move.narration,
                            'company_id':targ_account.company_id.id,
                        }
                        move_id = account_move_obj.create(cr, 1, move)
                        self.pool.get('account.move.line').write(cr, uid, [line.id], {'move_mirror_rel_id' : move_id})

                        analytic_account_id = ''
                        if line.analytic_account_id and line.analytic_account_id == mirror_selected.origin_analytic_account:
                            analytic_account_id = mirror_selected.targ_analytic_account.id

                        move_line_one = {
                            'name':line.name,
                            'debit':line.credit,
                            'credit':line.debit,
                            'account_id':targ_account.id,
                            'move_id': move_id,
                            'amount_currency':line.amount_currency * -1,
                            'period_id':move_period or False,
                            'journal_id':targ_journal.id,
                            'partner_id':line.partner_id.id,
                            'currency_id':line.currency_id.id,
                            'date_maturity':line.date_maturity,
                            'date':line.date,
                            'date_created':line.date_created,
                            'state':'valid',
                            'analytic_account_id':analytic_account_id,
                            'company_id':targ_account.company_id.id,
                        }

                        account_move_line_obj.create(cr, 1, move_line_one)
                        if line.debit != 0.0:
                            move_line_two_account_id = targ_journal.default_credit_account_id
                        else:
                            move_line_two_account_id = targ_journal.default_debit_account_id

                        move_line_two = {
                                         'name':line.name,
                                         'debit':line.debit,
                                         'credit':line.credit,
                                         'account_id':move_line_two_account_id.id,
                                         'move_id': move_id,
                                         'amount_currency':line.amount_currency,
                                         'journal_id':targ_journal.id,
                                         'period_id':move_period or False,
                                         'partner_id':line.partner_id.id,
                                         'currency_id':line.currency_id.id,
                                         'date_maturity':line.date_maturity,
                                         'date':line.date,
                                         'date_created':line.date_created,
                                         'state':'valid',
                                         'analytic_account_id':analytic_account_id,
                                         'company_id':targ_account.company_id.id,
                                         }
                        account_move_line_obj.create(cr, 1, move_line_two)

                        #Posted mirror
                        account_move_obj.post(cr, 1, [move_id], context={})
                    if move_id and original_move.move_reverse_id:
                        account_move_obj.reverse(cr, 1, [move_id], context={})
        return result

    def unlink(self, cr, uid, ids, context=None, check=True):
        for move in self.browse(cr, 1, ids, context=context):
            for line in move.line_id:
                if line.move_mirror_rel_id:
                    self.pool.get('account.move').button_cancel(cr, 1, [line.move_mirror_rel_id.id])
                    result = super(AccountMove, self).unlink(cr, 1, [line.move_mirror_rel_id.id], context=context, check=check)
        result = super(AccountMove, self).unlink(cr, 1, ids, context=context, check=check)
        return result
<|endoftext|>