ConDict

Check-in [04bdda6ca6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:get main function from testing branch
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:04bdda6ca6017565e0583a5d88ec9ab81de44f42
User & Date: zorro 2012-09-09 08:16:28
Context
2012-09-18
18:52
tests done check-in: 2928daa896 user: zorro tags: trunk
2012-09-09
08:16
get main function from testing branch check-in: 04bdda6ca6 user: zorro tags: trunk
08:14
done delete-function (by ID and pattern check-in: eb602c3be7 user: zorro tags: testing
2012-09-03
18:24
merge main functionality check-in: ee613e478b user: zorro tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to aside.py.

1
2
3
4




5
6
7
8
9
10
11
12
13
14
15
16
17





18
19
































#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import configparser





def get_config_data(filename):
    result = {'database': None, 'defuser': None}
    config = configparser.ConfigParser()
    try:
        config.read(filename)
        result['database'] = config['database']['dbname']
        result['defuser'] = config['user']['default_user']
    except (KeyError, IndexError, TypeError) as er:
        pass
    return result

def help_command(commands):





    for key, item in commands.items():
        print("{0:.<30}{1}".format(key, item[0]))



































|
>
>
>
>












|
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import re, configparser, json, signal
from urllib import request

YANDEX_TRANSLATE_JSON = "http://translate.yandex.net/api/v1/tr.json/translate?lang="
TEST_CONNECT = "http://ya.ru/"

def get_config_data(filename):
    result = {'database': None, 'defuser': None}
    config = configparser.ConfigParser()
    try:
        config.read(filename)
        result['database'] = config['database']['dbname']
        result['defuser'] = config['user']['default_user']
    except (KeyError, IndexError, TypeError) as er:
        pass
    return result

def get_command(raw_str):
    result = re.sub(r"\s+", " ", raw_str.strip())
    # return [command, str_params]
    command = result.split(" ", 1)
    if len(command) == 1:
        command.append([])
    return command


def get_translate(for_translate, trans_type):
    global YANDEX_TRANSLATE_JSON
    result = False
    prepate_url = request.pathname2url(for_translate)
    trans_types = {'en': 'en-ru', 'ru': 'ru-en'}
    prepate_url = YANDEX_TRANSLATE_JSON + trans_types[trans_type] + "&text=" + prepate_url
    try:
        conn = request.urlopen(prepate_url)
    except Exception as e:
        print("Not connection\nError:")
        print(e)
        return result
    if conn.status == 200:
        try:
            from_url = conn.read().decode('utf-8')
            result = json.loads(from_url)
        except Exception as e:
            print(e)
    conn.close()
    return result

def get_test_connection():
    global TEST_CONNECT
    try:
        conn = request.urlopen(TEST_CONNECT)
        result = True if conn.getcode() == 200 else False
    except Exception as e:
        print('Test connection False,', e)
        return False
    conn.close()
    return result 

Changes to condt.conf.

Changes to condt.py.

1
2
3
4





5
6



7
8
9
10

11
12
13
14
15
16
17
..
18
19
20
21
22
23
24
25
26
27







28
29
30
31
32
33
34

35
36
37
38
39
40
41
..
45
46
47
48
49
50
51










52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133





















134

























135
136





































































































































































































































#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import sqlite3, hashlib, getpass





DEBUG = True




class BaseConDict(object):
    """Base Console Dictionary class"""
    def __init__(self, name, dbfile):
        self.connect = sqlite3.connect(dbfile)

        self.name = name
    def __repr__(self):
        return "<ConDict object for {0}>".format(self.name)
    def __str__(self):
        return "<ConDict object for {0}>".format(self.name)
    def __bool__(self):
        valid = True if self.user_id else False
................................................................................
        return valid
    def __del__(self):
        self.connect.close()

class Condt(BaseConDict):
    """Condt - class for ConDict"""
    COMMANDS = {'.help': {'desc': 'list commands', 'command': None}, 
        # '.chname': {'desc': 'change current user name', 'command': None}, 
        # '.chpassword': {'desc': 'change current password', 'command': None},
        # '.list': {'desc': 'list users words', 'command': None},







        '.exit': {'desc': 'quit from program', 'command': None},
        }
    def __init__(self, name, dbfile):
        super().__init__(name, dbfile)       
        self.__pcounter = 3
        self.init_command()
        self.user_id = self.get_user()


    def get_user(self):
        sqlstr="SELECT id FROM user WHERE name=(?) AND password=(?)"
        cur = self.connect.cursor()
        ch_user_id = self.check_name(cur)
        if ch_user_id:
            ch_user_id = ch_user_id[0]
................................................................................
            user_id = self.handling_add(cur)
        cur.close()
        return user_id

    def init_command(self):
        self.COMMANDS['.help']['command'] = self.command_help
        self.COMMANDS['.exit']['command'] = self.command_exit











    def hash_pass(self, password):
        result = bytes(password.strip(), 'utf-8')

        return hashlib.sha1(result).hexdigest()

    def check_name(self, cur):
        try:
            cur.execute("SELECT id FROM user WHERE name=(?)", (self.name,))
        except sqlite3.DatabaseError as er:
            return None
        return cur.fetchone()

    def check_password(self, cur, user_id):
        try:
            cur.execute("SELECT id FROM user WHERE id=(?) AND password=(?)", (user_id, self.hash_pass(self.password)))
        except sqlite3.DatabaseError as er:
            return None
        return cur.fetchone()

    def handling_action(self, cur, ch_user_id):
        print('"{0}" please enter your password:'.format(self.name))
        self.password = input("Password:") if DEBUG else getpass.getpass()
        while(self.__pcounter > 0):
            user_id = self.check_password(cur, ch_user_id)
            if user_id:
                return user_id[0]
            else:
                action = input('Invalid password, there are actions "Exit"/"Press password again" [e/P]:')
                if action in ('', 'P', 'p'):
                    self.__pcounter -= 1
                    self.password = input("Password:") if DEBUG else getpass.getpass()
................................................................................
            elif want_add in ('n', 'N'):
                break
            else:
                print('select an option...')
        return None

    def handling_command(self, command):

        if command not in self.COMMANDS.keys():
            return None
        result = self.COMMANDS[command]['command']()
        return result

    def command_help(self):
        for key, item in self.COMMANDS.items():
            print("{0:.<30}{1}".format(key, item['desc']))
        return '.help'

    def command_exit(self):
        return 0

    def chname(self):
        pass





















    def chpassword(self):

























        pass









































































































































































































































|
>
>
>
>
>


>
>
>




>







 







|
|
|
>
>
>
>
>
>
>







>







 







>
>
>
>
>
>
>
>
>
>


|
>









|

|








|







 







>


|


|




|


|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import sqlite3, hashlib, getpass, datetime, csv
from aside import *

# please, change this stirg for your application
SALT = 'r8Uts$jLs74Lgh49_h75&w@dFsS4sgpm3Kqq['
EXPORT_NAME = 'condict_export_'
DEBUG = True

class IncorrectDbData(Exception): pass
class DublicationDbData(Exception): pass

class BaseConDict(object):
    """Base Console Dictionary class"""
    def __init__(self, name, dbfile):
        self.connect = sqlite3.connect(dbfile)
        self.online = False
        self.name = name
    def __repr__(self):
        return "<ConDict object for {0}>".format(self.name)
    def __str__(self):
        return "<ConDict object for {0}>".format(self.name)
    def __bool__(self):
        valid = True if self.user_id else False
................................................................................
        return valid
    def __del__(self):
        self.connect.close()

class Condt(BaseConDict):
    """Condt - class for ConDict"""
    COMMANDS = {'.help': {'desc': 'list commands', 'command': None}, 
        '.chname': {'desc': 'change current user name', 'command': None},
        '.chpassword': {'desc': 'change current password', 'command': None},
        '.list': {'desc': 'list users words', 'command': None},
        '.en': {'desc': 'dictionary mode English to Russian', 'command': None},
        '.ru': {'desc': 'dictionary mode Russian to English', 'command': None},
        '.add': {'desc': 'add new words', 'command': None},
        '.connect': {'desc': 'test connection', 'command': None},
        '.export': {'desc': 'export user dictionary to CSV file', 'command': None},
        '.edit': {'desc': 'edit words', 'command': None},
        '.delete': {'desc': 'delete words', 'command': None},
        '.exit': {'desc': 'quit from program', 'command': None},
        }
    def __init__(self, name, dbfile):
        super().__init__(name, dbfile)       
        self.__pcounter = 3
        self.init_command()
        self.user_id = self.get_user()
        self.command_connect()

    def get_user(self):
        sqlstr="SELECT id FROM user WHERE name=(?) AND password=(?)"
        cur = self.connect.cursor()
        ch_user_id = self.check_name(cur)
        if ch_user_id:
            ch_user_id = ch_user_id[0]
................................................................................
            user_id = self.handling_add(cur)
        cur.close()
        return user_id

    def init_command(self):
        self.COMMANDS['.help']['command'] = self.command_help
        self.COMMANDS['.exit']['command'] = self.command_exit
        self.COMMANDS['.chname']['command'] = self.command_chname
        self.COMMANDS['.chpassword']['command'] = self.command_chpassword
        self.COMMANDS['.list']['command'] = self.command_list
        self.COMMANDS['.en']['command'] = self.command_en
        self.COMMANDS['.ru']['command'] = self.command_ru
        self.COMMANDS['.add']['command'] = self.command_add
        self.COMMANDS['.connect']['command'] = self.command_connect
        self.COMMANDS['.export']['command'] = self.command_export
        self.COMMANDS['.edit']['command'] = self.command_edit
        self.COMMANDS['.delete']['command'] = self.command_delete

    def hash_pass(self, password):
        result = bytes(password.strip() + SALT, 'utf-8')
        result = bytes(hashlib.md5(result).hexdigest(), 'utf-8')
        return hashlib.sha1(result).hexdigest()

    def check_name(self, cur):
        try:
            cur.execute("SELECT id FROM user WHERE name=(?)", (self.name,))
        except sqlite3.DatabaseError as er:
            return None
        return cur.fetchone()

    def check_password(self, cur, user_id, password):
        try:
            cur.execute("SELECT id FROM user WHERE id=(?) AND password=(?)", (user_id, self.hash_pass(password)))
        except sqlite3.DatabaseError as er:
            return None
        return cur.fetchone()

    def handling_action(self, cur, ch_user_id):
        print('"{0}" please enter your password:'.format(self.name))
        self.password = input("Password:") if DEBUG else getpass.getpass()
        while(self.__pcounter > 0):
            user_id = self.check_password(cur, ch_user_id, self.password)
            if user_id:
                return user_id[0]
            else:
                action = input('Invalid password, there are actions "Exit"/"Press password again" [e/P]:')
                if action in ('', 'P', 'p'):
                    self.__pcounter -= 1
                    self.password = input("Password:") if DEBUG else getpass.getpass()
................................................................................
            elif want_add in ('n', 'N'):
                break
            else:
                print('select an option...')
        return None

    def handling_command(self, command):
        command, arg = get_command(command)
        if command not in self.COMMANDS.keys():
            return None
        result = self.COMMANDS[command]['command'](arg)
        return result

    def command_help(self, arg=None):
        for key, item in self.COMMANDS.items():
            print("{0:.<30}{1}".format(key, item['desc']))
        return '.help'

    def command_exit(self, arg=None):
        return 0

    def command_chname(self, arg=None):
        cur = self.connect.cursor()
        while(True):
            name = input("You login:")
            fullname = input("You full name (optional):")
            try:
                if name == '':
                    raise IncorrectDbData()
                cur.execute("UPDATE user SET name=(?), full=(?) WHERE id=(?)", (name, fullname, self.user_id))
            except (sqlite3.DatabaseError, IncorrectDbData) as er:
                print('Incorrect information, change data')
                e = input('Do you wand exit from name update [N/y]?')
                if e in ('y', 'Y'):
                    break
                continue
            else:
                self.connect.commit()
                self.name = name
                print("You name updated successfully")
                break
        cur.close()
        return 'chname'

    def command_chpassword(self, arg=None):
        cur = self.connect.cursor()
        while(True):
            password_old = input("Old password:") if DEBUG else getpass.getpass()
            try:
                if self.check_password(cur, self.user_id, password_old):
                    password1 = input("New password:") if DEBUG else getpass.getpass()
                    password2 = input("New password again:") if DEBUG else getpass.getpass()
                    if password1 != password2:
                        raise IncorrectDbData()
                    else:
                        cur.execute("UPDATE user SET password=(?) WHERE id=(?)", (self.hash_pass(password1), self.user_id))
                else:
                    raise IncorrectDbData()
            except (sqlite3.DatabaseError, IncorrectDbData) as er:
                print('Incorrect information, change data')
                e = input('Do you wand exit from password update [N/y]?')
                if e in ('y', 'Y'):
                    break
                continue
            else:
                self.connect.commit()
                self.password = password1
                print("You password updated successfully")
                break
        cur.close()
        return 'chpassword'

    def command_en(self, text):
        print(self.command_enru(text, 'en'))
        return 'en'
    def command_ru(self, text):
        print(self.command_enru(text, 'ru'))
        return 'ru'
    def command_enru(self, text, tr_type):
        if not self.online:
            return "Offline, please test connect with '.connect' command"
        result = get_translate(text, tr_type)
        if not result or result['code'] != 200:
            self.command_connect()
            return "Error, not foud translate"
        return result['text']

    def command_list(self, pattern=None):
        cur = self.connect.cursor()
        sql_list = "SELECT `translate`.`id`, `term`.`en`, `translate`.`rus`, `progress`.`all`, `progress`.`error` FROM `translate` LEFT JOIN `term` ON (`translate`.`term`=`term`.`token`) LEFT JOIN `progress` ON (`progress`.`translate_id`=`translate`.`id`) WHERE `translate`.`user_id`=(?) "
        params = (self.user_id,)
        result_text, result_param = "Get {0} rows", [0]
        if pattern:
            sql_list += " AND `term`.`en` LIKE (?)"
            params = (self.user_id, pattern + '%')
            result_text = "Get {0} rows for pattern '{1}%'"
            result_param.append(pattern)
        sql_list += " ORDER BY `translate`.`created` DESC, `term`.`token`"
        try:
            cur.execute(sql_list, params)
            i = 1
            for row in cur.fetchall():
                print("{0}. ID={1} all {2}, error {3}".format(i, row[0], row[3], row[4]))
                print("\t(en) {0}\n\t(ru) {1}".format(row[1], row[2]))
                i +=1
            result_param[0] = i - 1
            print(result_text.format(*result_param))
        except (sqlite3.DatabaseError, IncorrectDbData) as er:
            print('Sorry, error')
            return 'list'
        cur.close()
        return 'list'
    
    def command_add(self, en_words=None):
        """add new user pattern"""
        cur = self.connect.cursor()
        print('Please enter your patterns:')
        while True:
            try:
                en = input('En [' + en_words + ']:') if en_words else input('En: ')
                if not en:
                    if not en_words:
                        raise IncorrectDbData()
                    else:
                        en = en_words
                try:
                    ru_words = self.command_enru(en, 'en')[0]
                except Exception as e:
                    if DEBUG: print(e)
                    ru_words = None
                ru = input('Ru [' + ru_words + ']:') if ru_words else input('Ru: ')
                if not ru:
                    if not ru_words:
                        raise IncorrectDbData()
                    else:
                        ru = ru_words
                ru = ru.lower().strip()
                en = en.lower().strip()
                translate_id = self.command_add_kinds(cur, en, ru)
            except DublicationDbData:
                print('Words already contained in database. For search use ".list {0}"'.format(en))
                break
            except (sqlite3.DatabaseError, IncorrectDbData) as er:
                if DEBUG: print(er)
                print('Incorrect information, change data')
                ent = input('Do you wand enter new words [Y/n]?')
                if ent in ('n', 'N'):
                    break
                continue
            else:
                self.connect.commit()
                print("Words added successfully, ID={0}".format(translate_id))
                break
        cur.close()
        return 'add'

    def command_add_kinds(self, cur, en, ru):
        """SQL queries for add-command"""
        token = hashlib.md5(bytes(en, 'utf-8')).hexdigest()
        # search token
        sql_list = "SELECT `token` FROM `term` WHERE `token`=(?)"
        cur.execute(sql_list, (token,))
        # if cur.fetchone(): raise DublicationDbData()
        if not cur.fetchone():
            # insert in to tables
            sql_list1 = "INSERT INTO `term` (`token`, `en`) VALUES ((?), (?))"
            cur.execute(sql_list1, (token, en))
        cur.execute("SELECT `id` FROM `translate` WHERE `term`=(?) AND `user_id`=(?)", (token, self.user_id))
        if cur.fetchone(): raise DublicationDbData()
        sql_list2 = "INSERT INTO `translate` (`term`, `user_id`, `rus`) VALUES (?, ?, ?)"
        cur.execute(sql_list2, (token, self.user_id, ru))
        translate_id = cur.lastrowid
        sql_list3 = "INSERT INTO `progress` (`translate_id`) VALUES (?)"
        cur.execute(sql_list3, (translate_id,))
        return translate_id

    def command_export(self, arg=None):
        """export all user dictionary in CSV file"""
        global EXPORT_NAME, DEBUG
        if arg:
            export_name = arg + ".csv"
        else:
            d = datetime.date.today()
            export_name = EXPORT_NAME + d.strftime("%Y_%m_%d") + ".csv"
        try:
            cur = self.connect.cursor()
            writer_csv = csv.writer(open(export_name, 'w'), delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            writer_csv.writerow(['ENGLISH','RUSSIAN'])
            sql_list = "SELECT `term`.`en`, `translate`.`rus` FROM `translate` LEFT JOIN `term` ON (`translate`.`term`=`term`.`token`) WHERE `translate`.`user_id`=(?) ORDER BY `term`.`en`, `translate`.`rus`"
            cur.execute(sql_list, (self.user_id,))
            for result in cur.fetchall():
                writer_csv.writerow(result)
        except Exception as e:
            if DEBUG: print(e)
            print("Export error")
        else:
            cur.close()
            print("Export finished successfully to file: {0}".format(export_name))
        return 'export'

    def command_edit(self, translate_id):
        """Edit translate words form DB, search by ID"""
        # search id
        cur = self.connect.cursor()
        try:
            translate_id = int(translate_id)
            result = self.check_user_translate(cur, translate_id)
            if not result: 
                raise IncorrectDbData()
            else:
                result = result[0]
            # enter en-ru
            en = input('En [' + result[0] + ']:')
            if not en: en = result[0]
            ru = input('Ru [' + result[1] + ']:')
            if not ru: ru = result[1]
            # new token
            need_del = False
            token = hashlib.md5(bytes(en, 'utf-8')).hexdigest()
            if token != result[2]:
                cur.execute("INSERT INTO `term` (`token`, `en`) VALUES ((?), (?))", (token, en))
                need_del = True
            # translate
            cur.execute("UPDATE `translate` SET `rus`=(?), `term`=(?) WHERE `term`=(?) AND `user_id`=(?)", (ru, token, result[2], self.user_id))
            # delete recodrs in term if it needed
            if need_del:
                cur.execute("SELECT `id` FROM `translate` WHERE `term`=(?) LIMIT 1", (result[2],))
                if not cur.fetchone(): cur.execute("DELETE FROM `term` WHERE `token`=(?)", (result[2],))
        except IncorrectDbData as e:
            print('Record not found for current user.')
        except (TypeError, ValueError, sqlite3.DatabaseError) as er:
            if DEBUG: print(er)
            print("Error, use '.edit ID' (ID is numerical)")
        else:
            self.connect.commit()
            cur.close()
            print('Successfully update')
        return 'edit'

    def command_delete(self, id_or_pattern):
        """Delete translate words form DB, search by ID or pattern (several rows)"""
        cur = self.connect.cursor()
        try:
            try:
                pattern = int(id_or_pattern) 
                by_pattern = False
            except ValueError as e:
                pattern = id_or_pattern
                by_pattern = True
            result = self.check_user_translate(cur, pattern, by_pattern)
            if not result: raise IncorrectDbData()
            print('Records for delete:')
            id_for_del = []
            for row in result:
                # id, token
                id_for_del.append((row[3], row[2]))
                print("ID={0}:\t'{1}'".format(row[3], row[0]))
            correction = input("It is right [N/y]?")
            if correction not in ('Y', 'y'):
                return 'delete'
            # delete for correction information
            for rec in id_for_del:
                # delete translate
                cur.execute("DELETE FROM `translate` WHERE `id`=(?)", (rec[0],))
                # delete progress
                cur.execute("DELETE FROM `progress` WHERE `translate_id`=(?)", (rec[0],))
                # del from term if it needed
                cur.execute("SELECT `term` FROM `translate` WHERE `term`=(?) LIMIT 1", (rec[1],))
                if not cur.fetchone():
                    cur.execute("DELETE FROM `term` WHERE `token`=(?)", (rec[1],))
        except IncorrectDbData as e:
            print('Record not found for current user.')
        except (sqlite3.DatabaseError, TypeError) as er:
            if DEBUG: print(er)
            print("Error, use '.delete [ID or pattern]' (ID is numerical)")
        else:
            self.connect.commit()
            cur.close()
            print('Successfully update')
        return 'delete'

    def command_connect(self, arg=None):
        """test connection, set user status"""
        result = get_test_connection()
        if result:
            print("Ok connection")
        else:
            print("Error connection")
        self.online = result
        return 'connect'

    def check_user_translate(self, cur, for_search, by_pattern=False):
        sql_str = "SELECT `term`.`en`, `translate`.`rus`, `term`.`token`, `translate`.`id` FROM `translate` LEFT JOIN `term` ON (`translate`.`term`=`term`.`token`) "
        if by_pattern:
            pattern = for_search + '%' 
            sql_str += "WHERE `term`.`en` LIKE (?) AND `user_id`=(?) ORDER BY `translate`.`id`"
        else:
            pattern = for_search
            sql_str += "WHERE `translate`.`id`=(?) AND `user_id`=(?) ORDER BY `translate`.`id`"
        cur.execute(sql_str, (pattern, self.user_id))
        return cur.fetchall()

Changes to db.sql.

1
2
3
4

5
6
7
8
9
CREATE TABLE "progress" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "translate_id" INTEGER NOT NULL , "all" INTEGER DEFAULT 0, "error" INTEGER DEFAULT 0);
CREATE TABLE "term" ("token" VARCHAR(40) PRIMARY KEY  NOT NULL  UNIQUE , "en" VARCHAR NOT NULL );
CREATE TABLE "translate" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "term" VARCHAR(40) NOT NULL , "user_id" INTEGER NOT NULL , "rus" VARCHAR NOT NULL );
CREATE TABLE "user" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "name" VARCHAR NOT NULL  UNIQUE , "password" VARCHAR NOT NULL , "full" TEXT);

