from datetime import datetime
from datetime import timedelta
from re import search
from csv import writer
from sqlite3 import connect

class Log:
    def __str__(self):
        return "FACRY's  LOG"

    def __init__(self, log_file_pathname, data_base_file_path_name):
        self.log_file_pathname = log_file_pathname
        self.data_base_file_path_name = data_base_file_path_name
        self.log_data = self.read_log_file()
        self.cvar_dictionary = self.get_cvar_dictionary()
        self.start_time = self.parse_log_start_time()
        self.map_name, self.mode_name = self.parse_session_mode_and_map()
        self.frags, self.delta = self.parse_frags()
        self.prettified_frags = self.prettify_frags()
        self.session_start_time, self.session_end_time = self. \
            parse_game_session_start_and_end_times()
        self.data_base = connect(self.data_base_file_path_name)
        self.cursor = self.data_base.cursor()

    def read_log_file(self):
        """
        return bytes object
        :param log_file_pathname: path to the log_file file
        :return: string object
        """
        try:
            with open(self.log_file_pathname, 'r') as data:
                return data.read().split('\n')
        except OSError:
            return ''

    def get_cvar_dictionary(self):
        """
        read the log data, if a line contain cvar, get its name as a key and
        its value as a value in cvar_dictionary
        :return: dictionary
        """
        cvar_dictionary = {}
        for line in self.log_data:
            if 'cvar' in line:
                try:
                    name, value = search('[(](.*)[)]', line).groups()[0]. \
                        split(',')
                    cvar_dictionary[name] = value
                except ValueError:
                    pass
        return cvar_dictionary

    def parse_log_start_time(self):
        """
        get a date_time object by read the first line of the log_file
        :return: date_time object
        """
        start_time_info = self.log_data[0][2:]
        time_zone = self.cvar_dictionary['g_timezone']  # type: string
        if len(time_zone) == 2:
            time_zone = time_zone[0] + '0' + time_zone[1] + '00'
        else:
            time_zone = '+' + '0' + time_zone + '00'
        start_time_info += time_zone
        for index, charactor in enumerate(start_time_info):
            if charactor == ',':
                return datetime.strptime(start_time_info[index + 2:],
                                         '%B %d, %Y %H:%M:%S%z')

    def parse_session_mode_and_map(self):
        """
        get map and mode name
        :param log_data: string
        :return: tuple
        """
        for line in self.log_data:
            if 'Loading level' in line:
                map, mode = search('.*Levels/(.*), mission (.*) .*',
                                   line).groups()
                return map, mode

    def check_if_hour_increase(self,
                               current_time,
                               flag):
        """
        get current_time and flag as 2 string reference for current line's time
        and the last line's time, compare them if current time is smaller than
        flag that mean the hour increase 1
        :param current_time: string
        :param flag: string
        :return: Boolean
        """
        flag_minute, flag_second = flag.split(':')
        current_time_minute, current_time_second = current_time.split(':')
        if int(current_time_minute) > int(flag_minute):
            return False
        elif int(current_time_minute) < int(flag_minute):
            return True
        else:
            if int(current_time_second) > int(flag_second):
                return False
            elif int(current_time_second) < int(flag_second):
                return True

    def increase_time(self,
                      current_time,
                      delta_hour,
                      delta_day):
        """
        get current as a string("<nn:nn>"), return a datetime object base on
        delta hour and delta day.
        :param current_time: string
        :param delta_hour: int
        :param delta_day: int
        :return: datetime object
        """
        start_time = self.start_time
        current_minute, current_second = current_time.split(':')
        current_time = start_time.replace(minute=int(current_minute),
                                          second=int(current_second)) + \
                                          timedelta(hours=delta_hour,
                                                    days=delta_day)
        return current_time

    def parse_frags(self):
        """
        get data from log file and return a list of kill information. Kill
        information is a tuple contain time, killer, weapon and victim. If
        there some suicided, the kill information only contain time and his
        name
        :param log_data: string
        :return: list
        """
        delta_hour = 0
        delta_day = 0
        kill_infomation_list = []
        flag = '00:00'
        for line in self.log_data:
            kill_infomation = line.split()
            try:
                kill_infomation[0] = kill_infomation[0][1:-1]
            except IndexError:
                continue
            if not search('[0-9][0-9]:[0-9][0-9]',
                          kill_infomation[0]):
                continue
            if 'itself' in kill_infomation:
                kill_infomation = kill_infomation[:3]
                kill_infomation.pop(1)
            elif 'killed' in line and 'with' in line:
                kill_infomation = [x for x in kill_infomation if x
                                   not in ['killed',
                                           'with',
                                           '<Lua>']]
            else:
                try:
                    if self.check_if_hour_increase(kill_infomation[0],
                                                   flag):
                        delta_hour += 1
                    flag = kill_infomation[0]
                    continue
                except (ValueError, IndexError):
                    continue
            if self.check_if_hour_increase(kill_infomation[0],
                                           flag):
                delta_hour += 1
            flag = kill_infomation[0]
            kill_infomation[0] = self.increase_time(kill_infomation[0],
                                                    delta_hour,
                                                    delta_day)
            kill_infomation_list.append(tuple(kill_infomation))
            if delta_hour > 24:
                delta_day += 1
        return kill_infomation_list, [delta_hour, delta_day]

    def prettify_frags(self):
        def get_emoji_dictionary():
            """
            Return a dictionary with the key is weapon code and value is the
            emoji
            :return: dictionary
            """
            emoji_dictionary = {}
            emoji_data = [['🚙', 'Vehicle'],
                          ['🔫', 'Falcon', 'Shotgun', 'P90', 'MP5', 'M4',
                           'AG36', 'OICW', 'SniperRifle', 'M249',
                           'MG', 'VehicleMountedAutoMG',
                           'VehicleMountedMG'],
                          ['💣', 'HandGrenade', 'AG36Grenade',
                           'OICWGrenade', 'StickyExplosive'],
                          ['🚀', 'Rocket', 'VehicleMountedRocketMG',
                           'VehicleRocket'],
                          ['🔪', 'Machete'],
                          ['🚤', 'Boat']]
            for data in emoji_data:
                emoji = data[0]
                for weapon_code in data[1:]:
                    emoji_dictionary[weapon_code] = emoji
            return emoji_dictionary

        def handle_frags(frag,
                         prettified_frag_list,
                         emoji_dictionary):
            """
            get list of prettified_frags(string) and
            :param prettified_frag_list: list of string
            :param emoji_dictionary: dictionary
            :return:
            """
            if len(frag) > 2:
                prettified_frag = '[' + str(frag[0]) + ']' + \
                                  ' 🙂  ' + frag[1] + ' ' + \
                                  emoji_dictionary[frag[3]] + \
                                  '  ☹  ' + \
                                  frag[2]
                prettified_frag_list.append(prettified_frag)
            else:
                prettified_frag = '[' + str(frag[0]) + ']' + \
                                  ' ☹  ' + frag[1] + ' ☠  '
                prettified_frag_list.append(prettified_frag)
            return prettified_frag_list

        emoji_dictionary = get_emoji_dictionary()
        prettify_frag_list = []
        for frag in self.frags:
            prettify_frag_list = handle_frags(frag,
                                              prettify_frag_list,
                                              emoji_dictionary)
        return prettify_frag_list

    def parse_game_session_start_and_end_times(self):
        for line in self.log_data:
            if search('<[0-9][0-9]:[0-9][0-9]>  Level ' +
                      self.map_name + ' loaded in .* seconds', line):
                session_start_time = line.split()[0][1:-1]
            elif 'Statistics' in line:
                session_end_time = line.split()[0][1:-1]
        session_start_time = self.increase_time(session_start_time, 0, 0)
        try:
            session_end_time
        except ValueError:
            session_end_time = self.log_data[-1].split('')[0][-1:1]
        session_end_time = self.increase_time(session_end_time,
                                              self.delta[0],
                                              self.delta[1])
        return session_start_time, session_end_time

    def write_frag_csv_file(self):
        """
        open a file and write csv data in it
        :return: None
        """
        with open('logs/log.csv', 'w') as csvFile:
            for line in self.frags:
                data = writer(csvFile)
                data.writerow(line)
            csvFile.close()

    def insert_match_to_sqlite(self):
        data = (self.session_start_time,
                self.session_end_time,
                self.mode_name,
                self.map_name)
        self.cursor.execute \
            ('''INSERT INTO match(Start_time,
            End_time, Game_mode, Map_name) VALUES (?,?,?,?)''', data)
        self.data_base.commit()
        return self.cursor.lastrowid

    def insert_frag_to_sqlite(self):
        match_id = self.insert_match_to_sqlite()
        for frag in self.frags:
            frag = tuple([match_id] + list(frag))
            if len(frag) == 5:
                self.cursor.execute \
                    ('''INSERT INTO Match_frag(Match_id,
                    Frag_time, Killer_name, Victim_name,
                    Weapon_code) VALUES (?,?,?,?,?)''', frag)
            else:
                self.cursor.execute \
                    ('''INSERT INTO Match_frag(Match_id,
                    Frag_time, Killer_name) VALUES (?,?,?)''', frag)
        self.data_base.commit()
        self.data_base.close()

