Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | merge with testing |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
ecc710b2d0bc47718f5b2c2b9fe5b09c |
| User & Date: | zorro 2012-10-13 15:36:24.195 |
Context
|
2012-10-17
| ||
| 17:54 | merge main functionality Leaf check-in: 45df65e986 user: zorro tags: trunk | |
|
2012-10-13
| ||
| 15:36 | merge with testing check-in: ecc710b2d0 user: zorro tags: trunk | |
|
2012-10-12
| ||
| 12:21 | default command = en-ru translate check-in: 53a4d2e45c user: alzay tags: testing | |
|
2012-09-18
| ||
| 18:52 | tests done check-in: 2928daa896 user: zorro tags: trunk | |
Changes
Changes to aside.py.
1 2 3 4 | #!/usr/bin/env python3 #-*- coding: utf-8 -*- import re, configparser, json, signal | | | < > | > > | > | > | > > | 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 |
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import re, configparser, json, signal
from urllib import request, parse
YANDEX_TRANSLATE_JSON = "http://translate.yandex.net/api/v1/tr.json/translate?"
TEST_CONNECT = "http://ya.ru/"
CHECK_MANY_SPACE = re.compile(r"\s+")
DEFCTEST = 10
def get_config_data(filename):
global DEFCTEST
result = {'database': None, 'defuser': None, 'defctest': DEFCTEST, 'debug': False}
config = configparser.ConfigParser()
try:
config.read(filename)
for sec in config.sections():
if 'dbname' in config[sec]:
result['database'] = config[sec]['dbname']
if 'default_user' in config[sec]:
result['defuser'] = config[sec]['default_user']
if 'test_count' in config[sec]:
result['defctest'] = int(config[sec]['test_count'])
if 'debug' in config[sec]:
result['debug'] = config[sec].getboolean('debug')
except (ValueError, KeyError, IndexError, TypeError) as er:
pass
return result
def prepare_str(input_str):
global CHECK_MANY_SPACE
result = CHECK_MANY_SPACE.sub(" ", input_str.strip())
|
| ︙ | ︙ | |||
36 37 38 39 40 41 42 |
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'}
| | > | > > | 42 43 44 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 |
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'}
params = {'lang': trans_types[trans_type], 'text': for_translate}
prepate_url = parse.urlencode(params, encoding="utf-8")
try:
conn = request.urlopen(YANDEX_TRANSLATE_JSON + 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
print("check connection...")
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
def check_ans(answer, enter):
global CHECK_MANY_SPACE
a1 = CHECK_MANY_SPACE.sub(" ", answer.lower().strip())
a2 = CHECK_MANY_SPACE.sub(" ", enter.lower().strip())
return (a1 == a2)
|
Changes to condt.conf.
1 2 3 4 | [database] dbname=db.sqlite [user] | > > | | 1 2 3 4 5 6 7 8 | [database] dbname=db.sqlite # developing mode (on/off, 1/0, yes/no) debug=yes [user] default_user=test test_count=10 |
Changes to condt.py.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import sqlite3, hashlib, getpass, datetime, csv, random
from aside import *
# please, change this stirg for your application
SALT = 'r8Uts$jLs74Lgh49_h75&w@dFsS4sgpm3Kqq['
EXPORT_NAME = 'condict_export_'
DEBUG = False
class IncorrectDbData(Exception): pass
class DublicationDbData(Exception): pass
class BaseConDict(object):
"""Base Console Dictionary class"""
| > | > > > > > | 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 |
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import sqlite3, hashlib, getpass, datetime, csv, random
from aside import *
# please, change this stirg for your application
SALT = 'r8Uts$jLs74Lgh49_h75&w@dFsS4sgpm3Kqq['
EXPORT_NAME = 'condict_export_'
TEST_NUM = 5
DEBUG = False
class IncorrectDbData(Exception): pass
class DublicationDbData(Exception): pass
class BaseConDict(object):
"""Base Console Dictionary class"""
def __init__(self, name, dbfile, debug):
global DEBUG
DEBUG = debug
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()
def prer(self, error):
global DEBUG
if DEBUG: print(error)
class Condt(BaseConDict):
"""Condt - class for ConDict"""
COMMANDS = {'.help': {'desc': 'list commands', 'command': None,
'full': 'output list commands'},
'.chname': {'desc': 'change current user name', 'command': None,
'full': 'change current info: login and name'},
|
| ︙ | ︙ | |||
58 59 60 61 62 63 64 65 |
'full': 'quit form program'},
'.test': {'desc': 'start test (default en)', 'command': None,
'full': 'start en-ru test'},
'.testru': {'desc': 'start ru-test', 'command': None,
'full': 'start ru-en test'},
'.testmix': {'desc': 'start en-ru test', 'command': None,
'full': 'start mix test'},
}
| > > > > | | > | < > > > > > > > > | > | > > > | > > | < < > > | > > > | > > > > | < < | | | > > | | < < | | | > > > > > > > > > > | 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 111 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 137 138 139 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 |
'full': 'quit form program'},
'.test': {'desc': 'start test (default en)', 'command': None,
'full': 'start en-ru test'},
'.testru': {'desc': 'start ru-test', 'command': None,
'full': 'start ru-en test'},
'.testmix': {'desc': 'start en-ru test', 'command': None,
'full': 'start mix test'},
'.testinfo': {'desc': 'information by test', 'command': None,
'full': 'full test information by test ID'},
'.testlist': {'desc': 'list of tests', 'command': None,
'full': 'this command print list of your tests'},
}
def __init__(self, name, dbfile, debug, ctest=10):
super().__init__(name, dbfile, debug)
self.__pcounter = 3
self.ctest = ctest
self.init_command()
self.user_id = self.get_user()
self.command_connect()
def get_user(self):
"""get user ID by name and password"""
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
user_id = self.handling_action(cur, ch_user_id)
else:
user_id = self.handling_add(cur)
cur.close()
return user_id
def init_command(self):
"""commands list"""
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['.import']['command'] = self.command_import
self.COMMANDS['.edit']['command'] = self.command_edit
self.COMMANDS['.delete']['command'] = self.command_delete
self.COMMANDS['.test']['command'] = self.command_testen
self.COMMANDS['.testru']['command'] = self.command_testru
self.COMMANDS['.testmix']['command'] = self.command_testmix
self.COMMANDS['.testlist']['command'] = self.command_testlist
self.COMMANDS['.testinfo']['command'] = self.command_testinfo
def hash_pass(self, password):
"""create password hash: text => hast string"""
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):
"""get user id by name - unique field"""
uid = None
try:
cur.execute("SELECT id FROM user WHERE name=(?)", (self.name,))
uid = cur.fetchone()
if uid: uid = uid[0]
except (sqlite3.DatabaseError, IndexError) as er:
self.prer(er)
return None
return uid
def check_password(self, cur, user_id, password):
"""check password"""
try:
cur.execute("SELECT id FROM user WHERE id=(?) AND password=(?)", (user_id, self.hash_pass(password)))
except sqlite3.DatabaseError as er:
self.prer(er)
return None
return cur.fetchone()
def handling_action(self, cur, ch_user_id):
"""password request"""
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 action in ('e', 'E'):
break
else:
print('select an option...')
return None
def handling_add(self, cur):
"""add new user, if not found name"""
while(True):
want_add = input('Are you want add new user? [Y/n]')
if want_add in ('', 'y', 'Y'):
name = input("You login [{0}]:".format(self.name))
if name == '':
name = self.name
fullname = input("You full name (optional):")
password = input("Password:") if DEBUG else getpass.getpass()
transaction_ok = False
try:
with self.connect:
cur.execute("INSERT INTO user (name, password, full) VALUES (?,?,?)", (name, self.hash_pass(password), fullname))
except sqlite3.DatabaseError as er:
print('Incorrect information, change data')
continue
if cur.rowcount == -1:
print('Incorrect information, change data')
continue
self.name = name
self.password = self.hash_pass(password)
return cur.lastrowid
elif want_add in ('n', 'N'):
break
else:
print('select an option...')
return None
def handling_command(self, command):
"""parser for user command"""
command, arg = get_command(command)
if command not in self.COMMANDS.keys():
# call en-ru translate
if command == '' or command[0] == '.': return None
arg = command + ' ' + arg if arg else command
result = self.COMMANDS['.en']['command'](arg)
else:
result = self.COMMANDS[command]['command'](arg)
return result
def command_help(self, arg=None):
"""callback for .help command"""
if arg:
s = '.' + arg
result = self.COMMANDS.get(s)
if result:
print("'{0}'\t{1}".format(s,result['full']))
else:
print('not found, use ".help"')
else:
for key, item in self.COMMANDS.items():
print("{0:.<30}{1}".format(key, item['desc']))
return 'help'
def command_exit(self, arg=None):
# pass
return 0
def command_chname(self, arg=None):
"""change user name"""
cur = self.connect.cursor()
while(True):
name = input("You login:")
fullname = input("You full name (optional):")
try:
if name == '':
raise IncorrectDbData()
with self.connect:
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
self.name = name
print("You name updated successfully")
break
cur.close()
return 'chname'
def command_chpassword(self, arg=None):
"""change user password"""
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:
with self.connect:
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, please change data')
e = input('Do you wand exit from password update [N/y]?')
if e in ('y', 'Y'):
break
continue
self.password = password1
print("You password updated successfully")
break
cur.close()
return 'chpassword'
def command_en(self, text):
"""en-ru translate"""
print(self.command_enru(text, 'en'))
return 'en'
def command_ru(self, text):
"""ru-en translate"""
print(self.command_enru(text, 'ru'))
return 'ru'
def command_enru(self, text, tr_type):
"""translate, only with online"""
global DEBUG
# found in offline DB
alreadyEx = self.alreadyex(text, tr_type)
if alreadyEx:
if DEBUG: print("[offline]")
return alreadyEx[0]
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):
"""print user dictionary"""
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 + '%')
|
| ︙ | ︙ | |||
279 280 281 282 283 284 285 286 287 288 289 290 291 |
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:
| > > > > > > > > > | | < | | < < < | < | < < < | | | < | | > > > > > > > > > > > > > > < > | | > > > | | < | > | < | 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 |
print(result_text.format(*result_param))
except (sqlite3.DatabaseError, IncorrectDbData) as er:
print('Sorry, error')
return 'list'
cur.close()
return 'list'
def check_default(self, defaultVar, addStr=''):
result = input(addStr + ' [' + defaultVar + ']:') if defaultVar else input(addStr +': ')
if not result:
if not defaultVar:
raise IncorrectDbData()
else:
result = defaultVar
return prepare_str(result)
def command_add(self, en_words=None):
"""add new user pattern"""
cur = self.connect.cursor()
print('Please enter your patterns:')
while True:
try:
en = self.check_default(en_words, 'En')
# check en translate
if self.alreadyex(en): raise DublicationDbData
# get translate
try:
ru_words = self.command_enru(en, 'en')[0]
except Exception as e:
if DEBUG: print(e)
ru_words = None
ru = self.check_default(ru_words, 'Ru')
with self.connect:
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:
self.prer(er)
print('Incorrect information, change data')
ent = input('Do you wand enter new words [Y/n]?')
if ent in ('n', 'N'):
break
continue
# may be use "else"
print("Words added successfully, ID={0}".format(translate_id))
break
cur.close()
return 'add'
def alreadyex(self, enru, typetr='en'):
"""check en words in DB"""
cur = self.connect.cursor()
if typetr == 'en':
addstr = "SELECT `rus` FROM `translate` WHERE `term`=(?) AND `user_id`=(?)"
params = (hashlib.md5(bytes(enru, 'utf-8')).hexdigest(), self.user_id)
else:
addstr = "SELECT `term`.`en` FROM `translate` LEFT JOIN `term` ON (`translate`.`term`=`term`.`token`) WHERE `translate`.`rus` LIKE (?) AND `translate`.`user_id`=(?) LIMIT 1;"
params = (prepare_str(enru), self.user_id)
cur.execute(addstr, params)
result = cur.fetchone()
cur.close()
return result
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 not cur.fetchone():
# insert in to tables
sql_list1 = "INSERT INTO `term` (`token`, `en`) VALUES ((?), (?))"
cur.execute(sql_list1, (token, prepare_str(en)))
# done in self.alreadyex
# cur.execute("SELECT `id` FROM `translate` WHERE `term`=(?) AND `user_id`=(?)", (token, self.user_id))
# if cur.fetchone(): raise DublicationDbData()
# add translate row
sql_list2 = "INSERT INTO `translate` (`term`, `user_id`, `rus`) VALUES (?, ?, ?)"
cur.execute(sql_list2, (token, self.user_id, prepare_str(ru)))
translate_id = cur.lastrowid
# add progress row
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
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', newline='', encoding='utf-8'), dialect='excel', delimiter=';', quoting=csv.QUOTE_ALL)
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,))
results = cur.fetchall()
for result in results:
writer_csv.writerow(result)
except Exception as er:
self.prer(er)
print("Export error")
else:
print("Export finished, successfully export {0} record(s) to file: {1}".format(len(results), export_name))
cur.close()
return 'export'
def command_edit(self, translate_id):
"""Edit translate words form DB, search by ID"""
# search id
cur = self.connect.cursor()
try:
|
| ︙ | ︙ | |||
386 387 388 389 390 391 392 |
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()
| > | | | | | | | | | > < < | < < < < > | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
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()
with self.connect:
if token != result[2]:
cur.execute("INSERT INTO `term` (`token`, `en`) VALUES ((?), (?))", (token, prepare_str(en)))
need_del = True
# translate
cur.execute("UPDATE `translate` SET `rus`=(?), `term`=(?) WHERE `term`=(?) AND `user_id`=(?)", (prepare_str(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:
self.prer(er)
print('Record not found for current user.')
except (TypeError, ValueError, sqlite3.DatabaseError) as er:
self.prer(er)
print("Error, use '.edit ID' (ID is numerical)")
else:
print('Successfully update')
cur.close()
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:
|
| ︙ | ︙ | |||
432 433 434 435 436 437 438 |
# 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
| > | | | | | | | | | | > < < | < < < < > > > > | | | | | | | | | | | | | | | | | | | | > | | | | < | < < | < | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | > < < < < < | | > | > | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
# 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
with self.connect:
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 er:
self.prer(er)
print('Record not found for current user.')
except (sqlite3.DatabaseError, TypeError) as er:
self.prer(er)
print("Error, use '.delete [ID or pattern]' (ID is numerical)")
else:
print('Successfully update')
cur.close()
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):
"""search user pattern"""
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()
def command_import(self, import_name):
"""import user dict to CSV"""
start = False
cur = self.connect.cursor()
uniqCount, dublCount = 0, 0
try:
read_csv = csv.reader(open(import_name, newline='', encoding='utf-8'), dialect='excel', delimiter=';', quoting=csv.QUOTE_ALL)
with self.connect:
for row in read_csv:
if not start:
start = True
continue
if len(row) < 2: continue
en = row[0]
ru = row[1]
# check term
token = hashlib.md5(bytes(prepare_str(en), 'utf-8')).hexdigest()
# check translate
cur.execute("SELECT `term` FROM `translate` WHERE `user_id`=(?) AND `term`=(?)", (self.user_id, token))
if not cur.fetchone():
# check term
cur.execute("SELECT `token` FROM `term` WHERE `token`=(?)", (token,))
if not cur.fetchone():
cur.execute("INSERT INTO `term` (`token`, `en`) VALUES ((?), (?))", (token, prepare_str(en)))
cur.execute("INSERT INTO `translate` (term,user_id,rus) VALUES (?,?,?)", (token, self.user_id, prepare_str(ru)))
translate_id = cur.lastrowid
cur.execute("INSERT INTO `progress` (`translate_id`) VALUES (?)", (translate_id,))
print("Added: {0}".format(en))
uniqCount += 1
else:
print("Dublicate record: {0}".format(en))
dublCount += 1
except sqlite3.DatabaseError as er:
self.prer(er)
print("DB error for {0}".format(en))
except (TypeError, IOError) as er:
self.prer(er)
print("Please write '.import import_file.csv'")
else:
print("Successfully import {0} new record(s), with {1} duplicates.".format(uniqCount, dublCount))
cur.close()
return 'import'
def command_testen(self, arg):
self.command_test(arg, 0)
return 'test-en'
def command_testru(self, arg):
self.command_test(arg, 1)
return 'test-ru'
def command_testmix(self, arg):
self.command_test(arg, 2)
return 'test-mix'
def command_test(self, arg=None, type_test=0):
"""start user test"""
cur = self.connect.cursor()
created = datetime.datetime.now()
name = ''
try:
arg = int(arg) if arg else self.ctest
except (TypeError, ValueError) as e:
arg = self.ctest
# start test
types_test = ('en-ru', 'ru-en', 'mix')
print("Start test, type: '{0}', count: {1}".format(types_test[type_test], arg))
try:
with self.connect:
# insert `test`
cur.execute("INSERT INTO `test` (`user_id`, `name`, `created`) VALUES (?,?,?)", (self.user_id, types_test[type_test], created))
test_id = cur.lastrowid
alreadyq, to_save, progress = [], [], []
for i in range(1, arg+1):
# 0-en, 1-ru, 2-mix
question, answer, translate_id = self.gen_question(cur, type_test, alreadyq)
if question is None:
print("too few words")
break
alreadyq.append(str(translate_id))
print('\nQuestion {0}: {1}'.format(i,question))
enter = input('translate: ')
# check error
er = False if check_ans(answer, enter) else True
result_row = {"test_id": test_id, "num": i, "question": question, 'answer': answer, 'enter': enter, 'error': er}
to_save.append(result_row)
progress_error = 1 if er else 0
progress.append({'translate_id': translate_id, 'error': progress_error})
# save results
cur.executemany("INSERT INTO `result` (`test_id`,`number`,`question`,`answer`,`enter`,`error`) VALUES (:test_id, :num, :question, :answer, :enter, :error)", to_save)
# update test
cur.execute("UPDATE `test` SET `finished`=(?) WHERE `id`=(?)", (datetime.datetime.now(), test_id))
# update progress
cur.executemany("UPDATE `progress` SET `all`=`all`+1, `error`=`error`+:error WHERE `translate_id`=:translate_id", progress)
except sqlite3.DatabaseError as er:
self.prer(er)
print("Error")
else:
print("Test successfully finished, ID={}.".format(test_id))
self.print_test_result(to_save, test_id, False)
cur.close()
def print_test_result(self, tests, test_id, print_right=False):
"""print test info"""
right, error = 0, 0
print("*******YOUR RESULT********")
for q in tests:
if q['error']:
error += 1
print("Q#{0} (Error): {1}\n[correct] {2}\n[you] {3}\n".format(q['num'],q['question'],q['answer'],q['enter']))
else:
right += 1
if print_right:
print("Q#{0}: {1}\n[correct] {2}\n[you] {3}\n".format(q['num'],q['question'],q['answer'],q['enter']))
print("**************************")
print("Test ID={2}. Result: {0} error(s) from {1}".format(error,(right + error), test_id))
def gen_question(self, cur, type_test, alreadyq):
"""genaration question for any test"""
sql_list = "SELECT `translate`.`id`, `term`.`en`, `translate`.`rus` FROM `translate` LEFT JOIN `term` ON (`translate`.`term`=`term`.`token`) WHERE `translate`.`user_id`=" + str(self.user_id) + " AND (`translate`.`id` NOT IN (" + ", ".join(alreadyq) + "))"
cur.execute(sql_list)
for_search = cur.fetchall()
if not for_search:
return None, None, None
row = for_search[random.randint(0,len(for_search)-1)]
# 0 => en, 1 => ru, 2 => mix
translate_id = row[0]
if type_test == 0:
question, answer = row[1], row[2]
elif type_test == 1:
question, answer = row[2], row[1]
else:
i = random.randint(1,2)
j = 1 if i == 2 else 2
question, answer = row[i], row[j]
return question, answer, translate_id
def command_testlist(self, arg=None):
"""print user tests"""
global TEST_NUM
cur = self.connect.cursor()
try:
arg = int(arg) if arg else TEST_NUM
sql_list = "SELECT `test`.`id`, `test`.`name`, `test`.`created`, `test`.`finished` FROM `test` WHERE `test`.`user_id`=(?) ORDER BY `test`.`created` DESC, `test`.`finished` DESC LIMIT (?);"
cur.execute(sql_list, (self.user_id, arg))
i = 1
print("Your tests:")
for row in cur.fetchall():
created = datetime.datetime.strptime(row[2], "%Y-%m-%d %H:%M:%S.%f")
finished = datetime.datetime.strptime(row[3], "%Y-%m-%d %H:%M:%S.%f")
cur.execute("SELECT COUNT(*) FROM `result` WHERE `result`.`test_id`=(?) AND `result`.`error`=1", (row[0],))
results = cur.fetchone()
error = results[0] if results else 0
cur.execute("SELECT COUNT(*) FROM `result` WHERE `result`.`test_id`=(?)", (row[0],))
results = cur.fetchone()
allres = results[0] if results else 0
print("{0}. ID={1}, type: {2}, {5} error(s) from {6}\n created: {3}, finished: {4}\n".format(i, row[0], row[1], created.strftime("%d.%m.%Y %H:%M:%S"), finished.strftime("%d.%m.%Y %H:%M:%S"), error, allres))
i +=1
except (ValueError, TypeError) as er:
self.prer(er)
print("Error, use <.testlist N> (N - number)")
except sqlite3.DatabaseError as er:
self.prer(er)
print("Error")
cur.close()
return 'tetslist'
def command_testinfo(self, arg=None):
cur = self.connect.cursor()
try:
test_id = int(arg)
# test info
sql_list = "SELECT `test`.`id`, `test`.`name`, `test`.`created`, `test`.`finished` FROM `test` WHERE `test`.`user_id`=(?) AND `test`.`id`=(?);"
cur.execute(sql_list, (self.user_id, test_id))
test = cur.fetchone()
if not test:
print("Empty test")
return "test_info"
created = datetime.datetime.strptime(test[2], "%Y-%m-%d %H:%M:%S.%f")
finished = datetime.datetime.strptime(test[3], "%Y-%m-%d %H:%M:%S.%f")
print("ID={0}, type: {1}, created: {2}, finished: {3}\n".format(test[0], test[1], created.strftime("%d.%m.%Y %H:%M:%S"), finished.strftime("%d.%m.%Y %H:%M:%S")))
# results
cur.execute("SELECT `result`.`number`, `result`.`question`, `result`.`answer`, `result`.`enter`, `result`.`error` FROM `result` WHERE `result`.`test_id`=(?) ORDER BY `result`.`number`;", (test_id,))
for_print = []
for row in cur.fetchall():
for_print.append({'num': row[0], 'question': row[1], 'answer': row[2], 'enter': row[3], 'error': row[4]})
self.print_test_result(for_print, test_id, True)
except (ValueError, TypeError) as er:
self.prer(er)
print("Error, use <.tesinfo ID> (ID - number)")
except sqlite3.DatabaseError as er:
self.prer(er)
print("Error")
cur.close()
return 'testinfo'
|
Changes to db.sqlite.
cannot compute difference between binary files
Changes to dict.csv.
1 | "ENGLISH";"RUSSIAN" | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 | "ENGLISH";"RUSSIAN" |
Changes to main.py.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 |
config = get_config_data(CONF_NAME)
if not config['database'] or not os.path.exists(config['database']):
print("Not fount SQLite database")
return 1
# get name
user = config['defuser'] if config['defuser'] else input("User name:")
# create object
| | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
config = get_config_data(CONF_NAME)
if not config['database'] or not os.path.exists(config['database']):
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'], config['debug'], config['defctest'])
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)
|
| ︙ | ︙ |
Changes to readme.
1 2 3 4 5 6 7 8 9 10 | ConDict is simple Console Dictionary Uses: - SQLite3 http://www.sqlite.org/ - Python3 http://www.python.org/ - Yandex translate http://api.yandex.ru/translate/doc/dg/reference/translate.xml - Fossil http://www.fossil-scm.org/ | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
ConDict is simple Console Dictionary
Uses:
- SQLite3
http://www.sqlite.org/
- Python3
http://www.python.org/
- Yandex translate
http://api.yandex.ru/translate/doc/dg/reference/translate.xml
- Fossil
http://www.fossil-scm.org/
Test user:
login: test
password: 123
|