14 #include <ConfigHolder.h>
18 namespace freeRecite
{
23 std::cerr
<< "Can't load the config file.\n";
26 if(!dictionary
.load()) {
27 std::cerr
<< "Can't load the dictionary.\n";
36 void CUI::run(int argc
, char *argv
[]) {
41 if(!strcmp(argv
[1],"--help")) {
44 }else if(!strcmp(argv
[1],"--version")) {
45 std::cout
<< "Free Recite version 1.0" << std::endl
;
47 }else if(!strcmp(argv
[1],"all")) {
50 }else if(!strcmp(argv
[1],"cls")) {
53 }else if(!strcmp(argv
[1],"done")) {
56 }else if(!strcmp(argv
[1],"ls")) {
59 }else if(!strcmp(argv
[1],"modify")) {
60 modify(std::string(""));
62 }else if(!strcmp(argv
[1],"status")) {
65 }else if(!strcmp(argv
[1],"stress")) {
71 if(!strcmp(argv
[1],"export")) { //frt export <taskID>
72 if( ( taskID
= atoid(argv
[2]) ) != 0 ) {
75 } else { //frt export <filename>
76 exportFromFile(argv
[2]);
79 }else if(!strcmp(argv
[1],"new")) {
82 }else if(!strcmp(argv
[1],"merge")) {
85 }else if(!strcmp(argv
[1],"modify")) {
86 modify(std::string(argv
[2]));
88 }else if(!strcmp(argv
[1],"recite")) { //frt recite <taskID>
89 if( ( taskID
= atoid(argv
[2]) ) != 0 ) {
92 }else { //frt recite <fileName>
93 recite(argv
[2],false);
96 }else if(!strcmp(argv
[1],"rrecite")) { //frt recite <taskID>
97 if( ( taskID
= atoid(argv
[2]) ) != 0 ) {
100 }else { //frt recite <fileName>
101 recite(argv
[2],true);
104 }else if(!strcmp(argv
[1],"remove")) {
105 if( ( taskID
= atoid(argv
[2]) ) != 0 ){
109 }else if(!strcmp(argv
[1],"test")) {
110 if( ( taskID
= atoid(argv
[2]) ) != 0 ) {
113 }else { //frt test <fileName>
117 }else if(!strcmp(argv
[1],"rtest")) {
118 if( ( taskID
= atoid(argv
[2]) ) != 0 ) {
121 }else { //frt rtest <fileName>
126 } //else if(argc == 3)
128 std::cout
<< "frt: \'" << argv
[argc
-1] << "\' is not a frt-command. "
129 << "See \'frt --help\'." << std::endl
;
132 time_t CUI::atoid(const char *argv
) {
133 std::istringstream
ssm(argv
);
136 return static_cast<time_t>(tid
);
138 return static_cast<time_t>(0);
141 void CUI::cleanStress() {
142 ::remove(configHolder
.keyFile().c_str());
146 for(int i
= 0; i
< 10; ++i
)
147 std::cerr
<< std::endl
;
150 void CUI::createNew(const char *fileName
) {
151 std::string taskName
;
152 std::ifstream
ifs(fileName
);
154 std::cout
<< "Can't find the file." << std::endl
;
157 std::set
<std::string
> wordSet
;
158 std::string word
, name
, cmd
;
159 std::cout
<< "Give a task name for it?" << std::endl
;
160 std::cout
<< "(Press Enter will give a default name): ";
161 std::getline(std::cin
,name
);
163 std::getline(ifs
,word
);
164 while(word
[word
.size()-1] == ' ')
165 word
.erase(word
.size()-1);
166 while(!dictionary
.lookUp(word
) && !word
.empty()) {
167 std::cout
<< '\"' << word
<< '\"'
168 << " can't be fond in your dictionary"<<std::endl
169 << "Remove(R),Modify(M) or Add to dictionary(A)? (R/m/a)"
171 std::getline(std::cin
,cmd
);
173 if(cmd
== "A" || cmd
== "a")
174 while(!modify(word
)) /* An empty sentance. */;
175 else if(cmd
== "M" || cmd
== "m") {
176 std::cout
<< "Input the new word: ";
177 std::getline(std::cin
,word
); //Get a new word from the user.
180 std::getline(ifs
,word
); //Read a new word from file.
183 wordSet
.insert(word
);
185 unsigned taskMaxWords
= 0;
186 if(wordSet
.size() > 30)
190 if(manager
.createTask(wordSet
,name
.c_str(),taskMaxWords
)) {
191 std::cout
<< "Creat a task SUCCESS!" << std::endl
;
194 std::cerr
<< "Can't creat a task :}" << std::endl
;
198 void CUI::exportFromFile(const char *fileName
) {
199 std::ifstream
ifs(fileName
);
201 std::set
<std::string
> wdSet
;
206 std::getline(ifs
, tmpWord
);
207 while(tmpWord
[tmpWord
.size()-1] == ' ')
208 tmpWord
.erase(tmpWord
.size()-1);
210 wdSet
.insert(tmpWord
);
213 std::set
<std::string
>::const_iterator itr
= wdSet
.begin();
214 while(itr
!= wdSet
.end()) {
215 if(dictionary
.lookUp(*itr
)) {
216 std::cout
<< std::setw(12) << std::setfill(' ') << std::left
217 << dictionary
.word() << ' ';
218 std::cout
<< '[' << dictionary
.phonetics() << ']';
219 std::cout
<< ' ' << dictionary
.translation() << std::endl
;
221 std::cout
<< *itr
<< " *** " << std::endl
;
227 void CUI::exportDone() {
228 exportFromFile(configHolder
.doneFile().c_str());
231 void CUI::exportTask(time_t taskID
) {
232 if(!manager
.hasTask(taskID
)) {
233 std::cout
<< "There's no this task!" << std::endl
;
236 std::string fileName
= Scanner::getTaskFileName(taskID
);
237 exportFromFile(fileName
.c_str());
240 void CUI::exportStress(){
241 exportFromFile(configHolder
.keyFile().c_str());
244 void CUI:: merge(const char *fileName
) {
245 if(!dictionary
.merge(fileName
))
246 std::cerr
<< "FAIL" << std::endl
;
248 std::cerr
<< "SUCCESS" << std::endl
;
251 void CUI::test(const char *fileName
, bool reverse
) {
253 if(!tester
.load(fileName
)) {
254 std::cerr
<< "Can't open this file!" << std::endl
;
258 time_t startTime
= 0;
263 r_scanProcess(tester
);
268 startTime
= (endTime
- startTime
)/60;
269 time_t usedTime
= startTime
> 0 ? startTime
: 1;
270 std::cout
<< std::endl
<< "Used Time: "
271 << usedTime
<< " minutes" << std::endl
;
272 std::cout
<< "There're " << tester
.capability() << " words in this task. "
273 << tester
.getScore() << "% of them you have remembered."
277 void CUI::test(time_t taskID
, bool reverse
) {
279 if(!manager
.hasTask(taskID
)) {
280 std::cout
<< "There's no this task!" << std::endl
;
283 if(!tester
.load(taskID
)) {
284 std::cerr
<< "error when load words!" << std::endl
;
287 time_t startTime
= 0;
292 r_scanProcess(tester
);
297 startTime
= endTime
- startTime
;
298 std::cout
<< std::endl
<< "Used Time: "
299 << startTime
/60 << "minutes" << std::endl
;
300 int testResult
= manager
.test(taskID
,tester
.getScore());
301 if(testResult
== 0) {
302 std::cout
<<"Your score is " << tester
.getScore() << std::endl
;
303 std::cout
<<"You passed it!"<<std::endl
;
304 time_t nextTime
= manager
.getNextTime(taskID
);
305 struct tm
* timeinfo
;
307 timeinfo
= localtime(&nextTime
);
308 strftime(buffer
,30,"%Y.%m.%d %H:%M:%S",timeinfo
);
309 std::cout
<< "Then next reviewing time is: " << buffer
311 }else if(testResult
== -1){
312 std::cout
<<"Your score is " << tester
.getScore() << std::endl
313 <<"You haven't passed it :} "<<std::endl
;
314 }else { // testResult == 1
315 std::cout
<< "Congratulations! You have complish this task!"
320 void CUI::recite(const char *fileName
, bool reverse
) {
322 if(!reciter
.load(fileName
)){
323 std::cerr
<< "Can't open this file!" << std::endl
;
326 time_t startTime
= 0;
330 r_scanProcess(reciter
);
332 scanProcess(reciter
);
334 startTime
= (endTime
- startTime
)/60;
335 time_t usedTime
= startTime
> 0 ? startTime
: 1;
336 std::cout
<< std::endl
<< "Used Time: "
337 << usedTime
<< " minutes" << std::endl
;
338 float r_num
= reciter
.capability() - reciter
.getScore();
339 std::cout
<< "There're " << reciter
.capability() << " words in this task. "
340 << reciter
.getScore() << " of them you have known before."
341 << std::endl
<< "Your Reciting Rate is: "
343 << " word(s)/min" << std::endl
;
346 void CUI::recite(time_t taskID
, bool reverse
) {
347 if(!manager
.hasTask(taskID
)) {
348 std::cerr
<< "There's no this task!" << std::endl
;
353 if(!reciter
.load(taskID
)) {
354 std::cerr
<< "error when load words!" << std::endl
;
357 time_t startTime
= 0;
361 r_scanProcess(reciter
);
363 scanProcess(reciter
);
365 startTime
= (endTime
- startTime
)/60;
366 time_t usedTime
= startTime
> 0 ? startTime
: 1;
367 std::cout
<< std::endl
<< "Used Time: "
368 << usedTime
<< " minutes" << std::endl
;
369 float r_num
= reciter
.capability() - reciter
.getScore();
370 std::cout
<< "There're " << reciter
.capability() << " words in this task. "
371 << reciter
.getScore() << " of them you have known before."
372 << std::endl
<< "Your Reciting Rate is: "
374 << " word(s)/min" << std::endl
;
377 void CUI::remove(time_t taskID
) {
378 if(!manager
.hasTask(taskID
)) {
379 std::cerr
<< "There's no this task!" << std::endl
;
382 manager
.removeTask(taskID
);
385 bool CUI::modify(const std::string
&word
) {
386 std::string newItem
,inputStr
;
389 std::getline(std::cin
,inputStr
);
390 newItem
.append("[W]"+inputStr
);
392 newItem
.append("[W]"+word
);
394 std::cout
<<"θ_ɑ_ʌ_ә_є_æ_ɔ_ʃ_ð_ŋ_ʒ"<<std::endl
;
395 std::cout
<<"0_1_2_3_4_5_6_7_8_9_="<<std::endl
;
397 std::getline(std::cin
,inputStr
);
398 newItem
.append("[T]"+inputStr
);
400 std::getline(std::cin
,inputStr
);
401 newItem
.append("[M]"+inputStr
);
403 if(!dictionary
.modify(newItem
)) {
404 std::cout
<<"ERROR!" << std::endl
;
407 std::cout
<<"SUCCESS!"<<std::endl
;
412 int i
= manager
.currNumWords();
414 std::cerr
<< "Error occurs when read tasks" << std::endl
;
419 time_t earlyTask
= manager
.getAllTasks().begin()->first
;
421 current
= (current
- earlyTask
) / (3600 * 24); //Days
424 std::cout
<< "Current Amount: " << i
<< std::endl
425 << "Reciting Rate : " << i
/current
<< " words/day" << std::endl
426 << "The foremost one is created before " << current
<< " days."
430 void CUI::showActive() {
431 if(!manager
.refresh()) {
432 std::cout
<< "The configure file is broken!" << std::endl
;
435 if(manager
.getActiveTaskNum() == 0) {
437 std::cout
<< "There's no new task should be review,type \"new\" to creat one."
440 if(manager
.getNextTime() != 0) {
441 time_t nextTime
= manager
.getNextTime();
442 struct tm
* timeinfo
;
444 timeinfo
= localtime(&nextTime
);
445 strftime(buffer
,30,"%Y.%m.%d %H:%M:%S",timeinfo
);
446 std::cout
<< "The nearest reviewing time is at " << buffer
448 << "Please use FreeRecite at that time!"
453 std::cout
<< std::setw(5) << std::setfill(' ') << std::left
<< "N"
454 << std::setw(25) << std::setfill(' ') << std::left
<< "Name"
455 << std::setw(5) << std::setfill(' ') << std::left
<< "Step"
456 << std::setw(10) << std::setfill(' ') << std::left
<< " ID"
459 for(int i
= 0; i
< manager
.getActiveTaskNum(); ++i
) {
460 std::cout
<< std::setw(5) << std::setfill(' ') << std::left
<< i
+1
461 << std::setw(25) << std::setfill(' ') << std::left
462 << manager
.getTaskName(manager
.getActiveTasks().at(i
)) << ' '
463 << std::setw(5) << std::setfill(' ') << std::left
464 << manager
.getTaskStep(manager
.getActiveTasks().at(i
))
465 << std::setw(10) << std::setfill(' ') << std::right
466 << manager
.getActiveTasks().at(i
)
472 void CUI::showAll() {
473 if(!manager
.refresh()) {
474 std::cout
<< "The configure file is broken!" << std::endl
;
477 if(manager
.getAllTasks().empty()) {
478 std::cout
<< "There's no new task should be review,type \"new\" to creat one."
482 std::cout
<< "There's " << manager
.getAllTasks().size()
483 << " tasks should review." << std::endl
;
484 std::cout
<< std::setw(5) << std::setfill(' ') << std::left
<< "N"
485 << std::setw(20) << std::setfill(' ') << std::left
<< "Name"
486 << std::setw(5) << std::setfill(' ') << std::left
<< "Step"
487 << std::setw(12) << std::setfill(' ') << std::left
<< " ID"
488 << std::setw(12) << std::setfill(' ') << std::left
<< " Review Time"
491 std::map
<time_t,Task
>::const_iterator itr
= manager
.getAllTasks().begin();
493 while(++i
,itr
!= manager
.getAllTasks().end()) {
494 std::cout
<< std::setw(5) << std::setfill(' ') << std::left
<< i
495 << std::setw(20) << std::setfill(' ') << std::left
496 << manager
.getTaskName(itr
->first
) << ' '
497 << std::setw(5) << std::setfill(' ') << std::left
498 << manager
.getTaskStep(itr
->first
)
499 << std::setw(12) << std::setfill(' ') << std::right
500 << itr
->first
<< " ";
501 time_t nextTime
= manager
.getNextTime(itr
->first
);
502 struct tm
* timeinfo
;
504 timeinfo
= localtime(&nextTime
);
505 strftime(buffer
,30,"%Y.%m.%d %H:%M:%S",timeinfo
);
506 std::cout
<< std::setw(12) << std::setfill(' ') << std::left
507 << buffer
<< std::endl
;
513 void CUI::showResult(bool result
) {
515 std::cout
<<" ** * * "<<std::endl
;
516 std::cout
<<" * * * * "<<std::endl
;
517 std::cout
<<" * * ** "<<std::endl
;
518 std::cout
<<" * * * * "<<std::endl
;
519 std::cout
<<" ** * * "<<std::endl
;
522 std::cout
<<"##### #### #### "<<std::endl
;
523 std::cout
<<"# # # # # "<<std::endl
;
524 std::cout
<<"##### #### #### "<<std::endl
;
525 std::cout
<<"# # # # # "<<std::endl
;
526 std::cout
<<"##### # # # # "<<std::endl
;
530 void CUI::r_scanProcess(Scanner
&scanner
) {
532 std::string inputStr
;
533 while(scanner
.isValid()) {
535 if(dictionary
.lookUp(scanner
.getWord())) {
536 std::cout
<<" Amount: "<< scanner
.capability()
537 <<" R_Num: " << scanner
.size()
538 <<" R_Times: "<< scanner
.times() << std::endl
;
539 std::cout
<<"**********************************************" << std::endl
;
540 std::cout
<<"*[W]: "<< dictionary
.word();
541 std::getline(std::cin
,inputStr
);
542 if( !dictionary
.phonetics().empty() )
543 std::cout
<< "*[T]: /" << dictionary
.phonetics() << "/" << std::endl
;
544 std::cout
<< "*[M]: " << dictionary
.translation() << std::endl
;
545 std::cout
<< "**********************************************" << std::endl
;
546 std::cout
<< "Type \'/help\' to show the implicit command!" << std::endl
;
547 std::cout
<< "Do you remember it?(Y/n) ";
549 std::getline(std::cin
,inputStr
);
550 if(inputStr
== "/help"){
553 } else if(inputStr
== "/modify"){
554 modify(scanner
.getWord());
556 } else if(inputStr
== "/add"){
557 std::cout
<< "Input new word: ";
558 std::getline(std::cin
,inputStr
);
559 scanner
.add(inputStr
);
560 std::cout
<< "SUCCESS!" << std::endl
;
562 } else if(inputStr
== "/rm"){
563 inputStr
= scanner
.getWord();
564 scanner
.remove(inputStr
);
565 std::cout
<< "SUCCESS!" << std::endl
;
567 } else if(inputStr
== "/stop") {
570 if(inputStr
== "Y" || inputStr
== "y" || inputStr
.empty())
575 std::cout
<< std::endl
;
577 scanner
.test(result
);
580 } else { //If the dictionary can't look up the current word
581 std::cout
<< '\"' << scanner
.getWord() << '\"'
582 << " can't be found in your dictionary."
583 << "\n Modify Or Remove it from task(M/r) ";
585 std::getline(std::cin
,m_r
);
586 if(m_r
== "R" || m_r
== "r") {
587 inputStr
= scanner
.getWord();
588 scanner
.remove(inputStr
);
589 std::cout
<< "SUCCESS!" << std::endl
;
591 modify(scanner
.getWord());
597 void CUI::scanProcess(Scanner
&scanner
) {
599 std::string inputStr
;
600 while(scanner
.isValid()) {
602 if(dictionary
.lookUp(scanner
.getWord())){
603 std::cout
<<" Type \'/help\' to show the implicit command!"
605 std::cout
<<" Amount: "<< scanner
.capability()
606 <<" R_Num: " << scanner
.size()
607 <<" R_Times: "<< scanner
.times()<<std::endl
;
608 std::cout
<<"[M]: "<<dictionary
.translation()<<std::endl
;
609 std::cout
<<"**********************************************" << std::endl
;
610 std::cout
<<"*Input : ";
611 std::getline(std::cin
,inputStr
);
613 if(inputStr
== "/hint") {
614 std::cout
<< "*Hint : " << dictionary
.word().at(0);
615 for(unsigned i
= 1; i
< dictionary
.word().size(); ++i
)
617 if( !dictionary
.phonetics().empty() )
618 std::cout
<< " /" << dictionary
.phonetics() << "/";
619 std::cout
<< std::endl
<<"*Input : ";
620 std::getline(std::cin
,inputStr
);
623 if(inputStr
== "/help"){
626 } else if(inputStr
== "/modify"){
627 modify(scanner
.getWord());
629 } else if(inputStr
== "/add"){
630 std::cout
<< "Input new word: ";
631 std::getline(std::cin
,inputStr
);
632 scanner
.add(inputStr
);
633 std::cout
<< "SUCCESS!" << std::endl
;
635 } else if(inputStr
== "/rm"){
636 inputStr
= scanner
.getWord();
637 scanner
.remove(inputStr
);
638 std::cout
<< "SUCCESS!" << std::endl
;
640 } else if(inputStr
== "/stop") {
643 result
= ( inputStr
== scanner
.getWord() ? true : false );
644 std::cout
<< "*Answer: " << dictionary
.word();
645 if( !dictionary
.phonetics().empty() )
646 std::cout
<< " /" << dictionary
.phonetics() << "/";
647 std::cout
<< std::endl
;
648 std::cout
<<"**********************************************" << std::endl
;
650 scanner
.test(result
);
651 } else { //If the dictionary can't look up the current word
652 std::cout
<< '\"' << scanner
.getWord() << '\"'
653 << " can't be found in your dictionary."
654 << "\n Modify Or Remove it from task(M/r) ";
656 std::getline(std::cin
,m_r
);
657 if(m_r
== "R" || m_r
== "r") {
658 inputStr
= scanner
.getWord();
659 scanner
.remove(inputStr
);
660 std::cout
<< "SUCCESS!" << std::endl
;
662 modify(scanner
.getWord());
668 void CUI::scanProHelp() {
669 std::cout
<< std::endl
<< "usage: /command " << std::endl
670 << "/help Show this help information" << std::endl
671 << "/add Add new word to this task" << std::endl
672 << "/rm Remove the current word from this task" << std::endl
673 << "/modify Modify the current word in the dictionary"
675 << "/hint Get the hint of current word, but the translation can't use"
677 << "/stop Stop Free Recite at once" << std::endl
;
681 std::cout
<< "usage: frt [--version] [--help] COMMAND [ARGS]" << std::endl
682 << "The most commonly used git commands are:" << std::endl
683 << " all Show the detail of all the tasks"
685 << " cls Clean the stress words"
687 << " done Export the remembered words"
689 << " export <ID|file> Export words in the task(file)"
691 << " ls List the tasks that should be reviewed"
693 << " new <file> Creat new tasks with the words in the file"
695 << " merge <file> Merge the dictionary into the file"
697 << " modify [word] Modify the word in the dictionary"
699 << " recite <ID|file> Recite the words in the task(file)"
701 << " rrecite <ID|file> Recite from the translationg to word"
703 << " remove <taskID> Remove a task"
705 << " stress Show the stress words"
707 << " status Show how many words you are reciting"
709 << " test <ID|file> Test the words in the task(file)"
711 << " rtest <ID|file> Test from translation to word"
713 << " --help Show this help information"
715 << " --version Show the current version"
719 } // namespace freeRecite End.