CREATE INDEX "progress_result" ON "progress" ("all" ASC, "error" ASC);
CREATE INDEX "progress_translate" ON "progress" ("translate_id" ASC);
CREATE INDEX "translate_user_id" ON "translate" ("user_id" ASC);
CREATE UNIQUE INDEX "user_name" ON "user" ("name" ASC);
CREATE INDEX "user_passwod" ON "user" ("password" ASC);


|

>


<


1
2
3
4
5
6
7

8
9
CREATE TABLE "progress" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "translate_id" INTEGER NOT NULL , "all" INTEGER DEFAULT 0, "error" INTEGER DEFAULT 0);
CREATE TABLE "term" ("token" VARCHAR(40) PRIMARY KEY  NOT NULL  UNIQUE , "en" VARCHAR NOT NULL );
CREATE TABLE "translate" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "term" VARCHAR(40) NOT NULL , "user_id" INTEGER NOT NULL , "rus" VARCHAR NOT NULL, "created" DATETIME NOT NULL DEFAULT (CURRENT_TIMESTAMP) );
CREATE TABLE "user" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "name" VARCHAR NOT NULL  UNIQUE , "password" VARCHAR NOT NULL , "full" TEXT);
CREATE INDEX "created" ON "translate" ("created" DESC);
CREATE INDEX "progress_result" ON "progress" ("all" ASC, "error" ASC);
CREATE INDEX "progress_translate" ON "progress" ("translate_id" ASC);