if __name__ == '__main__':
    log = Log('logs/log.txt', 'farcry')


# -*- coding: utf-8 -*-

from flectra import models, fields, api, exceptions, _
from pprint import pprint
from datetime import datetime, date
import calendar
from flectra.exceptions import UserError, ValidationError

class calon_siswa(models.Model):
    _name = 'siswa_psb_ocb11.calon_siswa'

    state = fields.Selection([('draft', 'Draft'), ('reg', 'Registered')], string='State', required=True, default='draft')
    is_siswa_lama = fields.Boolean('Siswa Lama', default=False)
    siswa_id = fields.Many2one('res.partner', string="Data Siswa Lama", ondelete="restrict")
    no_induk = fields.Char('No. Induk', related="siswa_id.induk")
    registered_siswa_id = fields.Many2one('res.partner', string="Registered Siswa")
    tahunajaran_id = fields.Many2one('siswa_ocb11.tahunajaran', string='Tahun Ajaran', required=True, default=lambda self: self.env['siswa_ocb11.tahunajaran'].search([('active', '=', True)]))
    name = fields.Char('Nama', required=True)
    reg_number = fields.Char('Nomor Registrasi', required=True, default='New')
    street = fields.Char()
    street2 = fields.Char()
    zip = fields.Char()
    city = fields.Char()
    state_id = fields.Many2one("res.country.state", string='State')
    country_id = fields.Many2one('res.country', string='Country')
    phone = fields.Char()
    mobile = fields.Char()
    jenjang_id = fields.Many2one('siswa_ocb11.jenjang', string='Jenjang', required=True)
    tanggal_registrasi = fields.Date('Tanggal Registrasi', required=True, default=datetime.today().date())
    tahunajaran_id = fields.Many2one('siswa_ocb11.tahunajaran', string='Tahun Diterima')
    induk = fields.Char(string='Internal Reference', required=False, copy=False, readonly=True, default="New")
    nis = fields.Char(string="NIS", required=False)
    panggilan = fields.Char(string="Panggilan")
    jenis_kelamin = fields.Selection([('laki', 'Laki-laki'), ('perempuan', 'Perempuan')], string='Jenis Kelamin', required=True)
    tanggal_lahir = fields.Date(string='Tanggal Lahir', required=False)
    tempat_lahir = fields.Char(string='Tempat Lahir', required=False)
    alamat = fields.Char(string='Alamat')
    telp = fields.Char(string='Telp')
    ayah = fields.Char(string='Ayah')
    pekerjaan_ayah_id = fields.Many2one('siswa_ocb11.pekerjaan', string='Pekerjaan Ayah')
    telp_ayah = fields.Char(string='Telp. Ayah')
    ibu = fields.Char(string='Ibu')
    pekerjaan_ibu_id = fields.Many2one('siswa_ocb11.pekerjaan', string='Pekerjaan Ibu')
    telp_ibu = fields.Char(string='Telp. Ibu')
    rombels = fields.One2many('siswa_ocb11.rombel_siswa', inverse_name='siswa_id' , string='Detail Rombongan Belajar')
    active_rombel_id = fields.Many2one('siswa_ocb11.rombel', string='Rombongan Belajar', compute='_compute_rombel', store=True)
    is_siswa = fields.Boolean(default=False)
    mutasi = fields.Boolean(string='Mutasi', default=False)
    lulus = fields.Boolean(string='Lulus', default=False)
    non_aktif_selection = fields.Selection([('mutasi', 'Mutasi'), ('lulus', 'Lulus'), ('meninggal', 'Meninggal Dunia')], string='Keterangan')
    tanggal_non_aktif = fields.Date('Tanggal Non Aktif')
    anak_ke = fields.Integer('Anak ke')
    dari_bersaudara = fields.Integer('Dari Bersaudara')
    usia = fields.Float('Usia', compute="_compute_usia", store=True)
    is_distributed = fields.Boolean('is distributed', default=False)
    rombel_id = fields.Many2one('siswa_ocb11.rombel', string='Rombongan Belajar', domain="[('jenjang_id','=',jenjang_id)]")
    pembayaran_lines = fields.One2many('siswa_psb_ocb11.calon_siswa_biaya',
                    inverse_name='calon_siswa_id',
                    string='Pembayaran')
    biaya_lines = fields.One2many('siswa_biaya_ta_jenjang_on_calon_siswa_rel',
                    inverse_name='calon_siswa_id',
                    string='Biaya')
#     biaya_lines = fields.Many2many('siswa_keu_ocb11.biaya_ta_jenjang',
#                                             relation='siswa_biaya_ta_jenjang_on_calon_siswa_rel',
#                                             column1='calon_siswa_id',
#                                             column2='biaya_ta_jenjang_id',
#                                             string="Biaya")

    biaya_optional_ids = fields.Many2many('siswa_keu_ocb11.biaya_ta_jenjang',
                        relation='siswa_biaya_optional_on_calon_siswa_rel',
                        column1='calon_siswa_id', column2='biaya_ta_jenjang_id',
                        string="Biaya Opsional")
