update dict
[QFreeRecite.git] / src / core / Manager.cpp
blobbaa6435980e5970810296f03a779b5d3792ec744
1 #include <fstream>
2 #include <sstream>
3 #include <set>
4 #include <map>
5 #include <ctime>
6 #include <cstdlib>
7 #include <cstring>
8 #include <cstdio>
10 #include "Debug.h"
11 #include "ConfigHolder.h"
12 #include "Dict.h"
13 #include "Manager.h"
14 #include "ForgetCurve.h"
15 #include "Scanner.h"
16 #include "Task.h"
18 namespace freeRecite {
20 bool Manager::load() {
21 firstReviewTime = 0;
22 allTasks.clear();
23 activeID.clear();
24 maxTaskID = 0;
25 validFlag = false;
26 std::ifstream ifs(configHolder.mgrFile().c_str());
27 if(!ifs.is_open())
28 return false;
29 Task tmpTask;
30 unsigned amount;
31 ifs >> amount;
32 ifs.ignore(1,',');
33 ifs >> maxTaskID;
34 ifs.ignore(1,'\n');
35 bool firstFlag = true;
36 while(amount > 0 && ifs.good()) {
37 ifs >> tmpTask;
38 allTasks[tmpTask.getID()] = tmpTask;
40 if(tmpTask.shouldReview())
41 activeID.push_back(tmpTask.getID());
42 else if(firstFlag){
43 firstReviewTime = tmpTask.getReviewTime();
44 firstFlag = false;
45 }else if(firstReviewTime > tmpTask.getReviewTime())
46 firstReviewTime = tmpTask.getReviewTime();
47 --amount;
50 if(!activeID.empty())
51 firstReviewTime = 0;
52 validFlag = true;
53 return true;
56 bool Manager::save() {
57 std::ofstream ofs(configHolder.mgrFile().c_str());
58 if(!ofs.is_open())
59 return false;
60 ofs << static_cast<unsigned>(allTasks.size())
61 << ',' << maxTaskID << '\n';
62 std::map<time_t,Task>::const_iterator itr = allTasks.begin();
63 while(itr != allTasks.end()){
64 if(!ofs.good())
65 return false;
66 else {
67 if((itr->second).isAvailable())
68 ofs << itr->second;
69 ++itr;
72 return true;
75 bool Manager::refresh() {
76 if(save()) {
77 activeID.clear();
78 allTasks.clear();
79 return load();
80 }else
81 return false;
84 bool Manager::hasTask(time_t taskID) {
85 if(allTasks.find(taskID) == allTasks.end())
86 return false;
87 else
88 return true;
91 int Manager::currNumWords() {
92 std::ifstream ifs;
93 std::set<std::string> allWords;
94 std::string tmpWord;
95 std::map<time_t,Task>::const_iterator itr = allTasks.begin();
96 while(itr != allTasks.end()) {
97 ifs.open(Scanner::getTaskFileName(itr->first).c_str());
98 if(!ifs.is_open())
99 return -1;
101 while(std::getline(ifs,tmpWord)) {
102 if(!tmpWord.empty()) {
103 allWords.insert(tmpWord);
106 ifs.close();
107 ++itr;
109 return static_cast<int>(allWords.size());
112 int Manager::doneNumWords() {
113 std::ifstream ifs;
114 std::set<std::string> allWords;
115 std::string tmpWord;
116 ifs.open(configHolder.doneFile().c_str());
117 if(!ifs.is_open())
118 return 0;
119 while(std::getline(ifs,tmpWord)) {
120 if(!tmpWord.empty()) {
121 allWords.insert(tmpWord);
124 return static_cast<int>(allWords.size());
127 bool Manager::createTask(const std::set<std::string> &words,
128 const char *taskName, unsigned maxLimit) {
129 if(words.size()==0)
130 return false;
131 unsigned tasksNum = words.size()/maxLimit + 1;
132 maxLimit = words.size()/tasksNum;
133 std::string baseName;
134 std::string realName;
135 std::ofstream desFile;
136 std::ostringstream os;
138 time_t curTime;
139 struct tm * timeinfo;
140 char buffer[20];
141 std::set<std::string>::const_iterator itr = words.begin();
142 time(&curTime);
144 if(taskName != 0)
145 baseName = taskName;
147 if(baseName.empty()){
148 timeinfo = localtime(&curTime);
149 strftime(buffer,20,"%Y%m%d%H%M%S",timeinfo);
150 baseName = buffer;
153 for (unsigned i = 1; i <= tasksNum; ++i) { //[0]
154 memset(buffer,0,20);
155 os.str("");
156 os << "_" << i;
158 if(tasksNum > 1)
159 realName = baseName + os.str();
160 else
161 realName = baseName;
162 if(curTime > maxTaskID)
163 maxTaskID = curTime;
164 else
165 ++maxTaskID;
166 desFile.open(Scanner::getTaskFileName(maxTaskID).c_str());
167 D_OUTPUT(Scanner::getTaskFileName(maxTaskID).c_str())
168 if(!desFile.is_open())
169 return false;
171 //Write words into file.
172 unsigned j = 0;
173 while(j++ < maxLimit && itr != words.end()) {
174 if(!desFile.good())
175 return false;
176 if(itr->empty()) {
177 ++itr;
178 continue;
179 }else {
180 if(dictionary.lookUp(*itr))
181 desFile << *itr << std::endl;
182 else {
183 std::string str = *itr;
184 //Convert the word to lower
185 for(int i = 0; i < str.size(); ++i)
186 if(isupper(str[i]))
187 str[i] = tolower(str[i]);
188 if(dictionary.lookUp(str))
189 desFile << str << std::endl;
190 else
191 desFile << *itr << std::endl;
193 ++itr;
197 Task newTask(maxTaskID,realName.c_str());
198 //Pass a copy of newTask here.
199 allTasks[newTask.getID()] = newTask;
200 activeID.push_back(newTask.getID());
201 desFile.close();
202 } //[!0]
203 refresh();
204 return true;
207 void Manager::removeTask(time_t taskID) {
208 allTasks.erase(allTasks.find(taskID));
209 if(save()) {
210 ::remove(Scanner::getTaskFileName(taskID).c_str());
212 refresh();
215 const std::vector<time_t> &Manager::getActiveTasks() const{
216 return activeID;
219 const std::map<time_t,Task> &Manager::getAllTasks() const{
220 return allTasks;
224 //Get the number of the active tasks.
225 int Manager::getActiveTaskNum() const {
226 return activeID.size();
229 //Get the task's name.
230 const std::string &Manager::getTaskName(time_t taskID)const {
231 return (allTasks.find(taskID)->second).getName();
235 time_t Manager::getNextTime(time_t taskID) const {
236 return (allTasks.find(taskID)->second).getReviewTime();
239 //Get the step of the task.
240 int Manager::getTaskStep(time_t taskID)const {
241 return (allTasks.find(taskID)->second).getStep();
244 int Manager::test(const time_t &taskID, const int &mark){
245 int result = (allTasks[taskID]).test(mark);
246 refresh();
247 if(result != 1) //If user haven't complish the task,return directly.
248 return result;
250 // This task have been complished, add the words to done.txt and
251 // delete this task in manager.
252 std::ifstream ifs(Scanner::getTaskFileName(taskID).c_str());
253 if(!ifs.is_open())
254 return result;
255 std::set<std::string> doneWords;
256 std::string word;
257 while(ifs.good()) {
258 std::getline(ifs,word);
259 if(!word.empty())
260 doneWords.insert(word);
262 ifs.close();
263 ifs.open(configHolder.doneFile().c_str());
264 if(ifs.is_open()) {
265 while(ifs.good()) {
266 std::getline(ifs,word);
267 if(!word.empty())
268 doneWords.insert(word);
270 ifs.close();
272 std::ofstream ofs(configHolder.doneFile().c_str());
273 if(!ofs.is_open())
274 return result;
275 std::set<std::string>::const_iterator itr = doneWords.begin();
276 while(ofs.good() && itr != doneWords.end())
277 ofs << *itr++ << '\n';
278 removeTask(taskID);
279 return result;
282 //This is a global variable.
283 Manager manager;
285 } //namespace freeRecite end