//public/js/practice.js
class Typing{
constructor(practice){
this.letters = practice;
this.counter = Math.floor(Math.random() * (this.letters).length);
this.usedCounter = this.counter;
this.nextKey = this.letters[this.counter][0];
this.pressedKey = 0;
this.mistake = 0;
this.scoreLetter = 0;
this.numLetters = 0;
this.setClock();
this.setColor(this.nextKey);
}
setColor(nextKey){
var rightShift = {'A':1,'S':1,'D':1,'F':1,'G':1,'Z':1,'X':1,'C':1,'V':1,'B':1,'Q':1,'W':1,'E':1,'R':1,'T':1,
'~':1,'!':1,'@':1,'#':1,'$':1,'%':1};
var leftShift = {'H':1,'J':1,'K':1,'L':1,':':1,'"':1,'N':1,'M':1,'<':1,'>':1,'?':1,'Y':1,'U':1,'I':1,'O':1,'P':1,
'{':1,'}':1,'|':1,'^':1,'&':1,'*':1,'(':1,')':1,'_':1,'+':1};
var keys = $(".keyboard-base").children().css({'color':'black'});
for(var index in keys){
var key = keys[index].innerHTML;
if(key){
var data = keys[index].getAttribute("data-l");
if(key == "'"){
data += '"';
}
if((nextKey == data[5]) || (nextKey == data[6])){
keys[index].focus();
$(keys[index]).css({'color':'teal'});
if(this.nextKey in rightShift){
$('.rightshift').css({'color':'teal'});
}else if(this.nextKey in leftShift){
$('.leftshift').css({'color':'teal'});
}
break;
}
}
}
$('#letter').html(this.letters[this.counter][2]);
}
checkKey(key){
if(key == this.nextKey){
this.scoreLetter += 1;
while(true){
this.counter = Math.floor(Math.random() * (this.letters).length);
if(this.counter != this.usedCounter){
this.usedCounter = this.counter
break;
}
}
this.pressedKey = this.nextKey;
this.nextKey = this.letters[this.counter][0];
this.setColor(this.nextKey);
}else{
document.getElementById('beep').play();
$('#mistake span').html(this.toKhNum(++this.mistake));
}
$('#letters span').html(this.toKhNum(++this.numLetters))
}
toKhNum(number){
const khNum = {'0':'០', '1':'១', '2':'២', '3':'៣', '4':'៤', '5':'៥', '6':'៦', '7':'៧', '8':'៨', '9':'៩'};
var stringNum = number.toString();
var khNumString = '';
for(var i in stringNum){
khNumString += khNum[stringNum[i]];
}
return khNumString;
}
setClock(){
var second = 0;
var minute = 0;
var hour = 0;
var minuteTest = 0;
var callNextLevel = true;
var clock = setInterval(() => {
$('#timelapse .second').html(this.toKhNum(++second));
if(second == 60){
second = 0;
$('#timelapse .minute').html(this.toKhNum(++minute));
}
if(minute == 60){
minute = 0;
++minuteTest;
$('#timelapse .hour').html(this.toKhNum(++hour));
}
if((minuteTest <= 2) && (this.scoreLetter >= 480) && (this.mistake <= 10))
if(callNextLevel){
this.updateLevel();
callNextLevel = false;
}
}, 1000);
}
updateLevel(){
$.post("login/update",
function(data, status){
if(status == "success"){
var grade = typing.toKhNum(data.grade);
$('#info').html(`សូមអបអរសាទដោយអ្នកបានឆ្លងចូលកំរឹតទី ${grade} ហើយ!!`);
$('#level span').html(grade);
}
});
}
}//end of class
#controllers/login.py
import config
from copy import deepcopy
from bottle import Bottle, template, request, response, redirect
from verify_email import verify_email
from models import userdb
class Login(Bottle):
def __init__(self):
super().__init__()
self.get('/', callback=self.index)
self.post('/user', callback=self.postUser)
self.get('/logout', callback=self.logout)
self.post('/update', callback=self.updateUser)
self.userdb = userdb.Userdb()
def index(self):
kdict = deepcopy(config.kdict)
kdict['blogTitle'] = "ចុះឈ្មោះ"
return template('login', data=kdict)
def postUser(self):
kdict = deepcopy(config.kdict)
username = request.forms.getunicode('fusername')
password = request.forms.getunicode('fpassword')
email = request.forms.getunicode('femail')
checkEmail = verify_email(email)
if checkEmail and username and password:
result = self.userdb.checkUser(username, password, email)
if result:
response.set_cookie('logged-in', result[0], path='/', secret=kdict['secretKey'])
redirect('/')
else:
result = self.userdb.checkUsername(username)
if not result:
response.set_cookie('logged-in', username, path='/', secret=kdict['secretKey'])
self.userdb.insert(username, password, email, 1, False)
redirect('/')
else:
kdict['message'] = 'ឈ្មោះអ្នកប្រើប្រាស់នេះត្រូវបានគេប្រើរួចហើយ។'
return template('login', data=kdict)
else:
if not checkEmail:
kdict['message'] = 'Email របស់លោកអ្នកមិនត្រឹមត្រូវទេ។'
return template('login', data=kdict)
elif not (username or password):
kdict['message'] = 'ត្រូវមានឈ្មោះអ្នកប្រើប្រាស់និងពាក្យសំងាត់។'
return template('login', data=kdict)
def logout(self):
kdict = deepcopy(config.kdict)
username = request.get_cookie('logged-in', secret=kdict['secretKey'])
if username:
self.userdb.deleteUser(username)
response.delete_cookie('logged-in', path='/', secret=kdict['secretKey'])
redirect('/')
def updateUser(self):
kdict = deepcopy(config.kdict)
username = request.get_cookie('logged-in', secret=kdict['secretKey'])
if username:
self.userdb.updateUser(username)
grade = self.userdb.checkUsername(username)
return {'grade':grade[2]}
GitHub: https://khmerweb-typing.herokuapp.com
Heroku: https://khmerweb-typing.herokuapp.com/