#     biaya_optional_ids = fields.Many2many('siswa_keu_ocb11.biaya',
#                         relation='siswa_psb_ocb11_biaya_optional_calon_siswa_rel',
#                         column1='calon_siswa_id', column2='biaya_id',
#                         string="Biaya Opsional", ondelete="cascade")
    total = fields.Float('Total Bayar')
    terbilang = fields.Char('Terbilang')
    satuan = ['', 'satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh',
          'delapan', 'sembilan', 'sepuluh', 'sebelas']
    bayar_tunai = fields.Float('Bayar Tunai', default=0.0)
    total_biaya = fields.Float('Total Biaya')

    @api.depends('tanggal_lahir')
    def _compute_usia(self):
        print('inside compute usia')

    def calculate_bayar_tunai(self):
        print('inside calculate bayar tunai')
        total_harus_bayar = sum(map(lambda x: x.jumlah_harga_setelah_potongan, self.pembayaran_lines))
        tunai = self.bayar_tunai
        if tunai > total_harus_bayar:
            raise ValidationError(_('Jumlah bayar tunai melebihi jumlah tagihan.'))
        else:
            print('Bayar Tunai : ' + str(tunai))
            for pay in self.pembayaran_lines:
                if tunai > 0 :
                    if tunai > ((pay.harga * pay.qty) - pay.potongan_harga) :
                        # pay.dibayar = pay.harga - pay.potongan_harga
    #                     pay.write({
    #                             'dibayar' : (pay.harga * pay.qty) - pay.potongan_harga,
    #                         })
                        pay.dibayar = (pay.harga * pay.qty) - pay.potongan_harga
                        tunai -= (pay.harga * pay.qty) - pay.potongan_harga
                        print('inside calculate bayar tunai on first if')
                        print('dibayar : ' + str((pay.harga * pay.qty) - pay.potongan_harga))
                    else:
                        # pay.dibayar = tunai
    #                     pay.write({
    #                         'dibayar' : tunai
    #                     })
                        pay.dibayar = tunai
                        print('inside calculate bayar tunai on second if')
                        print('dibayar : ' + str(tunai))
                        tunai = 0
                else:
                    pay.dibayar = 0
    #                 pay.write({
    #                     'dibayar' : 0
    #                 })
                    print('inside calculate bayar tunai on Main if')

    @api.onchange('is_siswa_lama')
    def onchange_is_siswa_lama(self):
        print('onchange is siswa lama')
        # domain = {'siswa_id':[('tahunajaran_id','!=',self.tahunajaran_id.id),('is_siswa','=',True)]}
        domain = {'siswa_id':[('is_siswa', '=', True)]}
        return {'domain':domain, 'value':{'siswa_id':[]}}

    @api.onchange('siswa_id')
    def onchange_siswa_id(self):
        # get prev tahunajaran
        prev_ta = self.env['siswa_ocb11.tahunajaran'].search([
            ('sort_order', '=', self.tahunajaran_id.sort_order - 1)
        ])

        # get rombel siswa
        rombel_siswa = self.env['siswa_ocb11.rombel_siswa'].search([
            ('tahunajaran_id', '=', prev_ta.id),
            ('siswa_id', '=', self.siswa_id.id),
        ]).rombel_id

        # set name from siswa_id & set data-data dari ssiswa lama
        self.name = self.siswa_id.name
        self.panggilan = self.siswa_id.panggilan
        self.jenis_kelamin = self.siswa_id.jenis_kelamin
        self.tempat_lahir = self.siswa_id.tempat_lahir
        self.tanggal_lahir = self.siswa_id.tanggal_lahir
        self.nis = self.siswa_id.nis
        self.anak_ke = self.siswa_id.anak_ke
        self.dari_bersaudara = self.siswa_id.dari_bersaudara
        self.street = self.siswa_id.street
        self.street2 = self.siswa_id.street2
        self.city = self.siswa_id.city
        self.state_id = self.siswa_id.state_id.id
        self.zip = self.siswa_id.zip
        self.country_id = self.siswa_id.country_id.id
        self.phone = self.siswa_id.phone
        self.mobile = self.siswa_id.mobile
        self.ayah = self.siswa_id.ayah
        self.pekerjaan_ayah_id = self.siswa_id.pekerjaan_ayah_id.id
        self.telp_ayah = self.siswa_id.telp_ayah
        self.ibu = self.siswa_id.ibu
        self.pekerjaan_ibu_id = self.siswa_id.pekerjaan_ibu_id.id
        self.telp_ibu = self.siswa_id.telp_ibu

        # filter jenjang
        domain = {'jenjang_id':[('order', '>', rombel_siswa.jenjang_id.order)]}
        return {'domain':domain, 'value':{'jenjang_id':[]}}

        # set data siswa
    # @api.onchange('siswa_id')
    # def siswa_id_onchange(self):
        self.name = self.siswa_id.name
        self.panggilan = self.siswa_id.panggilan
        self.nis = self.siswa_id.nis
        self.jenis_kelamin = self.siswa_id.jenis_kelamin
        self.tempat_lahir = self.siswa_id.tempat_lahir
        self.tanggal_lahir = self.siswa_id.tanggal_lahir
        self.anak_ke = self.siswa_id.dari_bersaudara
        self.street = self.siswa_id.street
        self.street2 = self.siswa_id.street2
        self.city = self.siswa_id.city
        self.state_id = self.siswa_id.state_id
        self.zip = self.siswa_id.zip
        self.country_id = self.siswa_id.country_id
        self.phone = self.siswa_id.phone
        self.mobile = self.siswa_id.mobile
        self.ayah = self.siswa_id.ayah
        self.pekerjaan_ayah_id = self.siswa_id.pekerjaan_ayah_id
        self.telp_ayah = self.siswa_id.telp_ayah
        self.ibu = self.siswa_id.ibu
        self.pekerjaan_ibu_id = self.siswa_id.pekerjaan_ibu_id
        self.telp_ibu = self.siswa_id.telp_ibu

    # @api.onchange('jenjan_id')
    # def onchange_jenjang_id(self): # set filter rombel_id
    #     domain = {'rombel_id':[('jenjang_id','=',self.jenjang_id)]}
    #     return {'domain':domain, 'value':{'rombel_id':[]}}

    def get_current_jenjang_id(self):
        return self.jenjang_id

    @api.model
    def create(self, vals):
        if vals.get('reg_number', _('New')) == _('New'):
            if 'company_id' in vals:
                vals['reg_number'] = self.env['ir.sequence'].with_context(force_company=vals['company_id']).next_by_code('reg.no.siswa.psb.ocb11') or _('New')
            else:
                vals['reg_number'] = self.env['ir.sequence'].next_by_code('reg.no.siswa.psb.ocb11') or _('New')

        result = super(calon_siswa, self).create(vals)
        return result

    def assign_pembayaran_to_siswa(self, siswa):
        # add pembayaran
        pembayaran = self.env['siswa_keu_ocb11.pembayaran'].create({
            'tanggal' : self.tanggal_registrasi ,
            'tahunajaran_id' : self.tahunajaran_id.id,
            'siswa_id' : siswa.id,
        })

        # reset pembayaran_lines
        pembayaran.pembayaran_lines.unlink()
        pembayaran.total = 0

        total_bayar = 0.0
        for pay in self.pembayaran_lines:

#             print('Payment Lines : ')
#             print('harga : ' + str(pay.harga))
#             print('dibayar : ' + str(pay.dibayar))
#             print('biaya_id : ' + str(pay.biaya_id.id))

            # get siswa_biaya
            if pay.dibayar > 0:  # jangan dimasukkan ke pembayaran untuk yang nilai dibayarnya = 0
                if pay.biaya_id:
                    if pay.biaya_id.is_bulanan:
                        pay_biaya_id = self.env['siswa_keu_ocb11.siswa_biaya'].search([
                                    ('siswa_id', '=', siswa.id),
                                    ('tahunajaran_id', '=', self.tahunajaran_id.id),
                                    ('biaya_id', '=', pay.biaya_id.id),
                                    ('tahunajaran_id', '=', self.tahunajaran_id.id),
                                    ('bulan', '=', pay.bulan),
                                    ]).id
                    else:
                        pay_biaya_id = self.env['siswa_keu_ocb11.siswa_biaya'].search([
                                    ('siswa_id', '=', siswa.id),
                                    ('tahunajaran_id', '=', self.tahunajaran_id.id),
                                    ('biaya_id', '=', pay.biaya_id.id),
                                    ('tahunajaran_id', '=', self.tahunajaran_id.id),
                                    ]).id

                    pembayaran.pembayaran_lines = [(0, 0, {
                                            'biaya_id' : pay_biaya_id,
                                            'bayar' : pay.dibayar
                                            })]
                    total_bayar += pay.dibayar

#             print('pay_biaya_id : ' + str(pay_biaya_id))
#             print('-------------------')

        # raise exceptions.except_orm(_('Warning'), _('TEST ERROR'))

        # confirm pembayaran
        pembayaran.action_confirm()

        # set terbilang
        if total_bayar == 0:
            self.terbilang = 'nol'
        else:
            t = self.terbilang_(total_bayar)
            while '' in t:
                t.remove('')
            self.terbilang = ' '.join(t)

        self.terbilang += ' Rupiah'
        # set total
        self.total = total_bayar

    def assign_biaya_line_to_siswa(self, siswa):
        # assign biaya to siswa
            total_biaya = 0.0
#             if self.is_siswa_lama:
#                 id_siswa = self.siswa_id.id
#             else:
#                 id_siswa = new_siswa.id

            for by_lin in self.biaya_lines:
#                 if self.is_siswa_lama and by_lin.biaya_id.is_siswa_baru_only:
#                     print('skip')
#                     continue
#                 else:
                if by_lin.biaya_id.is_bulanan:
                    for bulan_index in range(1, 13):
                        harga = by_lin.harga

#                         if by_lin.biaya_id.is_different_by_gender:
#                             if self.jenis_kelamin == 'perempuan':
#                                 harga = by_lin.harga_alt

                        # get local nama bulan
                        bulan_name = calendar.month_name[bulan_index]
                        with calendar.different_locale('id_ID.utf8'):
                            bulan_name = calendar.month_name[bulan_index]

                        new_siswa_biaya = self.env['siswa_keu_ocb11.siswa_biaya'].create({
                            'name' : by_lin.biaya_id.name + ' ' + bulan_name,
                            'siswa_id' : siswa.id,
                            'tahunajaran_id' : self.tahunajaran_id.id,
                            'biaya_id' : by_lin.biaya_id.id,
                            'bulan' : bulan_index,
                            'harga' : harga,
                            'amount_due' : harga,
                            'jenjang_id' : self.jenjang_id.id
                        })
                        total_biaya += harga

                        # add potongan biaya jika tersedia
#                         pbyr_lin = self.pembayaran_lines.search([('biaya_id', '=', by_lin.biaya_id.id)])
#                         if pbyr_lin:
                        if by_lin.potongan_harga > 0:
                            new_siswa_biaya.potongan_ids = [(0, 0, {
                                                                'siswa_id' : siswa.id,
                                                                'jumlah_potongan' : by_lin.potongan_harga
                                                            })]
                            for pot in new_siswa_biaya.potongan_ids:
                                pot.action_confirm()

                else:
                    harga = by_lin.harga

#                     if by_lin.biaya_id.is_different_by_gender:
#                         if self.jenis_kelamin == 'perempuan':
#                             harga = by_lin.harga_alt

                    new_siswa_biaya = self.env['siswa_keu_ocb11.siswa_biaya'].create({
                        'name' : by_lin.biaya_id.name,
                        'siswa_id' : siswa.id,
                        'tahunajaran_id' : self.tahunajaran_id.id,
                        'biaya_id' : by_lin.biaya_id.id,
                        'harga' : harga,
                        'amount_due' : harga,
                        'jenjang_id' : self.jenjang_id.id
                    })
                    total_biaya += harga

                    # add potongan biaya jika tersedia
                    if by_lin.potongan_harga > 0:
                        new_siswa_biaya.potongan_ids = [(0, 0, {
                                                            'siswa_id' : siswa.id,
                                                            'jumlah_potongan' : by_lin.potongan_harga
                                                        })]
                        for pot in new_siswa_biaya.potongan_ids:
                            pot.action_confirm()