CREATE UNIQUE INDEX "user_name" ON "user" ("name" ASC);
CREATE INDEX "user_passwod" ON "user" ("password" ASC);

Changes to db.sqlite.

cannot compute difference between binary files

Added dict.csv.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ENGLISH;RUSSIAN
ability;способность
can you play the guitar?;вы можете играть на гитаре?
conversation;разговор
famous;известный
guitar;гитара
hi;привет
how do you do?;как поживаете?
judo;дзюдо
mistake;ошибка
odd;странно
restaurant;ресторан
riding a bike;езда на велосипеде
sailing;парусный спорт
sentences;предложения
skill;мастерство
vocabulary;словарь

Changes to main.py.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
20
21
22
23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#-*- coding: utf-8 -*-

from aside import *
from condt import Condt
import getpass, os

CONF_NAME = 'condt.conf' 
PREFIX = "{0}@ConDict>>>"
WELCOM = """****************************************************
*** Good day.                                    ***
*** For help, use the command ".help", nice work.***
****************************************************"""

def main():
    global CONF_NAME, PREFIX
................................................................................
        print("Not fount SQLite database")
        return 1
    # get name
    user = config['defuser'] if config['defuser'] else input("User name:")
    # create object
    account = Condt(user, config['database'])
    if not account:
        print('Validation error, bye...')
        return 0
    print(WELCOM)
    prefix = PREFIX.format(account.name)
    while (True):


        command = input(prefix)
        get_command = account.handling_command(command)
        if get_command is None:
            print('Sorry, unknown command: "{0}"\nuse ".help" for more information'.format(command))
            continue
        if not get_command:
            print("Bye {0}!".format(account.name))
            return 0
        # COMMANDS[command][1](COMMANDS)
        # print('ok', command)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print('Press Ctrl+C, Bye')







|







 







|


<

>
>






|

<
<






2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40


41
42
43
44
45
46
#-*- coding: utf-8 -*-

from aside import *
from condt import Condt
import getpass, os

CONF_NAME = 'condt.conf' 
PREFIX = "{0}@ConDict[{1}]>>>"
WELCOM = """****************************************************
*** Good day.                                    ***
*** For help, use the command ".help", nice work.***
****************************************************"""

def main():
    global CONF_NAME, PREFIX
................................................................................
        print("Not fount SQLite database")
        return 1
    # get name
    user = config['defuser'] if config['defuser'] else input("User name:")
    # create object
    account = Condt(user, config['database'])
    if not account:
        print('Validation error, by...')
        return 0
    print(WELCOM)

    while (True):
        conn_status = 'online' if account.online else 'offline'
        prefix = PREFIX.format(account.name, conn_status)
        command = input(prefix)
        get_command = account.handling_command(command)
        if get_command is None:
            print('Sorry, unknown command: "{0}"\nuse ".help" for more information'.format(command))
            continue
        if not get_command:
            print("By {0}!".format(account.name))
            return 0



if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print('Press Ctrl+C, Bye')