#             for by in ta_jenjang.biayas:
#                 # cek biaya apakah is_optional dan apakah di pilih dalam biaya_lines
#                 by_found = False
#                 if by.biaya_id.is_optional:
#                     for by_in_pay in self.biaya_lines:
#                         if by.biaya_id.id == by_in_pay.biaya_id.id:
#                             by_found = True
#                     if not by_found:
#                         continue
#
#                 if self.is_siswa_lama and by.biaya_id.is_siswa_baru_only:
#                     print('skip')
#                     continue
#                 else:
#                     print('JENJANG ID : ' + str(self.jenjang_id.id))
#                     if by.biaya_id.is_bulanan:
#                         for bulan_index in range(1, 13):
#                             harga = by.harga
#
#                             if by.is_different_by_gender:
#                                 if self.jenis_kelamin == 'perempuan':
#                                     harga = by.harga_alt
#
#                             self.env['siswa_keu_ocb11.siswa_biaya'].create({
#                                 'name' : by.biaya_id.name + ' ' + calendar.month_name[bulan_index],
#                                 'siswa_id' : id_siswa,
#                                 'tahunajaran_id' : self.tahunajaran_id.id,
#                                 'biaya_id' : by.biaya_id.id,
#                                 'bulan' : bulan_index,
#                                 'harga' : harga,
#                                 'amount_due' : harga,
#                                 'jenjang_id' : self.jenjang_id.id
#                             })
#                             total_biaya += harga
#                     else:
#                         harga = by.harga
#
#                         if by.is_different_by_gender:
#                             if self.jenis_kelamin == 'perempuan':
#                                 harga = by.harga_alt
#
#                         self.env['siswa_keu_ocb11.siswa_biaya'].create({
#                             'name' : by.biaya_id.name,
#                             'siswa_id' : id_siswa,
#                             'tahunajaran_id' : self.tahunajaran_id.id,
#                             'biaya_id' : by.biaya_id.id,
#                             'harga' : harga,
#                             'amount_due' : harga,
#                             'jenjang_id' : self.jenjang_id.id
#                         })
#                         total_biaya += harga

            # set total_biaya dan amount_due
            print('ID SISWA : ' + str(siswa.id))
            res_partner_siswa = self.env['res.partner'].search([('id', '=', siswa.id)])
            self.env['res.partner'].search([('id', '=', siswa.id)]).write({
                'total_biaya' : total_biaya,
                'amount_due_biaya' : res_partner_siswa.amount_due_biaya + total_biaya,
            })

    def action_confirm(self):
        # check pembayaran is set or not
        if len(self.pembayaran_lines) > 0:
            total_harus_bayar = sum(map(lambda x: x.jumlah_harga_setelah_potongan, self.pembayaran_lines))
            dibayar_on_lines = sum(map(lambda x: x.dibayar, self.pembayaran_lines))
            tunai = self.bayar_tunai

            if tunai > total_harus_bayar:
                raise ValidationError(_('Jumlah bayar tunai melebihi jumlah tagihan.'))

            elif dibayar_on_lines == 0.0:
                raise ValidationError(_('Jumlah bayar tidak sesuai dengan jumlah tagihan.'))

            else:
                # register siswa to res.partner
                the_siswa = self.siswa_id

                if self.is_siswa_lama:
                    # update siswa lama
                    self.env['res.partner'].search([('id', '=', self.siswa_id.id)]).write({
                        # 'rombels' : [(0, 0,  { 'rombel_id' : self.rombel_id.id, 'tahunajaran_id' : self.tahunajaran_id.id })],
                        # 'active_rombel_id' : self.rombel_id.id,
                        'is_siswa_lama' : True,
                        'calon_siswa_id' : self.id,
                    })
                else:
                    # insert into res_partner
                    new_siswa = self.env['res.partner'].create({
                        'is_customer' : 1,
                        'name' : self.name,
                        'calon_siswa_id' : self.id,
                        'street' : self.street,
                        'street2' : self.street2,
                        'zip' : self.zip,
                        'city' : self.city,
                        'state_id' : self.state_id.id,
                        'country_id' : self.country_id.id,
                        'phone' : self.phone,
                        'mobile' : self.mobile,
                        'tanggal_registrasi' : self.tanggal_registrasi,
                        'tahunajaran_id' : self.tahunajaran_id.id,
                        'nis' : self.nis,
                        'panggilan' : self.panggilan,
                        'jenis_kelamin' : self.jenis_kelamin,
                        'tanggal_lahir' : self.tanggal_lahir,
                        'tempat_lahir' : self.tempat_lahir,
                        'alamat' : self.alamat,
                        'telp' : self.telp,
                        'ayah' : self.ayah,
                        'pekerjaan_ayah_id' : self.pekerjaan_ayah_id.id,
                        'telp_ayah' : self.telp_ayah,
                        'ibu' : self.ibu,
                        'pekerjaan_ibu_id' : self.pekerjaan_ibu_id.id,
                        'telp_ibu' : self.telp_ibu,
                        # 'rombels' : [(0, 0,  { 'rombel_id' : self.rombel_id.id, 'tahunajaran_id' : self.tahunajaran_id.id })],
                        # 'active_rombel_id' : self.rombel_id.id,
                        'is_siswa' : True,
                        'anak_ke' : self.anak_ke,
                        'dari_bersaudara' : self.dari_bersaudara
                    })
                    # self.siswa_id = new_siswa.id
                    self.registered_siswa_id = new_siswa.id
                    # self.siswa_id = new_siswa.id
                    the_siswa = new_siswa

                # update state
                self.state = 'reg'

                # assign siswa biaya
                # get tahunajaran_jenjang
                ta_jenjang = self.env['siswa_ocb11.tahunajaran_jenjang'].search([('tahunajaran_id', '=', self.tahunajaran_id.id),
                ('jenjang_id', '=', self.jenjang_id.id)
                ])

                # assign biaya to siswa
                self.assign_biaya_line_to_siswa(the_siswa)

                # add pembayaran
                self.assign_pembayaran_to_siswa(the_siswa)

                # raise exceptions.except_orm(_('Warning'), _('You can not delete Done state data'))
        else:
            raise exceptions.except_orm(_('Warning'), _('Can not confirm this registration, complete payment first!'))

    def terbilang_(self, n):
        if n >= 0 and n <= 11:
            hasil = [self.satuan[int(n)]]
        elif n >= 12 and n <= 19:
            hasil = self.terbilang_(n % 10) + ['belas']
        elif n >= 20 and n <= 99:
            hasil = self.terbilang_(n / 10) + ['puluh'] + self.terbilang_(n % 10)
        elif n >= 100 and n <= 199:
            hasil = ['seratus'] + self.terbilang_(n - 100)
        elif n >= 200 and n <= 999:
            hasil = self.terbilang_(n / 100) + ['ratus'] + self.terbilang_(n % 100)
        elif n >= 1000 and n <= 1999:
            hasil = ['seribu'] + self.terbilang_(n - 1000)
        elif n >= 2000 and n <= 999999:
            hasil = self.terbilang_(n / 1000) + ['ribu'] + self.terbilang_(n % 1000)
        elif n >= 1000000 and n <= 999999999:
            hasil = self.terbilang_(n / 1000000) + ['juta'] + self.terbilang_(n % 1000000)
        else:
            hasil = self.terbilang_(n / 1000000000) + ['milyar'] + self.terbilang_(n % 100000000)
        return hasil

    def action_print_kwitansi(self):
        # return self.env.ref('siswa_psb_ocb11.report_kwitansi_registrasi_action').report_action(self)
        return self.env.ref('siswa_psb_ocb11.report_bukti_pembayaran_registrasi_action').report_action(self)

    def action_reset(self):
        # reset confirmed calon siswa
        id_siswa = self.registered_siswa_id.id
        if self.is_siswa_lama:
            id_siswa = self.siswa_id.id

        # remove pembayaran
        pembayaran = self.env['siswa_keu_ocb11.pembayaran'].search([
                                ('siswa_id', '=', id_siswa),
                                ('tahunajaran_id', '=', self.tahunajaran_id.id)
                            ])

        if pembayaran:
            for pb in pembayaran:
                if pb.state == 'paid':
                    pb.action_cancel()
                pb.unlink()
                print('Pembayaran Deleted')
        # --------------------------------

        # remove tabungan siswa
        print('Delete Data Tabungan : ')
        tabungan = self.env['siswa_tab_ocb11.tabungan'].search([
                                ('siswa_id', '=', id_siswa),
                                ('tahunajaran_id', '=', self.tahunajaran_id.id)
                            ])
        pprint(tabungan)
        for tab in tabungan:
            if tab.state == 'post':
                tab.action_cancel()
            tab.unlink()

        # remove siswa biaya
        siswa_biaya = self.env['siswa_keu_ocb11.siswa_biaya'].search([
                            ('siswa_id', '=', id_siswa),
                            ('tahunajaran_id', '=', self.tahunajaran_id.id),
                            ])
        # remove potongan biaya
        for sis_by in siswa_biaya:
            for pot in sis_by.potongan_ids:
                pot.action_reset()
                pot.unlink()

        # remove siswa_biaya
        siswa_biaya.unlink()
        print('Siswa Deleted')

        # remove res_partner
        print('Deleting Registered Siswa')
        if not self.is_siswa_lama:
            self.env['res.partner'].search([('id', '=', id_siswa)]).unlink()
        else:
#             # change siswa_id.calon_siswa_id to previouse
#             print('Sort Order Tahun Ajaran : ' + str(self.tahunajaran_id.sort_order))
#             prev_tahun_ajaran_id = self.env['siswa_ocb11.tahunajaran'].search([
#                                             ('sort_order', '=', 1)
#                                         ]).id
#             print('Prev Tahun ajaran')
#             pprint(prev_tahun_ajaran_id)
            print('Get Prev Tahun Ajaran')
            self.env.cr.execute('select id from siswa_ocb11_tahunajaran where sort_order = ' + str(self.tahunajaran_id.sort_order - 1))
            prev_tahun_ajaran_id = self.env.cr.fetchone()
            pprint(prev_tahun_ajaran_id)
            print(prev_tahun_ajaran_id[0])
#             print('Prev Tahn Ajara : ' + str(prev_tahun_ajaran_id.id))

            if prev_tahun_ajaran_id:
                prev_calon_siswa_id = self.env['siswa_psb_ocb11.calon_siswa'].search([
                            '&','|',
                            ('tahunajaran_id', '=', prev_tahun_ajaran_id[0]),
                            ('siswa_id', '=', self.siswa_id.id),
                            ('registered_siswa_id','=',self.siswa_id.id)

                        ])
                pprint(prev_calon_siswa_id)
                if prev_calon_siswa_id:
#                     self.siswa_id.calon_siswa_id = [(3, self.id)]
#                     self.siswa_id.calon_siswa_id = [(4, prev_calon_siswa_id.id)]
                    self.siswa_id.calon_siswa_id = prev_calon_siswa_id.id
                else:
#                     self.siswa_id.calon_siswa_id = [(3, self.id)]
                    self.siswa_id.calon_siswa_id = None
            else:
                self.siswa_id.calon_siswa_id = [(3, self.id)]

        # update calon_siswa state
        self.state = 'draft'

        # Recompute Tagihan Siswa Dashboard/ Keuangan Dashboard
        dash_keuangan_id = self.env['ir.model.data'].search([('name', '=', 'default_dashboard_pembayaran')]).res_id
        dash_keuangan = self.env['siswa_keu_ocb11.keuangan_dashboard'].search([('id', '=', dash_keuangan_id)])
        for dash in dash_keuangan:
            dash.compute_keuangan()
        print('Recompute Keuangan Dashboard done')
        # raise exceptions.except_orm(_('Warning'), _('Reset Succesfull'))

    def clear_biaya_default(self):
        print('clear biaya default')

    def generate_biaya_default(self):
        total_biaya_sum = 0
        get_biaya_ta_jenjang_ids = self.env['siswa_keu_ocb11.biaya_ta_jenjang'].search([
                                        ('tahunajaran_id', '=', self.tahunajaran_id.id),
                                        ('jenjang_id', '=', self.jenjang_id.id),
                                    ])

        # clear data lama
        self.biaya_lines.unlink()

        # clear pembayaran_lines
        self.pembayaran_lines.unlink()
        self.bayar_tunai = 0.0

#         biaya_ids = []
        for by in get_biaya_ta_jenjang_ids:
            if by.biaya_id.assign_to == 'all' or (self.is_siswa_lama and by.biaya_id.assign_to == 'lama') or (not self.is_siswa_lama and by.biaya_id.assign_to == 'baru'):
#             if self.is_siswa_lama and by.biaya_id.is_siswa_baru_only:
#                     print('skip')
#                     continue
#             else:
                print(by.biaya_id.name)
                if not by.biaya_id.is_optional:
                    get_harga = by.harga
                    qty = 1

                    if by.biaya_id.is_different_by_gender and self.jenis_kelamin == 'perempuan':
                        get_harga = by.harga_alt

                    # hitung total biaya
                    if by.biaya_id.is_bulanan:
                        qty = 12
                    total_biaya_sum += qty * get_harga
                    if by:
                        self.biaya_lines = [(0, 0, {
                                'biaya_ta_jenjang_id' : by.id,
                                'harga' : get_harga,
                                'qty' : qty,
                                'jumlah_harga' : qty * get_harga
                            })]

        # add all biaya to biaya_lines
        self.total_biaya = total_biaya_sum

        # clear biaya optional select option
        for by in self.biaya_optional_ids:
            self.biaya_optional_ids = [(3, by.id)]

        # filtering biaya_optional_ids
        domain = {'biaya_optional_ids':[('is_siswa_lama', '=', False)]}
        return {'domain':domain, 'value':{'biaya_optional_ids':[]}}

    def generate_biaya_optional(self):
        for by in self.biaya_optional_ids:

            is_found = False
            for by_lin in self.biaya_lines:
                if by_lin.biaya_id.id == by.id :
                    is_found = True
                    break

            if not is_found:

                get_harga = by.harga
                qty = 1

                if by.biaya_id.is_different_by_gender and self.jenis_kelamin == 'perempuan':
                    get_harga = by.harga_alt

                # hitung total biaya
                if by.biaya_id.is_bulanan:
                    qty = 12

                self.total_biaya += qty * get_harga

                self.biaya_lines = [(0, 0, {
                        'biaya_ta_jenjang_id' : by.id,
                        'harga' : get_harga,
                        'qty' : qty,
                        'jumlah_harga' : qty * get_harga
                    })]

                # after generate to biaya_lines, clear the biaya_optional_ids
                self.biaya_optional_ids = [(3, by.id)]

    def generate_pembayaran_lines(self):
        # cek apakah biaya lines telah terisi atau belum
        if self.biaya_lines:
            if self.pembayaran_lines:
                self.pembayaran_lines.unlink()

            biaya_registrasi_ids = self.env['siswa_psb_ocb11.biaya_registrasi'].search([
                    ('tahunajaran_id', '=', self.tahunajaran_id.id),
                    ('jenjang_id', '=', self.jenjang_id.id),
                ])

            for by_reg in biaya_registrasi_ids.biaya_ta_jenjang_ids:
                self.ensure_one()
                if by_reg.biaya_id.assign_to == 'all' or (self.is_siswa_lama and by_reg.biaya_id.assign_to == 'lama') or (not self.is_siswa_lama and by_reg.biaya_id.assign_to == 'baru'):
#                 if self.is_siswa_lama and by_reg.biaya_id.is_siswa_baru_only:
#                     print('skip')
#                     continue
#                 else:
                    harga = by_reg.harga

                    if by_reg.biaya_id.is_different_by_gender and self.jenis_kelamin == 'perempuan':
                            harga = by_reg.harga_alt

                    bulan = by_reg.bulan

                    if by_reg.is_bulanan:
                        bulan = 7

                    # loop untuk mencari di biaya_lines apakah biaya ini telah tersedia
                    is_found = False
                    for by_line in self.pembayaran_lines:
                        if by_line.biaya_id.id == by_reg.biaya_id.id :
                            is_found = True
                            break
        #
                    if not is_found:
                        # cek potongan
#                         get_biaya_lin = self.biaya_lines.search([('biaya_ta_jenjang_id', '=', by_reg.id)])
                        get_biaya_lin = self.env['siswa_biaya_ta_jenjang_on_calon_siswa_rel'].search([
                                ('calon_siswa_id', '=', self.id),
                                ('biaya_ta_jenjang_id', '=', by_reg.id)
                            ])
                        potongan = 0
                        if get_biaya_lin:
                            potongan = get_biaya_lin.potongan_harga

                        newid = self.env['siswa_psb_ocb11.calon_siswa_biaya'].create({
                            'calon_siswa_id' : self.id,
                            'biaya_id' : by_reg.biaya_id.id,
                            'bulan' : bulan,
                            'harga' : harga,
                            'potongan_harga' : potongan,
                            'dibayar' : 0,
                        })
        else:
            raise exceptions.except_orm(_('Warning'), _('Data biaya belum terisi, lengkapi dulu pada tab Biaya'))

        # update bayar_tunai
#         self.bayar_tunai = sum(map(lambda x: x.harga, self.pembayaran_lines))


#!/usr/bin/python
import sys
import yaml
import os.path

def process_config():
  if (len(sys.argv) < 2):
    raise Exception('Missing path to configuration file!')

  if (not os.path.isfile(sys.argv[1])):
    raise Exception('Configuration file does not exist: ' + sys.argv[1])

  with open(sys.argv[1], 'r') as ymlfile:
    cfg = yaml.load(ymlfile)

  watch_include = '';
  watch_exclude = ''
  for section in cfg['watch']:
    watch_include = watch_include + ' ' + section['source'];
    if ('exclude' in section):
      for item in section['exclude']:
        watch_exclude = watch_exclude + ' --exclude ' + item

  if (len(watch_include) == 0):
    raise Exception('Nothing to watch! Config file: ' + sys.argv[1])

  return (watch_include+watch_exclude)

def main():
  print("inotifywait -r -q -e close_write -m" + process_config())
  return

main()


import os
from joblib import load
import torch
from torch.utils.data import Dataset

from lib.utilities.constants import *
from lib.midi_processor.processor import decode_midi, encode_midi
from lib.data.midi_processing import process_midi, process_midi_ed
from lib.utilities.hide_prints import NoStdOut

import numpy as np

import os
import random

import pretty_midi
import music21

from tqdm import tqdm

class MidiDataset(Dataset):
    """

    Pytorch Dataset for the Maestro e-piano dataset (https://magenta.tensorflow.org/datasets/maestro).
    Recommended to use with Dataloader (https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader)

    Uses all files found in the given root directory of pre-processed (preprocess_midi.py)
    Maestro midi files.

    """

    def __init__(self, root, arch, max_seq=2048, random_seq=False, percentage=100.0, keys=None, gedi=False, cocon=False):
        self.root       = root
        self.max_seq    = max_seq
        self.random_seq = random_seq
        self.percentage = percentage
        self.model_arch = arch
        self.keys       = keys
        self.gedi       = gedi
        self.cocon      = cocon

        self.rng = np.random.default_rng(seed=2486)

        fs = [os.path.join(root, f) for f in os.listdir(self.root)]
        # Data files hold (midi_file, encoding_file)
        self.data_files = [f for f in fs if os.path.isfile(f)]
        if self.percentage < 100.0:
            self.data_files = self.rng.choice(self.data_files, int(self.percentage/100 * len(self.data_files)))

        self.total_data = []
        for i in range(len(self.data_files)):
            with NoStdOut():
                data_points = self.__read_encoded_midi(self.data_files[i])
                for data_point in data_points:
                    self.total_data.append(data_point)

    def __read_encoded_midi(self, data):
        # All data on cpu to allow for the Dataloader to multithread
        data = load(data)

        data_points = []

        key = data[0]
        encodings = data[1]
        f_path = data[2]

        token_key = None
        if self.keys:
            if not key in KEY_VOCAB:
                my_score: music21.stream.Score = music21.converter.parse(f_path)
                key = my_score.analyze('Krumhansl')

            token_key = KEY_VOCAB[key]
        # encoding --> tensor
        for enc in encodings:
            data_points.append((torch.tensor(enc, dtype=TORCH_LABEL_TYPE), token_key))

        return data_points

    # __len__
    def __len__(self):
        """

        Author: Damon Gwinn

        How many data files exist in the given directory

        """

        return len(self.total_data)

    # __getitem__
    def __getitem__(self, idx):
        """

        Author: Damon Gwinn

        Gets the indexed midi batch. Gets random sequence or from start depending on random_seq.

        Returns the input and the target.

        """
        aug_midi, token_key = self.total_data[idx]
        if self.model_arch == 2:
            if not self.keys:
                x, tgt_input, tgt_output = process_midi_ed(aug_midi, self.max_seq, False)
            else:
                raise NotImplementedError('encoder-decoder arch isn\'t updated for key control')
            return x, tgt_input, tgt_output
        elif self.model_arch == 1:
            x, tgt = process_midi(aug_midi, self.max_seq, False, token_key)
            if self.gedi:
                return x, tgt, token_key
            elif self.cocon:
                c = torch.full((self.max_seq, ), TOKEN_PAD, dtype=TORCH_LABEL_TYPE)
                c[0] = token_key
                return c, x[1:], tgt[1:]
            else:
                return x, tgt

    def __transpose(self, midi: pretty_midi.PrettyMIDI()) -> torch.tensor:
        """
        Augments the data by shifting all of the notes to higher and/or lower pitches.
        Pitch transpositions uniformly sampled from {-3, -2, . . . , 2, 3} half-steps

        :param torch.tensor midi: preprocessed midi tensor
        :return: transposed midi tensor (if all notes could be transposed)
        """
        pitch_change = self.rng.choice([0, 5, 7]) # perfect 4th and 5th
        if pitch_change == 0:
            return midi

        for instrument in midi.instruments:
            for note in instrument.notes:
                note.pitch += pitch_change

        return midi


#!/usr/bin/env python3

from util import read_input

def day1_part1():
    sum = 0
    with read_input(1) as f:
        for line in f:
            sum += int(line)
    return sum

assert day1_part1() == 420

def day1_part2(sum=0, seen=None):
    if seen is None:
        seen = {}
    with read_input(1) as f:
        for line in f:
            sum += int(line)
            if seen.get(sum):
                return sum
            seen[sum] = True
    return day1_part2(sum, seen)

assert day1_part2() == 227


import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('SKR6.JPG')
#print(img.shape)
cv2.imshow('Gambar Asli', img)
cv2.waitKey(4)

img_scaled = cv2.resize(img, None, fx=0.1, fy=0.1)
#print(img_scaled.shape)
cv2.imshow('Gambar scaled', img_scaled)
cv2.waitKey(3)

img_gray = cv2.cvtColor(img_scaled, cv2.COLOR_BGR2GRAY)
cv2.imshow('Gambar gray', img_gray)
cv2.waitKey(2)

#_ , img_threshold = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
#cv2.imshow('Gambar threshold', img_threshold)
#cv2.waitKey(2)

#img_canny = cv2.Canny(img_threshold, 100, 200)
#cv2.imshow('Gambar canny', img_canny)
#cv2.waitKey(1)

img_canny2 = cv2.Canny(img_gray, 200, 300)
cv2.imshow('Gambar Canny from Gray', img_canny2)
cv2.waitKey(1)

kernel = np.ones((5,5),np.uint8)

closing = cv2.morphologyEx(img_canny2, cv2.MORPH_CLOSE, kernel)
cv2.imshow('morfologi closing', closing)
cv2.waitKey(0)

#img6 = cv2.imread('SKR5.jpg',0)
#edges = cv2.Canny(img6,100,200)

plt.subplot(121),plt.imshow(img6,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

#plt.show()


#-------------------------------------------------------------------------------
#                                  imports
#-------------------------------------------------------------------------------
import json
import os, subprocess
import platform
import vim

#-------------------------------------------------------------------------------
#                             constants & globals
#-------------------------------------------------------------------------------
CURRENT_DIR = os.getcwd()
PROJ_DIR = os.path.join(os.path.expanduser("~"),".proj_db")
osinfo = platform.system()

SELECT_PROJECT_DB = None #main flag
SESSION_DIR = None
SESSION_NAME = None
PROJ_FILELIST = None

#-------------------------------------------------------------------------------
#                                 class
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#                                 function
#-------------------------------------------------------------------------------

def envCheck():
    global SELECT_PROJECT_DB
    global SESSION_DIR
    global PROJ_FILELIST
    global SESSION_NAME
    SELECT_PROJECT_DB = vim.eval("$SELECT_PROJECT_DB")
    #SELECT_PROJECT_DB = os.getenv("SELECT_PROJECT_DB", None)
    if SELECT_PROJECT_DB and SELECT_PROJECT_DB != "-1":
        SESSION_DIR = os.path.join(PROJ_DIR, SELECT_PROJECT_DB)
        PROJ_FILELIST = os.path.join(SESSION_DIR, "projlist")
        with open(os.path.join(PROJ_DIR, SELECT_PROJECT_DB, "name")) as session_name:
            SESSION_NAME = session_name.readlines()[0].strip()
    else:
        SELECT_PROJECT_DB = None
        print("SELECT_PROJECT_DB not set")

def folder2file(inDir=None):
    import re
    outFileName = os.path.join(SESSION_DIR, "cscope.files")
    print("Searching ... \n [%s] >> [%s] ..." % (inDir, outFileName))
    p_white_list = re.compile(".*releasetools.*")
    p_black_list = re.compile(".*out/target.*")
    p_plus = re.compile(".*\.(c|cpp|cc|mk|xml|aidl|idl|java|py|sh|GNUMakefile|Makefile|h|hpp|hh)$")
    p_minus = re.compile(".*\.(git|svn).*")
    f = open(outFileName, "a")
    for (root, dirs, files) in os.walk(inDir):
        for afile in files:
            item = os.path.join(root, afile)
            if p_white_list.match(item):
                f.write("%s\n" % item)
                continue
            if p_black_list.match(item):
                continue
            if p_plus.match(item):
                if p_minus.match(item):
                    pass
                    #print("- %s" % item)
                else:
                    #print("+ %s" % item)
                    f.write("%s\n" % item)
    f.close()
    #theCmd = """ \
    #    ! -wholename "*.git*" -type f -regex ".*\.c$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.cpp$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.cc$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.mk$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.xml$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.aidl$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.java$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.py$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.sh$" \
    #-or ! -wholename "*.git*" -type f -regex ".*Makefile$" \
    #-or ! -wholename "*.git*" -type f -regex ".*\.h$" \
    #>> """

def folders2file(listfile):
    os.chdir(SESSION_DIR)
    if "Windows" == osinfo:
        os.system("del /f /q cscope.files*")
    elif "Linux" == osinfo:
        os.system("rm -f cscope.files*")
    elif "Darwin" == osinfo:
        os.system("rm -f cscope.files*")
    else:
        raise

    try:
        with open(listfile, "r") as fd:
            lines = fd.readlines()
            for line in lines:
                folder2file(line.strip())
    except IOError as e:
        print("I/O error ({0}):{1}".format(e.errno, e.strerror))
        raise
    except ValueError:
        print("ValueError")
        raise
    except:
        print("Unexpected error [%s]" % sys.exc_info()[0])
        raise

def addQuote(inFileName="cscope.files", outFileName="cscope.files.quoted"):
    os.chdir(SESSION_DIR)
    print("Quoting ...\n [%s] >> [%s] " % (inFileName, outFileName))
    fd = open(inFileName, "r")
    lines = fd.readlines()
    #print(lines)
    fd.close()
    newlines = []
    for line in lines:
        _line = line.rstrip()
        while os.path.islink(_line):
            _line = os.path.realpath(_line)
        if len(_line) > 249:
            print("File name tooooooo long! %s" % _line)
            continue
        if not os.path.isfile(_line):
            print("File invalid: %s" % _line)
            continue
        newlines.append('"' + _line + '"\n')
    #print(newlines)
    fd = open(outFileName, "w")
    fd.writelines(newlines)
    fd.close()

    return 0

def buildIndex(filename="cscope.files.quoted"):
    os.chdir(SESSION_DIR)
    if "Windows" == osinfo:
        os.system("del /f /q cscope.out cscope.out*")
        os.system("del /f tags")
    elif ("Linux" == osinfo or "Darwin" == osinfo):
        os.system("rm -fr cscope*out")
        os.system("rm -f tags")
    else:
        raise
    print("Cscope indexing ...\n [%s] >> [cscope.* ncscope.out]" % filename)
    theCmd = "cscope -bqC -i " + filename #-C to ignore case
    subprocess.check_call(theCmd, shell=True)

    return
    print("Ctags indexing ...\n [%s] >> [tags]" % PROJ_FILELIST)
    try:
        with open(PROJ_FILELIST, "r") as fd:
            lines = fd.readlines()
            for line in lines:
                theCmd = 'ctags --append=yes -R ' + line.strip() + ' -h .h.H.hh.hpp.hxx.h++.inc.def.cpp.c.java.mk'
                subprocess.check_call(theCmd, shell=True)
    except IOError as e:
        print("I/O error ({0}):{1}".format(e.errno, e.strerror))
        raise
    except ValueError:
        print("ValueError")
        raise
    except:
        print("Unexpected error [%s]" % sys.exc_info()[0])
        raise

def addQuote(inFileName="cscope.files", outFileName="cscope.files.quoted"):
    os.chdir(SESSION_DIR)
    print("Quoting ...\n [%s] >> [%s] " % (inFileName, outFileName))
    fd = open(inFileName, "r")
    lines = fd.readlines()
    #print(lines)
    fd.close()
    newlines = []
    for line in lines:
        _line = line.rstrip()
        while os.path.islink(_line):
            _line = os.path.realpath(_line)
        if len(_line) > 249:
            print("File name tooooooo long! %s" % _line)
            continue
        if not os.path.isfile(_line):
            print("File invalid: %s" % _line)
            continue
        newlines.append('"' + _line + '"\n')
    #print(newlines)
    fd = open(outFileName, "w")
    fd.writelines(newlines)
    fd.close()

    return 0

def run():
    envCheck()
    if not SELECT_PROJECT_DB:
        return
    folders2file(PROJ_FILELIST)
    addQuote()
    buildIndex()