boinctui-2.5.0/src/ 0000755 0001750 0001750 00000000000 13124150563 011755 5 ustar ss ss boinctui-2.5.0/src/tui-main.cpp 0000644 0001750 0001750 00000004201 13124150563 014201 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#if HAVE_LIBNCURSESW == 1 && NCURSESW_HAVE_SUBDIR == 1
#include
#else
#include
#endif
#include
#include "kclog.h"
#include "mainprog.h"
std::string locale;
void initcurses()
{
locale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");
setlocale(LC_MESSAGES, "");
initscr();
noecho();
curs_set(0);
keypad(stdscr,true); //разрешаем стрелки и т.п.
#ifdef ENABLEMOUSE
mousemask(ALL_MOUSE_EVENTS, NULL); // Report all mouse events
#endif
timeout(100); //ожидание для getch() 100 милисекунд
start_color();
}
void donecurses()
{
clear();
refresh();
endwin();
setlocale(LC_ALL, locale.c_str());
}
int main(int argc, char ** argv)
{
MainProg* mainprog;
kLogOpen("boinctui.log");
initcurses();
#ifdef DEBUG
struct mallinfo minf1 = mallinfo();
#endif
mainprog = new MainProg();
mainprog->refresh();
mainprog->mainloop(); //запускаем осн. цикл событий
delete mainprog;
#ifdef DEBUG
struct mallinfo minf2 = mallinfo();
kLogPrintf("mallinfo.uordblks= %d-%d = %d (bytes leak)\n",minf1.uordblks,minf2.uordblks, minf2.uordblks-minf1.uordblks);
//malloc_stats();
#endif
donecurses();
kLogClose();
exit(EXIT_SUCCESS);
}
boinctui-2.5.0/src/statwin.h 0000644 0001750 0001750 00000005503 13124150563 013622 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef STATWIN_H
#define STATWIN_H
#include
#include
#include "ngroup.h"
#include "nscrollview.h"
#include "tuievent.h"
#include "nscrollbar.h"
struct DayStat //статистика за один день проекта
{
time_t day; //день
unsigned long int scorehost;
unsigned long int scoreuser;
};
struct ProjStat
{
std::string name; //имя проекта
std::list days; //дни
static bool CmpAboveH( ProjStat stat1, ProjStat stat2 ) //для сортировки проектов true если ...
{
std::list::iterator it;
double stat1sum = 0;
double stat2sum = 0;
for (it = stat1.days.begin(); it != stat1.days.end(); it++)
stat1sum += (*it).scorehost;
for (it = stat2.days.begin(); it != stat2.days.end(); it++)
stat2sum += (*it).scorehost;
return stat1sum > stat2sum;
};
static bool CmpAboveU( ProjStat stat1, ProjStat stat2 ) //для сортировки проектов true если ...
{
std::list::iterator it;
double stat1sum = 0;
double stat2sum = 0;
for (it = stat1.days.begin(); it != stat1.days.end(); it++)
stat1sum += (*it).scoreuser;
for (it = stat2.days.begin(); it != stat2.days.end(); it++)
stat2sum += (*it).scoreuser;
return stat1sum > stat2sum;
};
};
class StatWin : public NGroup //окно общей стстистики
{
public:
StatWin(Srv* srv);
void eventhandle(NEvent* ev); //обработчик событий
void updatedata();
private:
int hpos; //индекс первого отображаемого проекта (для гориз скроллинга)
bool hostmode; //true - статистика для хоста (дефолт) false-для юзера
std::vector > ssbak; //прошлое значение
std::string caption;
Srv* srv;
NScrollView* content;
NScrollBar* scrollbar;
std::vector projects; //матрица статистики
void updatecaption();
};
#endif //STATWIN_H boinctui-2.5.0/src/addmgrform.h 0000644 0001750 0001750 00000002771 13124150563 014257 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef ADDMGRFORM_H
#define ADDMGRFORM_H
#include
#include
#include "nform.h"
#include "nstatictext.h"
#include "srvdata.h"
class AddAccMgrForm : public NForm
{
public:
AddAccMgrForm(int lines, int rows, Srv* srv, const char* mgrname);
void genfields(int& line, Item* mgr); //создаст массив полей
virtual void eventhandle(NEvent* ev); //обработчик событий
protected:
int namefield;
int passwfield;
int errmsgfield;
int usernamefield;
int urlfield;
Srv* srv;
std::string mgrname; //имя акк менеджера
std::string mgrurl; //url подключаемого менеджера
};
#endif //ADDMGRFORM_H boinctui-2.5.0/src/cfg.cpp 0000644 0001750 0001750 00000011375 12742135224 013231 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include
#include
#include
#include "cfg.h"
#include "resultparse.h"
#include "kclog.h"
Config* gCfg;
Config::Config(const char* filename)
{
root = NULL;
//полный путь к конфигу
if (filename == NULL)
fullname = NULL;
else
{
//хоум каталог
const char* homepath = getenv("HOME");
//полный путь
fullname = (char*)malloc(strlen(homepath)+strlen(filename)+2);
sprintf(fullname,"%s/%s",homepath,filename);
kLogPrintf("FULLCFGPATH=%s\n",fullname); fflush(stdout);
}
//загружаем если файл уже есть или генерируем дефолтный
load();
asciilinedraw = getivalue("line_draw_mode");
}
Config::~Config()
{
save();
if (root != NULL)
delete root;
if (fullname == NULL)
free(fullname);
}
void Config::load()
{
isdefault = true;
if (fullname == NULL)
{
generatedefault();
return;
}
struct stat st;
int retcode = lstat(fullname, &st);
if (retcode != 0) //файла нет?
{
//делаем дефолтный
generatedefault();
return;
}
//читаем файл
FILE* pfile;
pfile = fopen(fullname,"r");
if (pfile!=NULL)
{
kLogPrintf("SIZE=%ld\n",st.st_size);
char* buf = (char*)malloc(st.st_size + 1);
size_t n = fread (buf,1,st.st_size,pfile);
buf[n]=0;
kLogPrintf("%s\n",buf);
root = xmlparse(buf, st.st_size, errmsg);
if (!errmsg.empty())
errmsg = fullname + std::string("\n") + errmsg;
fclose (pfile);
isdefault = false;
}
}
void Config::save()
{
if (!errmsg.empty())
return; //если была ошибка при загрузке то файл не перезаписываем
if (fullname == NULL)
return;
if (root == NULL)
return;
kLogPrintf("Save Config to FULLCFGPATH=%s\n",fullname);
Item* cfg = root->findItem("boinctui_cfg");
if (cfg == NULL)
return;
std::string configxml = cfg->toxmlstring();
kLogPrintf("\n%s\n",cfg->toxmlstring().c_str());
FILE* pfile = fopen(fullname,"w");
if (pfile!=NULL)
{
fwrite(cfg->toxmlstring().c_str(),1, strlen(cfg->toxmlstring().c_str()),pfile);
fclose (pfile);
}
}
void Config::addhost(const char* shost, const char* sport, const char* spwd)
{
if ( (strlen(shost) == 0)||(strlen(sport) == 0) )
return; //пустые не заносим
Item* boinctui_cfg = getcfgptr();
if (boinctui_cfg == NULL)
return;
Item* srv = new Item("server");
Item* host = new Item("host");
host->appendvalue(shost);
srv->addsubitem(host);
Item* port = new Item("port");
port->appendvalue(sport);
srv->addsubitem(port);
if (strlen(spwd) > 0)
{
Item* pwd = new Item("pwd");
pwd->appendvalue(spwd);
srv->addsubitem(pwd);
}
boinctui_cfg->addsubitem(srv);
}
void Config::generatedefault()
{
kLogPrintf("generatedafault()\n");
root = new Item(""); //корневой
Item* cfg = new Item("boinctui_cfg");
root->addsubitem(cfg);
addhost("127.0.0.1","31416","");
}
int Config::getivalue(Item* node, const char* name) //ищет name начиная с node
{
int result = 0;
if (node != NULL)
{
Item* item = node->findItem(name);
if (item != NULL)
result = item->getivalue();
}
return result;
}
void Config::setivalue(Item* node, const char* name, int value) //создаст в node подэл-т name со значением value
{
Item* basenode = node;
if (basenode == NULL)
basenode = root; //если узел не указан используем корневой
if (basenode == NULL)
return; //ничего не делаем
Item* item = basenode->findItem(name);
//эл-та нет - нужно создать
if (item == NULL)
{
item = new Item(name);
basenode->addsubitem(item);
}
//устнавливаем значение
item->setivalue(value);
}
boinctui-2.5.0/src/srvdata.cpp 0000644 0001750 0001750 00000073244 13001203735 014131 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include
#include
#ifdef HAVE_OPENSSL
#include
#else
#include
#endif
#include
#include "srvdata.h"
#include "resultparse.h"
#include "kclog.h"
#define STATE_TIME_INTERVAL 2 //интервал в секундах между запросами
#define MSG_TIME_INTERVAL 2 //интервал в секундах между запросами
#define DISKUSAGE_TIME_INTERVAL 60 //интервал в секундах между запросами
#define STATISTICS_TIME_INTERVAL 300 //интервал в секундах между запросами
#define CCSTATUS_TIME_INTERVAL 600 //интервал в секундах между запросами
const int ERR_IN_PROGRESS = -204;
const int BOINC_SUCCESS = 0;
//=============================================================================================
PtrList::~PtrList()
{
kLogPrintf("PtrList::~PtrList() list.size()=%d\n",list.size());
while(!list.empty())
{
delete list.front();
list.erase(list.begin());
}
pthread_mutex_destroy(&mutex);
}
Item* PtrList::hookptr() //получить указатель из хвоста списка
{
Item* result = NULL;
pthread_mutex_lock(&mutex);
if (!list.empty())
{
list.back()->refcount++;
result = list.back()->dom;
}
pthread_mutex_unlock(&mutex);
return result;
}
void PtrList::releaseptr(Item* ptr) //сообщить списку что указатель больше не нужен (список сам решит нужно ли его удалять)
{
std::list::iterator it;
pthread_mutex_lock(&mutex);
//ищем элемент связанный с ptr
for( it = list.begin(); it != list.end(); it++)
{
if ( (*it)->dom == ptr) //нашли
{
(*it)->refcount--; //уменьшаем счетчик ссылок
}
}
//очищаем старые ненужные эл-ты
bool done;
do
{
done = true;
for( it = list.begin(); it != list.end(); it++)
{
if ( ((*it) != list.back()) && ((*it)->refcount <= 0) ) //нашли (последний не трогаем)
{
delete (*it)->dom;
delete (*it);
list.erase(it);
done = false;
break;
}
}
}
while (!done);
pthread_mutex_unlock(&mutex);
}
//=============================================================================================
bool daily_statisticsCmpAbove( Item* stat1, Item* stat2 ) //для сортировки статистики true если дата stat1 > stat2
{
Item* day1 = stat1->findItem("day");
Item* day2 = stat2->findItem("day");
if ( (day1 != NULL)&&(day2 != NULL) )
{
if (day1->getdvalue() > day2->getdvalue())
return true;
else
return false;
}
return false;
}
//=============================================================================================
SrvList::SrvList(/*Config* cfg*/)
{
// this->cfg = cfg;
refreshcfg();
}
SrvList::~SrvList()
{
kLogPrintf("SrvList::~SrvList() servers.size()=%d\n",servers.size());
clear();
}
void SrvList::refreshcfg() //перечитать из конфига
{
clear(); //удаляем старые сервера (если есть)
Item* boinctui_cfg = gCfg->getcfgptr();
if (boinctui_cfg == NULL)
return;
std::vector- slist = boinctui_cfg->getItems("server");
std::vector
- ::iterator it;
for (it = slist.begin(); it != slist.end(); it++)
{
Item* host = (*it)->findItem("host");
Item* port = (*it)->findItem("port");
Item* pwd = (*it)->findItem("pwd");
if ((host != NULL)&&(port != NULL))
{
if (pwd == NULL)
servers.push_back(new Srv(host->getsvalue(), port->getsvalue(), ""));
else
servers.push_back(new Srv(host->getsvalue(), port->getsvalue(), pwd->getsvalue()));
}
}
if (!servers.empty())
{
cursrv = servers.begin();
(*cursrv)->setactive(true);
}
}
void SrvList::clear() //удалить все соединения
{
kLogPrintf("SrvList::clear()\n");
std::list::iterator it;
cursrv = servers.begin();
for (it = servers.begin(); it != servers.end(); it++) //чистим все соединения
{
kLogPrintf("+delete server\n");
delete (*it);
kLogPrintf("-server deleted success\n");
}
servers.clear();
}
void SrvList::nextserver() //переключиться на след сервер в списке
{
(*cursrv)->setactive(false); //деактивируем тред
cursrv++;
if (cursrv == servers.end()) //дошли до конца переходим в начало списка
cursrv = servers.begin();
(*cursrv)->setactive(true); //активиркем тред
}
//=============================================================================================
Srv::Srv(const char* shost, const char* sport, const char* pwd) : TConnect(shost, sport)
{
allprojectsdom = NULL;
this->pwd = strdup(pwd);
lastmsgno = 0;
active = false;
loginfail = false;
ccstatusdomneedupdate = false;
pthread_mutex_init(&mutex, NULL);
}
Srv::~Srv()
{
kLogPrintf("+Srv::~Srv() host=%s:%s\n",shost,sport);
if (isactive())
{
setactive(false); //завершаем опросный тред (если он есть)
kLogPrintf("waiting stop...\n");
pthread_join(thread, NULL); //ждем пока тред остановится
}
if (allprojectsdom != NULL) delete allprojectsdom;
if (pwd != NULL) delete pwd;
pthread_mutex_destroy(&mutex);
kLogPrintf("-Srv::~Srv()\n");
}
Item* Srv::req(const char* fmt, ...) //выполнить запрос (вернет дерево или NULL)
{
if (hsock == -1)
createconnect();
if (hsock == -1)
return NULL;
// === посылаем запрос ===
char req[1024];
strcpy(req, "\n");
strcat(req, fmt);
strcat(req, "\n\n\003");
va_list args;
lock();
va_start(args, fmt);
sendreq(req, args);
va_end(args);
char* result = waitresult();
unlock();
if (result != NULL) //получен ответ
{
// === отрезаем теги
const char* teg1 = "";
const char* teg2 = "";
char* b = strstr(result,teg1);
char* e = strstr(result,teg2);
if (( b == NULL)||( e == NULL))
{
free(result);
return NULL;
}
*e = '\0';
b = b + strlen(teg1);
while ( (*b != '\0')&&(*b != '<') )
b++; //отрезаем лидирующие переводы строки и т.д.
// === костыль ТОЛЬКО для
if (strstr(fmt, "") != NULL)
b = (char*)stripinvalidtag(b, strlen(b)); //убираем кривые теги
// === разбираем ответ ===
lock();
std::string errmsg;
Item* dom = xmlparse(b, strlen(b), errmsg); //парсим xml
unlock();
free(result); //рез-т в тесктовом виде больше не нужен
return dom;
}
else
return NULL;
}
void Srv::createconnect()
{
lock();
TConnect::createconnect();
unlock();
loginfail = false;
if (hsock != -1)
loginfail = login();
}
bool Srv::login() //авторизоваться на сервере
{
bool result = false;
// if (strlen(pwd) == 0)
// return true; //пароль не задан (считаем что логин серверу не требуется)
//получить случайную строку (nonce)
Item* r1 = req("");
if (r1 == NULL)
return result;
kLogPrintf("login() nonce='%s'\n", r1->toxmlstring().c_str());
Item* nonce = r1->findItem("nonce");
if ( nonce == NULL )
{
delete r1;
return result;
}
const char* snonce = r1->findItem("nonce")->getsvalue();
//расчитать хэш md5 от nonce+pwd
unsigned char md5digest[MD5_DIGEST_LENGTH];
MD5_CTX c;
MD5_Init(&c);
MD5_Update(&c, snonce, strlen(snonce));
MD5_Update(&c, pwd , strlen(pwd));
MD5_Final(md5digest,&c);
char shash[1024]; //строковое представление хэша
for (int i=0;i\n%s\n",shash);
kLogPrintf("login() Boinc answer ---\n%s\n", r2->toxmlstring().c_str());
if ( r2->findItem("unauthorized") != NULL ) //авторизация неуспешна
result = true;
delete r2;
return result;
}
void Srv::updatestatistics()
{
statisticsdom.addptr(req(""));
}
void Srv::updateccstatus() //обновить состояние
{
ccstatusdom.addptr(req(""));
}
void Srv::updatediskusage()
{
dusagedom.addptr(req(""));
}
void Srv::updatestate()
{
statedom.addptr(req(""));
}
void Srv::updatemsgs() //обновить сообщения
{
Item* domtree1 = req("");
if (domtree1 == NULL)
return;
Item* seqno = domtree1->findItem("seqno");
if (seqno == NULL)
{
delete domtree1;
return;
}
int curseqno = seqno->getivalue(); //кол-во сообщений на сервере в тек. момент
delete domtree1;
if (curseqno == lastmsgno) //если с прошлого вызова updatedata() новых сообщений нет, то просто выходим
return;
// === запрашиваем содержимое сообщений начиная с lastmsg сервере ===
char req2[256];
int msgno; //номер первого запрашиваемого сообщения
if (lastmsgno>0)
msgno = lastmsgno; //запрашиваем начиная с последнего отображенного
else
msgno = 0; //начинаем с первого
snprintf(req2,sizeof(req2),"\n%d\n",msgno);
Item* domtree = req(req2);
if (domtree == NULL)
return;
// === дополняем массив визуальных строк ===
if (!msgdom.empty()) //если есть ранее полученные сообщения
{
Item* tmpmsgdom = msgdom.hookptr();
//объединяем ветку "msgs" новых сообщений с основным деревом (msgdom)
msgdom.lock();
(tmpmsgdom->findItem("msgs"))->mergetree(domtree->findItem("msgs"));
msgdom.unlock();
delete domtree; //очищаем рез-т
msgdom.releaseptr(tmpmsgdom);
}
else
msgdom.addptr(domtree);
lastmsgno = curseqno;
}
void Srv::updateallprojects()
{
if (allprojectsdom != NULL)
delete allprojectsdom; //очищаем предыдущий рез-т
allprojectsdom = req("");
}
void Srv::updateacctmgrinfo()//обновить статистику
{
acctmgrinfodom.addptr(req(""));
}
void Srv::opactivity(const char* op) //изменение режима активности BOINC сервера "always" "auto" "newer"
{
Item* d = req("<%s/>0",op);
if (d != NULL)
delete d;
ccstatusdomneedupdate = true;
}
void Srv::opnetactivity(const char* op) //изменение режима активности сети "always" "auto" "newer"
{
Item* d = req("<%s/>0",op);
if (d != NULL)
delete d;
ccstatusdomneedupdate = true;
}
void Srv::opgpuactivity(const char* op) //изменение режима активности GPU "always" "auto" "newer"
{
Item* d = req("<%s/>0",op);
if (d != NULL)
delete d;
ccstatusdomneedupdate = true;
}
void Srv::optask(const char* url, const char* name, const char* op) //действия над задачей ("suspend_result",...)
{
Item* d = req("<%s>\n%s\n%s\n%s>",op,url,name,op);
if (d != NULL)
delete d;
}
void Srv::opproject(const char* name, const char* op) //действия над проектом ("project_suspend","project_resume",...)
{
if (statedom.empty())
return;
Item* tmpdom = statedom.hookptr();
std::string url = findProjectUrl(tmpdom,name);
Item* d = req("<%s>\n%s\n%s>",op,url.c_str(),op);
statedom.releaseptr(tmpdom);
if (d != NULL)
delete d;
}
void Srv::runbenchmarks() //запустить бенчмарк
{
Item* d = req("");
if (d != NULL)
delete d;
}
bool Srv::getprojectconfig(const char* url, std::string& errmsg) //получить c сервера файл конфигурации
{
//запрос на начало передачи
Item* res = req("\n%s\n", url);
if (res == NULL)
return false;
kLogPrintf("request=\n ?\n\n answer=\n%s\n", res->toxmlstring().c_str());
free(res);
//ждем завершения
bool done = false;
int count = 30; //не больше 30 запросов
do
{
res = req("");
if (res == NULL)
return false;
kLogPrintf("request=\n ?\n\n answer=\n%s\n", res->toxmlstring().c_str());
Item* error_num = res->findItem("error_num");
if (error_num != NULL)
{
int errnum = error_num->getivalue();
if (errnum == ERR_IN_PROGRESS) //ждать?
sleep(1); //ERR_IN_PROGRESS ждем 1 сек
else
{
free(res);
break;
}
}
else
{
Item* project_config = res->findItem("project_config");
if (project_config != NULL)
done = true;
else
{
free(res);
break;
}
}
free(res);
}
while((count--)&&(!done));
return done;
}
bool Srv::createaccount(const char* url, const char* email, const char* pass, const char* username, const char* teamname, std::string& errmsg) //создать аккаунт
{
kLogPrintf("createaccount(url=%s, email=%s, pass=%s, username=%s, teamname=%s)\n", url, email, pass, username, teamname);
//расчитать хэш md5 от pass+email
unsigned char md5digest[MD5_DIGEST_LENGTH];
MD5_CTX c;
MD5_Init(&c);
MD5_Update(&c, pass , strlen(pass));
MD5_Update(&c, email, strlen(email));
MD5_Final(md5digest,&c);
char shash[1024]; //строковое представление хэша
for (int i=0;i\n"
" %s\n"
" %s\n"
" %s\n"
" %s\n"
" %s\n"
"\n",
url,email,shash,username,teamname);
Item* res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
free(res);
//ждем завершения
int count = 30; //не больше 30 запросов
snprintf(sreq,sizeof(sreq),"");
bool done = false;
do
{
res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
Item* error_num = res->findItem("error_num");
if ((error_num != NULL)&&(error_num->getivalue() != ERR_IN_PROGRESS))
{
Item* error_msg = res->findItem("error_msg");
if (error_msg != NULL)
errmsg = error_msg->getsvalue(); //возврат строки ошибки
return false;
}
if (res->findItem("authenticator") != NULL)
done = true;
free(res);
sleep(1); //ждем 1 сек
}
while((count--)&&(!done));
return true;
}
bool Srv::projectattach(const char* url, const char* prjname, const char* email, const char* pass, std::string& errmsg) //подключить проект
{
//расчитать хэш md5 от pass+email
unsigned char md5digest[MD5_DIGEST_LENGTH];
MD5_CTX c;
MD5_Init(&c);
MD5_Update(&c, pass , strlen(pass));
MD5_Update(&c, email, strlen(email));
MD5_Final(md5digest,&c);
char shash[1024]; //строковое представление хэша
for (int i=0;i\n%s\n%s\n%s\n\n",url,email,shash);
Item* res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
free(res);
int count = 30; //не больше 30 запросов
snprintf(sreq,sizeof(sreq),"");
std::string sauthenticator;
bool done = false;
do
{
res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
Item* error_num = res->findItem("error_num");
if ((error_num != NULL)&&(error_num->getivalue() != ERR_IN_PROGRESS))
{
Item* error_msg = res->findItem("error_msg");
if (error_msg != NULL)
errmsg = error_msg->getsvalue(); //возврат строки ошибки
return false;
}
Item* authenticator = res->findItem("authenticator");
if (authenticator != NULL)
{
sauthenticator = authenticator->getsvalue();
done = true;
}
free(res);
sleep(1); //ждем 1 сек
}
while((count--)&&(!done));
if (!done)
return false;
//формируем запрос для подключения к проекту
snprintf(sreq,sizeof(sreq),"\n%s\n%s\n%s\n\n",url,sauthenticator.c_str(),prjname);
res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
bool result = (res->findItem("success") != NULL);
free(res);
return result;
}
bool Srv::accountmanager(const char* url, const char* username, const char* pass, bool useconfigfile, std::string& errmsg) //подключить аккаунт менеджер
{
if (strlen(url) > 0)
{
//получить конфиг (не знаю зачем!!!)
if (!getprojectconfig(url,errmsg))
{
errmsg = "Can't get config";
return false;
}
}
char sreq[1024];
//формируем запрос
if (useconfigfile)
snprintf(sreq,sizeof(sreq),"\n\n\n");
else
snprintf(sreq,sizeof(sreq),"\n%s\n%s\n%s\n\n",url,username,pass);
Item* res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
//ждем завершения
snprintf(sreq,sizeof(sreq),"");
bool done = false;
int count = 30; //не больше 30 запросов
do
{
res = req(sreq);
if (res == NULL)
return false;
kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str());
Item* error_num = res->findItem("error_num");
if (error_num != NULL)
{
int errnum = error_num->getivalue();
if (errnum == BOINC_SUCCESS) //успешно
done = true;
else
if (errnum != ERR_IN_PROGRESS) //ошибка выходим
{
Item* message = res->findItem("message");
if (message != NULL)
errmsg = message->getsvalue(); //возврат строки ошибки
free(res);
return false;
}
else
sleep(1); //ERR_IN_PROGRESS ждем 1 сек
}
free(res);
}
while((count--)&&(!done));
acctmgrinfodom.needupdate = true; //чтобы тред обновил данные
sleep(1); //даем треду 1 сек на обновление
kLogPrintf("RET %b\n",done);
return done;
}
std::string Srv::findProjectName(Item* tree, const char* url) //найти в дереве tree имя проекта с заданным url
{
Item* client_state = tree->findItem("client_state");
if (client_state == NULL)
return "ERR2";
std::vector
- projects = client_state->getItems("project"); //список проектов
std::vector
- ::iterator it;
for (it = projects.begin(); it!=projects.end(); it++)
{
Item* master_url = (*it)->findItem("master_url");
if ( strcmp(url,master_url->getsvalue()) == 0 ) //url совпали НАШЛИ!
{
Item* project_name = (*it)->findItem("project_name");
return project_name->getsvalue();
}
}
return "???";
}
std::string Srv::findProjectUrl(Item* tree, const char* name) //найти в дереве tree url проекта с заданным именем
{
Item* client_state = tree->findItem("client_state");
if (client_state == NULL)
return "ERR2";
std::vector
- projects = client_state->getItems("project"); //список проектов
std::vector
- ::iterator it;
for (it = projects.begin(); it!=projects.end(); it++)
{
Item* project_name = (*it)->findItem("project_name");
if ( strcmp(name, project_name->getsvalue()) == 0 ) //имена совпали НАШЛИ!
{
Item* master_url = (*it)->findItem("master_url");
return master_url->getsvalue();
}
}
return "";
}
Item* Srv::findresultbyname(const char* resultname)
{
if (statedom.empty())
return NULL;
if (resultname == NULL)
return NULL;
Item* tmpstatedom = statedom.hookptr();
Item* client_state = tmpstatedom->findItem("client_state");
if (client_state == NULL)
{
statedom.releaseptr(tmpstatedom);
return NULL;
}
std::vector
- results = client_state->getItems("result"); //список задач
std::vector
- ::iterator it;
for (it = results.begin(); it!=results.end(); it++)
{
Item* name = (*it)->findItem("name");
if ( strcmp(resultname,name->getsvalue()) == 0 ) //имена совпали НАШЛИ!
{
statedom.releaseptr(tmpstatedom);
return (*it);
}
}
statedom.releaseptr(tmpstatedom);
return NULL;
}
Item* Srv::findprojectbyname(const char* projectname)
{
if (statedom.empty())
return NULL;
if (projectname == NULL)
return NULL;
Item* tmpstatedom = statedom.hookptr();
Item* client_state = tmpstatedom->findItem("client_state");
if (client_state == NULL)
{
statedom.releaseptr(tmpstatedom);
return NULL;
}
std::vector
- projects = client_state->getItems("project"); //список проектов
std::vector
- ::iterator it;
for (it = projects.begin(); it!=projects.end(); it++)
{
Item* name = (*it)->findItem("project_name");
if ( strcmp(projectname,name->getsvalue()) == 0 ) //имена совпали НАШЛИ!
{
statedom.releaseptr(tmpstatedom);
return (*it);
}
}
statedom.releaseptr(tmpstatedom);
return NULL;
}
Item* Srv::findprojectbynamefromall(const char* projectname) //ищет в allprojectsdom
{
if (allprojectsdom == NULL)
return NULL;
if (projectname == NULL)
return NULL;
Item* projects = allprojectsdom->findItem("projects");
if (projects == NULL)
return NULL;
std::vector
- projectlist = projects->getItems("project"); //список проектов
std::vector
- ::iterator it;
for (it = projectlist.begin(); it!=projectlist.end(); it++)
{
Item* name = (*it)->findItem("name");
if ( strcmp(projectname,name->getsvalue()) == 0 ) //имена совпали НАШЛИ!
{
return (*it);
}
}
return NULL;
}
Item* Srv::findaccountmanager(const char* mgrname) //ищет менеджер по имени
{
if (allprojectsdom == NULL)
return NULL;
if (mgrname == NULL)
return NULL;
Item* projects = allprojectsdom->findItem("projects");
if (projects == NULL)
return NULL;
std::vector
- mgrlist = projects->getItems("account_manager"); //список менеджеров
std::vector
- ::iterator it;
for (it = mgrlist.begin(); it!=mgrlist.end(); it++)
{
Item* name = (*it)->findItem("name");
if ( strcmp(mgrname,name->getsvalue()) == 0 ) //имена совпали НАШЛИ!
{
return (*it);
}
}
return NULL;
}
Item* Srv::findappbywuname(const char* wuname) //найти приложение для данного WU
{
if (statedom.empty())
return NULL;
if (wuname == NULL)
return NULL;
Item* tmpstatedom = statedom.hookptr();
Item* client_state = tmpstatedom->findItem("client_state");
if (client_state == NULL)
{
statedom.releaseptr(tmpstatedom);
return NULL;
}
std::vector
- wulist = client_state->getItems("workunit"); //список WU
std::vector
- ::iterator it;
//ищем WU
for (it = wulist.begin(); it!=wulist.end(); it++)
{
Item* name = (*it)->findItem("name");
if ( strcmp(wuname,name->getsvalue()) == 0 ) //имена совпали НАШЛИ WU!
{
Item* app_name = (*it)->findItem("app_name");
std::vector
- applist = client_state->getItems("app"); //список APP
std::vector
- ::iterator it2;
for (it2 = applist.begin(); it2!=applist.end(); it2++)
{
Item* name = (*it2)->findItem("name");
if ( strcmp(app_name->getsvalue(),name->getsvalue()) == 0 ) //имена совпали НАШЛИ APP!
{
statedom.releaseptr(tmpstatedom);
return (*it2);
}
}
}
}
statedom.releaseptr(tmpstatedom);
return NULL;
}
time_t Srv::getlaststattime() //вернет время последней имеющейся статистики
{
time_t result = 0;
if (statisticsdom.empty())
return 0;
Item* tmpstatisticsdom = statisticsdom.hookptr();
Item* statistics = tmpstatisticsdom->findItem("statistics");
if (statistics!=NULL)
{
std::vector
- project_statistics = statistics->getItems("project_statistics");
std::vector
- ::iterator it;
for (it = project_statistics.begin(); it!=project_statistics.end(); it++) //цикл списка проектов
{
std::vector
- daily_statistics = (*it)->getItems("daily_statistics"); //все дни проекта в этом векторе
if (!daily_statistics.empty())
{
std::sort(daily_statistics.begin(), daily_statistics.end(), daily_statisticsCmpAbove); //сортируем по убыванию дат
Item* lastday = daily_statistics.front(); //последний день должен быть сверху
double d = lastday->findItem("day")->getdvalue();
if (d > result)
result = d;
}
} //проекты
}
statisticsdom.releaseptr(tmpstatisticsdom);
return result;
}
time_t Srv::gettimeelapsed(time_t t) //вернет соличество секунд между t и тек. временем
{
return (time(NULL) - t);
}
void* Srv::updatethread(void* args) //трейд опрашивающий сервер
{
Srv* me = (Srv*)args;
kLogPrintf("%s:%s::updatethread() started\n",me->gethost(),me->getport());
me->takt = 0;
while(me->active)
{
//get data from remote server
if ( me->statedom.empty() || ( (me->takt % STATE_TIME_INTERVAL) == 0 ) )
me->updatestate(); //
if (me->isconnected()&&(!me->loginfail)) //если нет коннекта то пропускаем прочие запросы
{
if ( me->msgdom.empty() || ( (me->takt % MSG_TIME_INTERVAL) == 0 ) )
me->updatemsgs(); ///
if ( me->statisticsdom.empty() || ( (me->takt % STATISTICS_TIME_INTERVAL) == 0 ) )
me->updatestatistics(); //
if ( me->dusagedom.empty() || ( (me->takt % DISKUSAGE_TIME_INTERVAL) == 0 ) )
me->updatediskusage(); //
if ( me->ccstatusdom.empty() || ( (me->takt % CCSTATUS_TIME_INTERVAL) == 0 ) || me->ccstatusdomneedupdate )
{
me->updateccstatus(); //
me->ccstatusdomneedupdate = false;
}
if (me->acctmgrinfodom.needupdate)
me->updateacctmgrinfo(); //ин-я по аккаунт менеджеру
}
//спим 1 секунду проверяя me->ccstatusdomneedupdate
for (int i = 0; i < 10; i++)
{
usleep(100000); //100 milisec
if (me->ccstatusdomneedupdate)
break; //прервать сон если нужен срочный апдейт
}
me->takt++;
}
kLogPrintf("%s:%s::updatethread() stopped\n",me->gethost(),me->getport());
return NULL;
}
void Srv::setactive(bool b) //включить/выключить тред обновления данных
{
if (isactive() != b)
{
if (b)
{
active = true;
if ( 0 != pthread_create(&thread, NULL, updatethread, this))
kLogPrintf("pthread_create() error\n");
}
else
{
active = false; //сигнализирует треду остановиться
}
}
}
boinctui-2.5.0/src/nmessagebox.cpp 0000644 0001750 0001750 00000013147 13001203473 014773 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include
#include
#include "kclog.h"
#include "nmessagebox.h"
// =============================================================================
NMButton::NMButton(const char* text, NEvent* pevent, ...) : NStaticText(NRect(3, 20, getmaxy(stdscr)/2-3/2,getmaxx(stdscr)/2-20/2))
{
appendstring(getcolorpair(COLOR_WHITE, COLOR_CYAN)," ");
appendstring(getcolorpair(COLOR_WHITE, COLOR_CYAN) | A_BOLD ,text);
appendstring(getcolorpair(COLOR_WHITE, COLOR_CYAN)," ");
this->pevent = pevent;
//размер кнопки
resize(1, mbstrlen(text) + 2);
//список клавиш на которые реагирует эта кнопка
va_list pk;
va_start(pk, pevent);
int ch = va_arg(pk, int);
while ( ch != 0)
{
keys.push_back((char)ch);
ch = va_arg(pk, int); //следующий ключ
}
va_end(pk);
}
void NMButton::eventhandle(NEvent* ev) //обработчик событий
{
NStaticText::eventhandle(ev); //предок
if ( ev->done )
return;
//одиночный или двойной клик
NMouseEvent* mevent = (NMouseEvent*)ev;
if (( ev->type == NEvent::evMOUSE ) && (mevent->cmdcode & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED)))
{
if (isinside(mevent->row, mevent->col))
{
ev->done = true;
NEvent* tmp = pevent;
pevent = NULL;
putevent(tmp); //активируем событие связанное с этой кнопкой
}
}
//клавиатура
if ( ev->type == NEvent::evKB )
{
if ( keys.end() != std::find(keys.begin(), keys.end(), ev->cmdcode) )
{
kLogPrintf("NMButton::eventhandle() got '%c' key\n", ev->cmdcode);
if (pevent)
{
ev->done = true;
NEvent* tmp = pevent;
pevent = NULL;
putevent(tmp); //активируем событие связанное с этой кнопкой
}
}
}
}
// =============================================================================
NMessageBox::NMessageBox(const char* text) : NGroup(NRect(3, 40, 1, 1))
{
//расчитать сколько строк нужно для отображения контента
int contentheight = 0;
int bsize = strlen(text); //количество байт
int result = 0; //подсчитанное кол-во символов
int nbytes = 0; //просмотренное кол-во байтов
int nlines = 0; //количество экранных строк
int col = getwidth() - 4;
const char* p = text;
do
{
col++;
if ((col >= getwidth() - 4)||(*p == '\n'))
{
if (*p == '\n')
col = 0;
else
col = 1;
contentheight++; //след строка
}
int symlen = mblen(p,bsize-nbytes);
nbytes = nbytes + symlen;
result++;
p = p + symlen; //адрес начала след символа
}
while ( (*p != 0)&&(nbytes < bsize) ); //дошли до конца
//заполняем содержимое
content = new NStaticText(NRect(contentheight, getwidth()-4, 2, 2));
content->setbgcolor(getcolorpair(COLOR_WHITE, COLOR_BLACK));
insert(content);
content->appendstring(getcolorpair(COLOR_WHITE, COLOR_BLACK) | A_BOLD, text);
modalflag = true;
resize(contentheight + 6,getwidth());
wattrset(win,getcolorpair(COLOR_WHITE, COLOR_BLACK) | A_BOLD);
if(asciilinedraw == 1)
wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
else
box(win,0,0);
//content->setalign(1);
move(getmaxy(stdscr)/2-getheight()/2,getmaxx(stdscr)/2-getwidth()/2); //центрируем
}
void NMessageBox::addbutton(NMButton* button) //добавить кнопку
{
insert(button);
std::list::iterator it;
int w = 0; //суммарная ширина всех кнопок
for (it = ++items.begin(); it != items.end(); it++) // ++ пропустить content
{
w = w + (*it)->getwidth() + 2; // +2 промежутки между кнопками
}
int row = getheight() - 3;
int col = (getwidth() - w) / 2 + 2;
for (it = ++items.begin(); it != items.end(); it++)
{
(*it)->move(row, col);
col = col + (*it)->getwidth() + 2;
}
}
void NMessageBox::eventhandle(NEvent* ev) //обработчик событий
{
NGroup::eventhandle(ev); //предок
if ( ev->done )
return;
//одиночный или двойной клик
NMouseEvent* mevent = (NMouseEvent*)ev;
if (/*(*/ ev->type == NEvent::evMOUSE /*) && (mevent->cmdcode & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))*/)
{
//блокируем все мышиные мнутри окна
// if (isinside(mevent->row, mevent->col))
ev->done = true;
}
//клавиатура
if (ev->type == NEvent::evKB )
{
//блокировать все клавиатурные кроме кода закрытия формы
if (ev->keycode != 27)
ev->done = true;
}
}
boinctui-2.5.0/src/mainwin.cpp 0000644 0001750 0001750 00000022273 13001203073 014116 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include "mainwin.h"
#include "tuievent.h"
#include "kclog.h"
#define INFPANWIDTH 20 //ширина инф панели
MainWin::MainWin(NRect rect/*, Config* cfg*/) : NGroup(rect)
{
//читаем опции из конфига если нет то создаем
wtaskheightpercent = 5000;
if (gCfg != NULL)
{
Item* rootcfg = gCfg->getcfgptr();
if (rootcfg != NULL)
{
Item* wtask_height_percent = rootcfg->findItem("wtask_height_percent");
if (wtask_height_percent == NULL) //создать
{
wtask_height_percent = new Item("wtask_height_percent");
wtask_height_percent->setivalue(wtaskheightpercent);
rootcfg->addsubitem(wtask_height_percent);
}
wtaskheightpercent = wtask_height_percent->getivalue();
}
}
colname.push_back(" # ");
colname.push_back("state ");
colname.push_back(" done%%");
colname.push_back(" project ");
colname.push_back(" est");
colname.push_back(" d/l");
colname.push_back(" application ");
colname.push_back(" task");
tablheader = new NStaticText(NRect(1, rect.cols -2-(INFPANWIDTH)-1, 1, 1));
tablheader->setstring(getcolorpair(COLOR_CYAN,COLOR_BLACK) | A_BOLD," # state done%% project est d/l task");
int wtaskheight = getheight() * wtaskheightpercent / 10000.0;
if (wtaskheight < 5)
wtaskheight = 5;
if (wtaskheight > getheight() - 10)
wtaskheight = getheight() - 10;
wtask = new TaskWin(NRect(wtaskheight/*getheight()/2*/, getwidth()-2-(INFPANWIDTH)-1, 2, 1)); //создаем окно процессов внутри wmain
setcoltitle();
taskscrollbar = new NScrollBar(NRect(wtask->getheight()+2,1, wtask->getbegrow()-2, getwidth()-INFPANWIDTH-2), ACS_TTEE | A_BOLD, 0, ACS_VLINE | A_BOLD); //скроллбар панели задач
wtask->setscrollbar(taskscrollbar);
wmsg = new MsgWin(NRect(getheight()-wtask->getheight()-4, getwidth()-2-(INFPANWIDTH+1), wtask->getheight()+3, 1)); //создаем окно евентов
hline = new NHLine(NRect(1, getwidth()-2-(INFPANWIDTH+1), wtask->getheight()+2, 1), NULL); //горизонтальная линия
// vline = new NVLine(NRect(wtask->getheight()+1/*getheight()-2*/, 1, 1, getwidth()-INFPANWIDTH-2), NULL); //вертикальная линия
msgscrollbar = new NScrollBar(NRect(wmsg->getheight()+2,1, wmsg->getbegrow()-1, getwidth()-INFPANWIDTH-2/*vline->getbegcol()*/),/*ACS_RTEE*/ACS_VLINE | A_BOLD,ACS_BTEE | A_BOLD, ACS_VLINE | A_BOLD); //скроллбар панели сообщений
wmsg->setscrollbar(msgscrollbar);
panel1 = new InfoPanel(NRect(getheight()-2,INFPANWIDTH,1,getwidth()-INFPANWIDTH-1));
caption = new NColorString(0,"");
insert(tablheader);
insert(wtask);
insert(wmsg);
insert(hline);
// insert(vline);
insert(taskscrollbar);
insert(msgscrollbar);
insert(panel1);
}
void MainWin::resize(int rows, int cols)
{
NGroup::resize(rows, cols);
tablheader->resize(1, getwidth()-2-(INFPANWIDTH)-1);
int wtaskheight = getheight() * wtaskheightpercent / 10000.0;
if (wtaskheight < 5)
wtaskheight = 5;
if (wtaskheight > getheight() - 10)
wtaskheight = getheight() - 10;
wtask->resize(wtaskheight/*getheight()/2*/, getwidth()-2-(INFPANWIDTH)-1); //размер окна задач
wmsg->resize(getheight()-wtask->getheight()-4, getwidth()-2-(INFPANWIDTH+1));
wmsg->move(wtask->getheight()+3, 1);
hline->resize(1, getwidth()-2-(INFPANWIDTH+1)); //горизонтальная линия
hline->move(wtask->getheight()+2, 1);
// vline->resize(wtask->getheight()+1/*getheight()-2*/, 1);
// vline->move(1 , getwidth()-INFPANWIDTH-2);
msgscrollbar->resize(wmsg->getheight()+2,1);
msgscrollbar->move(wmsg->getbegrow()-1, getwidth()-INFPANWIDTH-2/*vline->getbegcol()*/);
taskscrollbar->resize(wtask->getheight()+2,1);
taskscrollbar->move(wtask->getbegrow()-2, getwidth()-INFPANWIDTH-2);
panel1->resize(getheight()-2,INFPANWIDTH);
panel1->move(1,getwidth()-INFPANWIDTH-1);
}
void MainWin::saveopttoconfig() //сохранить высоту списка задач и т.д. в дереве конфига
{
//пишем в конфиг
if (gCfg != NULL)
{
Item* rootcfg = gCfg->getcfgptr();
if (rootcfg != NULL)
{
Item* wtask_height_percent = rootcfg->findItem("wtask_height_percent");
if (wtask_height_percent != NULL)
wtask_height_percent->setivalue(wtaskheightpercent);
}
}
}
void MainWin::setserver(Srv* srv) //установить отображаемый сервер
{
this->srv = srv;
wmsg->setserver(srv);
wtask->setserver(srv);
panel1->setserver(srv);
}
void MainWin::setcoltitle()
{
std::string s = "";
for (size_t i = 0; i < colname.size(); i++)
{
if (wtask->iscolvisible(i))
s = s + colname[i];
}
tablheader->setstring(getcolorpair(COLOR_CYAN,COLOR_BLACK) | A_BOLD, s.c_str());
}
void MainWin::refresh()
{
wattrset(win, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
if(asciilinedraw == 1)
wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
else
box(win, ACS_VLINE, ACS_HLINE);
//рисуем заголовок
wmove(win,0,(getwidth()/2)-(caption->getlen()+1)/2);
std::list::iterator it;
for (it = caption->parts.begin(); it != caption->parts.end(); it++) //цикл по частям тек строки
{
NColorStringPart* part = *it;
wattrset(win,part->attr);
wprintw(win,"%s",part->s.c_str());
//wattrset(win,0);
}
//wborder(win, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE, ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER);
//wattroff(win, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
NGroup::refresh();
}
void MainWin::updatecaption()
{
NColorString oldcaption = *caption;
caption->clear();
if (srv)
{
caption->append(getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD," Host %s:%s ",srv->gethost(),srv->getport());
if (srv->loginfail)
caption->append(getcolorpair(COLOR_WHITE,COLOR_RED) | A_BOLD,"unauthorized!");
else
{
if (!srv->isconnected())
caption->append(getcolorpair(COLOR_WHITE,COLOR_RED) | A_BOLD,"offline!");
}
}
else
caption->append(getcolorpair(COLOR_WHITE,COLOR_RED) | A_BOLD,"no servers");
if (oldcaption != *caption)
refresh();
}
void MainWin::eventhandle(NEvent* ev) //обработчик событий
{
static int keycodebak = 0;
static int keycodebakbak = 0;
NGroup::eventhandle(ev); //предок
if ( ev->done )
return;
if (ev->type == NEvent::evKB) //клавиатурные
{
//костыль для работы +- на нумпаде независимо от numlock (прямая интерпретация ESC последовательности)
if ((keycodebakbak == 27) && (keycodebak == 79) && (ev->keycode == 107))
ev->keycode = '+';
if ((keycodebakbak == 27) && (keycodebak == 79) && (ev->keycode == 109))
ev->keycode = '-';
switch(ev->keycode)
{
case '-': //меняем размер окна логов
case '+': //меняем размер окна логов
{
int wtaskheight = getheight() * wtaskheightpercent / 10000.0; //высота в строках
//игнорировать событие если дошли до ограничителей
if ((ev->keycode == '+')&&(wtaskheight < 5))
break;
if ((ev->keycode == '-')&&(wtaskheight > getheight() -10))
break;
//расчитать новый процентный размер окна
int delta = 10000.0/getheight();
if (ev->keycode == '+')
delta*=-1;
wtaskheightpercent+=delta;
if (wtaskheightpercent > 10000)
wtaskheightpercent = 10000;
wtaskheightpercent-=10;
if (wtaskheightpercent < 0)
wtaskheightpercent = 0;
//сохранить новое значение в конфиге
saveopttoconfig();
//ресайз и перерисовка
resize(getheight(),getwidth());
refresh();
break;
}
}
keycodebakbak = keycodebak;
keycodebak = ev->keycode;
}
if (ev->type == NEvent::evPROG) //прграммные
{
switch(ev->cmdcode)
{
case evCOLVIEWCH: //изменился набор колонок
{
setcoltitle();
tablheader->refresh();
wtask->refresh();
}
} //switch
}
//событие таймера
if (ev->type == NEvent::evTIMER) //таймер
{
updatecaption();
}
}
boinctui-2.5.0/src/nscrollview.h 0000644 0001750 0001750 00000005631 13124150563 014502 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NSCROLLVIEW_H
#define NSCROLLVIEW_H
#include
#include "nview.h"
#include "ncolorstring.h"
#include "nscrollbar.h"
class NScrollView : public NView //область со скроллингом
{
public:
NScrollView(NRect rect, NScrollBar* scrollbar = NULL) : NView(rect) { this->scrollbar=scrollbar; startindex = 0; autoscroll = false; needrefresh = true;};
virtual ~NScrollView();
void addstring(int attr, const char* fmt, ...);
void addstring(NColorString* s) { content.push_back(s); needrefresh = true; }; //добавляет строку
void eventhandle(NEvent* ev); //обработчик событий
void clearcontent(); //очищает строковый буфер
virtual void drawcontent(); //отрисовывает буфер строк
void scrollto(int delta); //сдвинуть отображение на drlta строк вверх или вниз
void setstartindex(int n); //установить отображение со строки n
int getstartindex() { return startindex; }; //получить номер первой видимой строки
int getmaxcontentwidth(); //вернет максимальную длину строки (в экранных символях) в content
bool getautoscroll() { return autoscroll; }; //true если включен режим автоскроллинга
void setautoscroll(bool b); //true чтобы включить автоскроллинг
void setscrollbar(NScrollBar* scrollbar) { this->scrollbar = scrollbar; };
virtual void resize(int rows, int cols);
virtual void refresh();
int getstringcount() { return content.size();}; //число строк
protected:
std::vector content; //массив строк с цветовыми аттрибутами
int startindex; //номер первой видимой строки
bool autoscroll; //если true то будет прокручивать автоматом до конца
NScrollBar* scrollbar; //скроллбар для этого эл-та (NULL если нет)
};
#endif //NSCROLLVIEW_H boinctui-2.5.0/src/resultparse.cpp 0000644 0001750 0001750 00000012000 12742135224 015025 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include
#include
#include
#include "resultparse.h"
#include "kclog.h"
std::stack
- curitem; //на верху стека указатель на текущий заполняемый эл-т а голова это вершина дерева
void callbackStartElement(void* userdata, const char* name, const char** atts); //колбэк начала эл-та
void callbackEndElement(void* userdata, const char* name); //коллбэк завершения эл-та
void callbackData(void *userdata, const char *content, int len); //коллбэк значения эл-та
char* stripinvalidtag(char* xml, int len) //ГРЯЗНЫЙ ХАК нужен чтобы до парсинга удалить кривые теги
//в сообщениях вида иначе будет ошибка парсинга
{
const char* teg1 = "";
const char* teg2 = "";
int bytesdone = 0; //просмотрено байт
char* pos = (char*)xml;
while (pos < xml + len)
{
char* x1 = strstr(pos, teg1);
char* x2 = strstr(pos, teg2);
if ((x1 != NULL)&&(x2 != NULL))
{
for(char* p = x1 + strlen(teg1); p < x2; p++)
{
if ((*p == '<')||(*p == '>')) //убираем html теги
*p = ' ';
}
pos = (x1>x2)? x1:x2; //берем наибольшую
pos++;
}
else
break;
}
return xml;
}
Item* xmlparse(const char* xml, int len, std::string& errmsg) //xml строка с xml len ее размер в байтах
{
XML_Parser parser;
void* ret;
parser = XML_ParserCreate(NULL/*"UTF-8"*/);
XML_SetUserData(parser, (void*) &ret);
XML_SetElementHandler(parser, callbackStartElement, callbackEndElement); //устанавливаем колбэки
XML_SetCharacterDataHandler(parser, callbackData);
Item* roottree = new Item(""); //создаем корневой эл-т дерева
curitem.push(roottree); //и делаем его текущим
int retcode = XML_Parse(parser, xml, len, XML_TRUE); //собственно парсинг
if (retcode == XML_STATUS_ERROR)
{
kLogPrintf("XML Error: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
errmsg = std::string("XML error:") + std::string(XML_ErrorString(XML_GetErrorCode(parser)));
}
XML_ParserFree(parser);
while (!curitem.empty())
curitem.pop(); //очищаем стек
return roottree; //возвращаем постороенное дерево
}
void callbackStartElement(void* userdata, const char* name, const char** atts)
{
//kLogPrintf("\t+ %s\n",name);
//аттрибуты тегов типа
//length=4 это атрибут (в boinc таких тегов нет?)
/*
for(int i = 0; atts[i]; i += 2)
printf(" %s= '%s'", atts[i], atts[i + 1]);
printf("\n");
*/
//создаем новый эл-т дерева
Item* pitem = new Item(name);
//добавляем созданный эл-т в вышестоящий (если он есть)
if (!curitem.empty())
{
Item* parentitem = curitem.top(); //владелец всегда на верху стека
parentitem->addsubitem(pitem);
}
//делаем созданный эл-т текущим (кладем в стек)
curitem.push(pitem);
}
void callbackEndElement(void* userdata, const char* name)
{
//kLogPrintf("\t- %s\n",name);
//удаляем текущий эл-т из стека (текущим становится его родитель)
curitem.pop();
}
void callbackData(void *userdata, const char *content, int len)
{
char *tmp = (char*)malloc(len+1);
strncpy(tmp, content, len);
tmp[len] = '\0';
//data = (void *) tmp;
//kLogPrintf("\ncallbackData()-->[%s]<-- len=%d\n",tmp,len);
//заносим значение в текущий эл-т
bool empty = true;
for (int i = 0; i < strlen(tmp); i++)
{
if (tmp[i] != ' ')
{
empty = false;
break;
}
}
if ( (!empty) && (strcmp(tmp,"\n") != 0) ) //пропускаем пустые строки
{
Item* pitem = curitem.top(); //текущий на верху стека
pitem->appendvalue(tmp);
}
free(tmp);
}
boinctui-2.5.0/src/taskinfowin.cpp 0000644 0001750 0001750 00000026756 12742135224 015037 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012-2014 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include
#include "kclog.h"
#include "taskinfowin.h"
std::string raw2hr (Item* item)
{
std::stringstream result;
if ( 0 == strcmp(item->getname(), "fraction_done") )
{
double d = item->getdvalue();
result << std::setprecision(4) << d*100 << " %";
}
if ( 0 == strcmp(item->getname(), "active_task_state") )
{
int i = item->getivalue();
switch (i)
{
case 0: result << "uninitialized"; break;
case 1: result << "executing"; break;
case 9: result << "suspended"; break;
case 5: result << "abort pending"; break;
case 8: result << "quit pending"; break;
case 10: result << "copy panding"; break;
}//switch
}
if ( 0 == strcmp(item->getname(), "scheduler_state") )
{
int i = item->getivalue();
switch (i)
{
case 1: result << "preempted"; break;
case 2: result << "scheduled"; break;
}//switch
}
if ( 0 == strcmp(item->getname(), "state") )
{
int i = item->getivalue();
switch (i)
{
case 0: result << "new"; break;
case 1: result << "downloading"; break;
case 2: result << "downloaded"; break;
case 3: result << "compute error"; break;
case 4: result << "uploading"; break;
case 5: result << "uploaded"; break;
case 6: result << "aborted"; break;
case 7: result << "upload failed"; break;
}//switch
}
if ( 0 == strcmp(item->getname(), "exit_status") )
{
int i = item->getivalue();
switch (i)
{
case 192: result << "exit statfile write"; break;
case 193: result << "exit signal"; break;
case 194: result << "aborted by client"; break;
case 195: result << "exit child failed"; break;
case 196: result << "exit disk limit exceeded"; break;
case 197: result << "exit time limit exceeded"; break;
case 198: result << "exit mem limit exceeded"; break;
case 199: result << "exit client exiting"; break;
case 200: result << "exit unstarted late"; break;
case 201: result << "exit missing coproc"; break;
case 202: result << "exit aborted by project"; break;
case 203: result << "aborted via gui"; break;
case 204: result << "exit unknown"; break;
}//switch
}
if
(
!strcmp(item->getname(), "received_time") ||
!strcmp(item->getname(), "report_deadline") ||
!strcmp(item->getname(), "completed_time")
)
{
time_t t = (time_t)item->getdvalue();
std::string s = ctime(&t);
if (s.size() > 0)
s.resize(s.size()-1); //убрать символ \n в конце
result << s;
}
if
(
!strcmp(item->getname(), "estimated_cpu_time_remaining") ||
!strcmp(item->getname(), "current_cpu_time") ||
!strcmp(item->getname(), "final_cpu_time") ||
!strcmp(item->getname(), "final_elapsed_time") ||
!strcmp(item->getname(), "checkpoint_cpu_time") ||
!strcmp(item->getname(), "elapsed_time")
)
{
time_t t = (time_t)item->getdvalue();
time_t t2;
int days = t / (24 * 3600);
t2 = t - (days * 24 * 3600);
int hours = t2 / 3600;
t2 = t2 - hours * 3600;
int mins = t2 / 60;
int secs = t2 - mins * 60;
if (days)
result << days << "d " << hours << "h " << mins << "m " << secs << "s";
else
{
if (hours)
result << hours << "h " << mins << "m " << secs << "s";
else
{
if (mins)
result << mins << "m " << secs << "s";
else
result << secs << "s";
}
}
}
return result.str();
}
void Tree2Text(Item* item, std::vector >& vout, int& maxlen1, int& maxlen2)
{
std::vector
- v = item->getItems(""); //получить все эл-ты
std::vector
- ::iterator it2;
for (it2 = v.begin(); it2!=v.end(); it2++) //цикл по эл-там задачи
{
if ((*it2)->isnode())
{
vout.push_back(std::pair( "", "")); //разделитель
Tree2Text(*it2, vout, maxlen1, maxlen2); //рекурсия
vout.push_back(std::pair( "", "")); //разделитель
}
else
{
std::string sval = (*it2)->getsvalue();
std::string svalhr = raw2hr(*it2);
if (svalhr.length())
sval = sval + " (" + svalhr + ")";
if (strlen((*it2)->getname()) > maxlen1)
maxlen1 = strlen((*it2)->getname());
if (sval.length()/*strlen((*it2)->getsvalue())*/ > maxlen2)
maxlen2 = sval.length() /*strlen((*it2)->getsvalue())*/;
vout.push_back(std::pair((*it2)->getname(), sval/*(*it2)->getsvalue()*/));
}
}
}
//поиск в векторе v переменной с именем varname. Вернет значение или ""
std::string FindVar(std::vector >& v, std::string& varname)
{
std::string result = "";
std::vector >::iterator it;
for (it = v.begin(); it!=v.end(); it++)
{
if ((*it).first == varname)
{
result = (*it).second;
break;
}
}
return result;
}
// =============================================================================
TaskInfoWin::TaskInfoWin(const char* caption, Srv* srv, const char* projecturl, const char* taskname)
: NGroup(NRect(getmaxy(stdscr) - 10, getmaxx(stdscr) - 60, 3, 3))
{
modalflag = true;
this->srv = srv;
this->projecturl = projecturl;
this->taskname = taskname;
this->caption = " ";
this->caption = this->caption + caption;
this->caption = this->caption + " ";
content = new NScrollView(NRect(getheight()-4, getwidth()-4, 2, 2));
insert(content);
updatedata();
//корректируем высоту в меньшую сторону если возможно
if (content->getstringcount() < content->getheight())
{
content->resize(content->getstringcount(), content->getwidth());
resize(content->getheight() + 4, getwidth());
}
//растягиваем по ширине
content->resize(content->getheight(), maxlen1 + maxlen2 + 10);
resize(getheight(), content->getwidth() + 4);
if (getwidth() > getmaxx(stdscr) - 10) //если слишком широко обрезаем
{
resize(getheight(), getmaxx(stdscr) - 10);
content->resize(content->getheight(), getwidth() - 4);
}
if(asciilinedraw == 1)
wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
else
box(win,0,0);
mvwprintw(win,0,getwidth()/2-(strlen(caption)/2), this->caption.c_str());
scrollbar = new NScrollBar(NRect(content->getheight()+2,1, content->getbegrow()-1, getwidth()-1), 0, 0, ACS_VLINE);
content->setscrollbar(scrollbar);
insert(scrollbar);
refresh();
}
void TaskInfoWin::updatedata()
{
if (srv == NULL)
return;
//===данные по процессам===
if (srv->statedom.empty())
return;
Item* tmpstatedom = srv->statedom.hookptr();
Item* client_state = tmpstatedom->findItem("client_state");
std::vector > ss;
maxlen1 = 0;
maxlen2 = 0;
if (client_state != NULL)
{
int oldstartindex = content->getstartindex();
content->clearcontent();
std::vector
- results = client_state->getItems("result");
std::vector
- ::iterator it;
for (it = results.begin(); it!=results.end(); it++) //цикл списка задач
{
Item* project_url = (*it)->findItem("project_url");
Item* name = (*it)->findItem("name");
if ((project_url != NULL)&&
(name != NULL)&&
(strcmp(project_url->getsvalue(), projecturl.c_str()) == 0)&&
(strcmp(name->getsvalue(), taskname.c_str()) == 0))
{
//имя проекта
std::string pname = srv->findProjectName(tmpstatedom, (*it)->findItem("project_url")->getsvalue());
ss.push_back(std::pair("PROJECT NAME", pname));
//имя приложения
char buf[256];
snprintf(buf, sizeof(buf),"%s","unknown application");
Item* wu_name = (*it)->findItem("wu_name");
if (wu_name != NULL)
{
Item* app = srv->findappbywuname(wu_name->getsvalue());
if (app != NULL)
{
Item* user_friendly_name = app->findItem("user_friendly_name");
if (user_friendly_name != NULL)
snprintf(buf, sizeof(buf),"%s",user_friendly_name->getsvalue());
}
}
ss.push_back(std::pair("APP NAME", buf));
ss.push_back(std::pair("", ""));
//raw данные
Tree2Text(*it, ss, maxlen1, maxlen2);
break;
}
} //цикл списка задач
content->setstartindex(oldstartindex);
needrefresh = true;
}
srv->statedom.releaseptr(tmpstatedom);
//заполняем визуальные строки
std::vector >::iterator it;
for (it = ss.begin(); it!=ss.end(); it++)
{
int varcolor = getcolorpair(COLOR_WHITE, COLOR_BLACK) | A_BOLD;
int valcolor = getcolorpair(COLOR_WHITE, COLOR_BLACK) | A_BOLD;
if ((FindVar(ssbak, (*it).first) != (*it).second)&&(!ssbak.empty()))
valcolor = getcolorpair(COLOR_CYAN, COLOR_BLACK) | A_BOLD;
NColorString* cs = new NColorString(varcolor, "%-*s ", maxlen1, (*it).first.c_str());
cs->append(valcolor, "%s\n", (*it).second.c_str());
content->addstring(cs);
}
ssbak = ss;
}
void TaskInfoWin::eventhandle(NEvent* ev) //обработчик событий
{
NGroup::eventhandle(ev); //предок
if ( ev->done )
return;
//реакция на мышь
NMouseEvent* mevent = (NMouseEvent*)ev;
if ( ev->type == NEvent::evMOUSE )
{
//блокируем все что внутри
if (isinside(mevent->row, mevent->col))
ev->done = true;
//закрываем при любом клике независимо от координат
if (mevent->cmdcode & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
{
putevent(new NEvent(NEvent::evKB, 27));
ev->done = true;
}
}
//клавиатура
if ( ev->type == NEvent::evKB )
{
ev->done = true;
switch(ev->keycode)
{
case KEY_PPAGE:
content->scrollto(-getheight()/2); //вверх на полокна
content->setautoscroll(false);
break;
case KEY_NPAGE:
if (!content->getautoscroll())
{
int oldpos = content->getstartindex();
content->scrollto(getheight()/2); //вниз на пол окна
if ( oldpos == content->getstartindex()) //позиция не изменилась (уже достигли конца)
content->setautoscroll(true); //включаем автоскроллинг
}
break;
default:
//блокировать все клавиатурные кроме кода закрытия формы
if (ev->keycode == 27)
ev->done = false;
} //switch
if (ev->done) //если обработали, то нужно перерисоваться
refresh();
}
if ( ev->type == NEvent::evTIMER )
{
updatedata(); //запросить данные с сервера
refresh(); //перерисовать окно
}
}
boinctui-2.5.0/src/tuievent.h 0000644 0001750 0001750 00000010204 12742135224 013770 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef TUIEVENT_H
#define TUIEVENT_H
#include "srvdata.h"
#include "nevent.h"
enum TuiEventType
{
evCFGCH, //конфигурация изменена
evABORTRES, //abort selected result
evABOUT, //открыть/закрыть откно About
evKEYBIND, //открыть/закрыть откно Key Bindings
evBENCHMARK, //run benchmark
evADDPROJECT, //форма добавить проект
evCOLVIEWCH, //переключение видимости колонки
evVIEWMODECH, //переключение режима видимости All/Hide done/Active tasks only
evSORTMODECH, //переключение режима сортировки списка задач 0-unsorted 1-state e.t.c.
evADDACCMGR, //форма акк менеджера
evPROJECTOP, //операции над проектом
evTASKINFO, //генерируется когда нужно открыть окно детальной информации о задаче
evTASKSELECTORON, //генерируется когда селектор задач становится видимым
evTASKSELECTOROFF, //генерируется когда селектор задач становится скрытым
evASCIIMODECHANGE, //генерируется при переключении режима ASCII рамок
evPOPUPMSG //генерируется когда нужно открыть попап сообщение
};
class TuiEvent : public NEvent //класс программных событий специфичных для boinctui
{
public:
TuiEvent(TuiEventType type) : NEvent(evPROG, type) {};
TuiEvent(TuiEventType type, Srv* srv, const char* prjname, bool userexist) : NEvent(evPROG, type) //событие для добавления проекта
{
this->srv = srv;
this->sdata1 = prjname;
this->bdata1 = userexist;
};
TuiEvent(TuiEventType type, Srv* srv, const char* mgrname) : NEvent(evPROG, type) //событие для подключения к менеджеру
{
this->srv = srv;
this->sdata1 = mgrname;
};
TuiEvent(TuiEventType type, Srv* srv, const char* projname, const char* projop) : NEvent(evPROG, type) //событие для действий с проектами
{
this->srv = srv;
this->sdata1 = projname;
this->sdata2 = projop;
this->bdata1 = false; //true - если получено подтверждение
};
TuiEvent(TuiEventType type ,int ncolumn, bool enable) : NEvent(evPROG, type) //событие переключения видимости колонки
{
this->idata1 = ncolumn;
this->bdata1 = enable;
};
TuiEvent(TuiEventType type ,int mode) : NEvent(evPROG, type) //событие режим видимости задач
{
this->idata1 = mode;
};
TuiEvent(TuiEventType type, const char* caption, const char* msg) : NEvent(evPROG, type) //событие попап сообщения
{
this->sdata1 = caption;
this->sdata2 = msg;
};
virtual ~TuiEvent() { /*kLogPrintf("~TuiEvent()\n");*/ };
Srv* srv;
std::string sdata1; //произвольная строка
std::string sdata2; //произвольная строка
bool bdata1; //произаольная bool переменная
int idata1; //произвольное целое
};
#endif //TUIEVENT_H
boinctui-2.5.0/src/addmgrform.cpp 0000644 0001750 0001750 00000023124 13124150563 014605 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include "addmgrform.h"
#include "mbstring.h"
#include "kclog.h"
#include "tuievent.h"
char* strlowcase(char* s); //в нижний регистр
AddAccMgrForm::AddAccMgrForm(int rows, int cols, Srv* srv, const char* mgrname) : NForm(rows,cols)
{
this->srv = srv;
settitle(mgrname);
this->mgrname = mgrname;
Item* account_manager = NULL;
if (srv !=NULL)
account_manager = srv->findaccountmanager(mgrname);
//поля
int row = 0;
genfields(row,account_manager);
//пересчитываем высоту формы, чтобы влезли все поля и центрируем
int r,c =0;
scale_form(frm, &r, &c);
kLogPrintf("field_count=%d scale_form()->%d,%d\n", field_count(frm), r, c);
resize(r+3,c+2);
set_current_field(frm, fields[0]); //фокус на поле
post_form(frm);
this->refresh();
}
void AddAccMgrForm::genfields(int& line, Item* mgr) //создаст массив полей
{
FIELD* f;
delfields();
//сообщение об ошибке
errmsgfield = getfieldcount();
f = addfield(new_field(1, getwidth()-2, line++, 0, 0, 0));
set_field_buffer(f, 0, "Errr");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_RED) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
field_opts_off(f, O_VISIBLE); //по умолчанию невидима
//получить url и имя менеджера (или из конфига или от boinc клиента
if (mgr != NULL)
{
Item* url = mgr->findItem("url");
if (url !=NULL)
mgrurl = url->getsvalue();
}
else
{
//взять url из конфига (если есть)
Item* boinctui_cfg = gCfg->getcfgptr();
if (boinctui_cfg != NULL)
{
std::vector
- mgrlist = boinctui_cfg->getItems("accmgr");
std::vector
- ::iterator it;
for (it = mgrlist.begin(); it != mgrlist.end(); it++)
{
Item* name = (*it)->findItem("name");
if (name != NULL)
if (name->getsvalue() == mgrname)
{
Item* url = (*it)->findItem("url");
if (url != NULL)
{
mgrurl = url->getsvalue();
break;
}
}
}
}
}
//имя менеджера
f = addfield(new_field(1, getwidth()-4, line, 2, 0, 0));
set_field_buffer(f, 0, "Description ");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
namefield = getfieldcount();
f = addfield(new_field(1, 40, line++, 15, 0, 0));
if (mgr != NULL)
{
field_opts_off(f, O_STATIC);
field_opts_off(f, O_ACTIVE); //статический текст
}
else
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_CYAN) | A_BOLD);
field_opts_off(f, O_AUTOSKIP);
set_max_field(f,128); //max width 128
char buf[129];
strncpy(buf, gettitle(), 128);
buf[128] = '\0';
char* p;
p = ltrim(buf);
rtrim(buf);
set_field_buffer(f, 0, p);
//url
line++;
f = addfield(new_field(1, getwidth()-4, line, 2, 0, 0));
set_field_buffer(f, 0, "URL ");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
urlfield = getfieldcount();
f = addfield(new_field(1, 40, line++, 15, 0, 0));
if (mgr != NULL)
{
field_opts_off(f, O_STATIC);
field_opts_off(f, O_ACTIVE); //статический текст
}
else
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_CYAN) | A_BOLD);
field_opts_off(f, O_AUTOSKIP);
set_max_field(f,128); //max width 128
set_field_buffer(f, 0, mgrurl.c_str());
//help
line++;
f = addfield(new_field(3, getwidth()-4, line++, 2, 0, 0));
set_field_buffer(f, 0, "If you have not yet registered with this account manager" \
" please do so before proceeding.");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
line = line + 2;
//user name
line++;
f = addfield(new_field(1, 10, line, 2 , 0, 0));
set_field_buffer(f, 0, "username");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
usernamefield = getfieldcount();
f = addfield(new_field(1, 40, line++, 15, 0, 0));
field_opts_off(f, O_AUTOSKIP);
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_CYAN) | A_BOLD);
//password
line++;
f = addfield(new_field(1, 10, line, 2 , 0, 0));
set_field_buffer(f, 0, "password");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
passwfield = getfieldcount();
f = addfield(new_field(1, 40, line++, 15, 0, 0));
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_CYAN) | A_BOLD);
field_opts_off(f, O_AUTOSKIP);
//подсказки
line++;
f = addfield(new_field(1, getwidth()-25, line++, 20 , 0, 0));
set_field_buffer(f, 0, "Enter-Ok Esc-Cancel");
set_field_back(f, getcolorpair(COLOR_WHITE,COLOR_BLACK) | A_BOLD);
field_opts_off(f, O_ACTIVE); //статический текст
//финализация списка полей
addfield(NULL);
}
void AddAccMgrForm::eventhandle(NEvent* ev) //обработчик событий
{
if ( ev->done )
return;
NMouseEvent* mevent = (NMouseEvent*)ev;
if ( ev->type == NEvent::evMOUSE)
{
NForm::eventhandle(ev); //предок
}
if ( ev->type == NEvent::evKB )
{
ev->done = true;
switch(ev->keycode)
{
case KEY_ENTER:
case '\n': //ENTER
{
form_driver(frm, REQ_NEXT_FIELD); //костыль чтобы текущее поле не потеряло значение
char* username = rtrim(field_buffer(fields[usernamefield],0));
char* passw = rtrim(field_buffer(fields[passwfield],0));
mgrurl = rtrim(field_buffer(fields[urlfield],0));
char* mgrname = rtrim(field_buffer(fields[namefield],0));
kLogPrintf("AddAccMgrForm OK username=[%s] passw=[%s]\n", username, passw);
if (srv!=NULL)
{
std::string errmsg;
bool success = srv->accountmanager(mgrurl.c_str(), username, passw, false, errmsg);
if (success)
{
Item* account_manager = NULL;
if (srv !=NULL)
account_manager = srv->findaccountmanager(mgrname);
if (account_manager == NULL) //для кастомных менеджеров сохраняем в конфигах
{
//проверить есть-ли уже в конфиге такой аккаунт менеджер
//то обновляем существующую запись, иначе добавляем новую
bool exist = false;
Item* boinctui_cfg = gCfg->getcfgptr();
if (boinctui_cfg != NULL)
{
std::vector
- mgrlist = boinctui_cfg->getItems("accmgr");
std::vector
- ::iterator it;
for (it = mgrlist.begin(); it != mgrlist.end(); it++)
{
Item* namecfg = (*it)->findItem("name");
Item* urlcfg = (*it)->findItem("url");
if (namecfg != NULL)
if (strcmp(namecfg->getsvalue(),mgrname) == 0)
{
exist = true;
//обновить значение url в конфиге
Item* urlcfg = (*it)->findItem("url");
if (urlcfg != NULL)
urlcfg->setsvalue(mgrurl.c_str());
}
if (urlcfg != NULL)
{
if (strcmp(urlcfg->getsvalue(),mgrurl.c_str()) == 0)
{
exist = true;
//обновить значение имени в конфиге
Item* namecfg = (*it)->findItem("name");
if (namecfg != NULL)
namecfg->setsvalue(mgrname);
}
}
if (exist)
break;
}
if (!exist)
{
//записать в конфиг как новый
Item* accmgr = new Item("accmgr");
boinctui_cfg->addsubitem(accmgr);
Item* name = new Item("name");
name->setsvalue(mgrname);
Item* url = new Item("url");
url->setsvalue(mgrurl.c_str());
accmgr->addsubitem(name);
accmgr->addsubitem(url);
}
}
}
putevent(new TuiEvent(evADDACCMGR)); //создаем событие чтобы закрыть форму
}
else
{
//СООБЩЕНИЕ ОБ ОШИБКЕ
errmsg = " Error: " + errmsg;
set_field_buffer(fields[errmsgfield], 0, errmsg.c_str());
field_opts_on(fields[errmsgfield], O_VISIBLE); //делаем видимой строку ошибки
this->refresh();
}
}
break;
}
case 27:
putevent(new TuiEvent(evADDACCMGR, srv, mgrname.c_str())); //код закрытия окна
break;
default:
kLogPrintf("AddAccMgrForm::KEYCODE=%d\n", ev->keycode);
ev->done = false;
NForm::eventhandle(ev); //предок
break;
} //switch
}
}
boinctui-2.5.0/src/nevent.h 0000644 0001750 0001750 00000004715 12742135224 013436 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NEVENT_H
#define NEVENT_H
#ifdef DEBUG
#include
#include
#endif
//#include "kclog.h"
class NEvent //класс описывающий событие создаваемое например при нажатии клавиш
{
public:
enum Type { evKB, evMOUSE, evPROG, evTIMER }; //evPROG событие генерируемое самой прораммой
NEvent(NEvent::Type type, int keycode) { this->type = type; this->done = false; this->keycode = keycode;};
virtual ~NEvent() { /*kLogPrintf("~NEvent()\n");*/ };
NEvent::Type type;
bool done; //true если обработано
union
{
int keycode; //код клавиатуры
int cmdcode; //произвольный код команды
};
#ifdef DEBUG
virtual std::string tostring()
{
std::stringstream s;
s << this << " " << type << "(";
switch (type)
{
case evKB:
s << "evKB keycode=" << keycode;
break;
case evMOUSE:
s << "evMOUSE";
break;
case evPROG:
s << "evPROG";
break;
case evTIMER:
s << "evTIMER";
break;
};
s << ")";
return s.str();
};
#endif
};
class NMouseEvent : public NEvent
{
public:
NMouseEvent(int bstate, int row, int col) : NEvent(evMOUSE, bstate) //bstate (see mmask_t ncurses.h)
{
this->col = col;
this->row = row;
};
virtual ~NMouseEvent() { /*kLogPrintf("~NMouseEvent()\n");*/ };
int row;
int col;
#ifdef DEBUG
virtual std::string tostring()
{
std::stringstream s;
s << NEvent::tostring() << "{row=" << row << ",col=" << col << ",bstate=" << std::hex << cmdcode;
s << "}";
return s.str();
};
#endif
};
#endif //NEVENT_H boinctui-2.5.0/src/nrect.h 0000644 0001750 0001750 00000002412 12742135224 013242 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NRECT_H
#define NRECT_H
class NRect //прямоугольная область //нумерация строк и столбцов идет от 0
{
public:
NRect() {};
NRect(int rows, int cols, int begrow, int begcol) {this->begrow = begrow; this->begcol = begcol; this->rows = rows; this->cols = cols;};
int begrow;
int begcol;
int rows; //высота (число строк)
int cols; //ширина (число колонок)
};
#endif //NRECT_H boinctui-2.5.0/src/mainprog.h 0000644 0001750 0001750 00000004271 13124150563 013746 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef MAINPROG_H
#define MAINPROG_H
#include "nprogram.h"
#include "msgwin.h"
#include "taskwin.h"
#include "mainwin.h"
#include "cfgform.h"
#include "cfg.h"
#include "srvdata.h"
#include "topmenu.h"
#include "about.h"
#include "helpwin.h"
#include "addprojectform.h"
#include "addmgrform.h"
#include "taskinfowin.h"
#define stUISELECTOR 1 //бит означающий что селектор задач включен
#define stUIMODALFORM 2 //бит означающий что активна модальная форма
#define stUITASKINFO 4 //бит означающий что активно окно и-и о задаче
#define stUISTATWIN 8 //бит означающий что активно окно детальной статистики (StatWin)
class MainProg : public NProgram
{
public:
MainProg();
~MainProg();
void smartresize();
bool mainloop();
virtual void eventhandle(NEvent* ev); //обработчик событий
protected:
TopMenu* menu;
MainWin* wmain;
NStaticText* wstatus;
//Config* cfg;
SrvList* gsrvlist; //глобальный список серверов
bool done; //флаг требования завершения
// void setcaption();
time_t evtimertime; //time of last evTIMER
unsigned int uistate; //маска состояния интерфейса
void updatestatuslinecontent();
};
#endif //MAINPROG_H
boinctui-2.5.0/src/nview.h 0000644 0001750 0001750 00000006465 12763755520 013305 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NVIEW_H
#define NVIEW_H
#include
#if HAVE_LIBNCURSESW == 1 && NCURSESW_HAVE_SUBDIR == 1
#include
#else
#include
#endif
#include "nrect.h"
#include "nevent.h"
class NGroup;
void initcolorpairs();
int getcolorpair(int fcolor, int bcolor); //получить пару для комбинации цветов
extern int asciilinedraw; //1-рисовать рамки символами +----+
class NView //базовый визуальный класс
{
public:
NView(NRect rect);
virtual ~NView() { del_panel(pan); delwin(win); };
//virtual void draw() {};
virtual void resize(int rows, int cols);
virtual void move(int begrow, int begcol);
PANEL* getpan() { return pan; }; //!!!!!!!!!!!!!!!!!!!!
int getwidth() { return rect.cols; }; //ширина в символах
int getheight() { return rect.rows; }; //высота в строках
int getbegrow() { return rect.begrow; }; //начальная строка
int getbegcol() { return rect.begcol; }; //начальный столбец
void erase() { werase(win); }; //очистить
bool isinside(int row, int col); //true если координаты внутри окна (row col абсолютные!)
virtual void refresh(); //перерисовать
virtual void setneedrefresh() { needrefresh = true; };
virtual void eventhandle(NEvent* ev) {/*EMPTY*/}; //обработчик событий
virtual void putevent(NEvent* ev); //отправить событие по цепочке владельцев в очередь
void setowner(NGroup* owner);
virtual const char* getid() { return typeid(*this).name(); }; //возвращает имя класса
virtual bool ismodal() { return modalflag; };
protected:
NGroup* owner; //владелец эл-та
WINDOW* win; //окно curses
PANEL* pan; //панель curses на основе окна win
bool needrefresh; //устанавливается в true когда нужна перерисовка
#ifdef DEBUG
int refreshcount; //счетчик обновлений
#endif
bool modalflag; //true если этот эл-т модальный
int getabsbegrow(); //получить начальную строку (абсолютную на экране)
int getabsbegcol(); //получить начальный столбец (абсолютный на экране)
private:
NRect rect; //координаты и размер
};
#endif //NVIEW_H boinctui-2.5.0/src/nvline.h 0000644 0001750 0001750 00000002253 12742135224 013425 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NVLINE_H
#define NVLINE_H
#include "nview.h"
class NVLine : public NView
{
public:
NVLine(NRect rect, const char* s) : NView(rect) { bgcolor = 0; };
virtual ~NVLine() { };
void setbgcolor(int colorpair) { bgcolor = colorpair; };
virtual void refresh();
protected:
int bgcolor; //цвет фона
const char* mbsym; //символ
};
#endif //NVLINE_H boinctui-2.5.0/src/cfgform.h 0000644 0001750 0001750 00000003066 12742135224 013560 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef CFGFORM_H
#define CFGFORM_H
#include
#include
#include "nform.h"
#include "cfg.h"
#include "nstatictext.h"
class CfgForm : public NForm
{
public:
CfgForm(int lines, int rows/*, Config* cfg*/);
void genfields(bool extfields); //создаст массив полей (extfields если нужно добавить хост)
virtual void eventhandle(NEvent* ev); //обработчик событий
protected:
void updatecfg(); //сохраняет данные из формы в cfg
//Config* cfg;
bool extfields; //true если поле для доп хоста видимо
int nhost; //макс номер хоста с 0го (включаа дополнительный если есть)
};
#endif //CFGFORM_H boinctui-2.5.0/src/infopanel.h 0000644 0001750 0001750 00000007533 13001203131 014071 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef INFOPANEL_H
#define INFOPANEL_H
#include "nview.h"
#include "resultdom.h"
#include "srvdata.h"
struct ProjectStat //статистика по проекту
{
std::string name; //имя проекта
std::string sstatus; //строка состояния проекта
double user; //очки по проекту (всего для юзера)
double host; //очки по проекту (всего для хоста)
time_t laststattime; //дата последней статистики
double userlastday; //очки юзера за последний день по каждому проекту
double hostlastday; //очки хоста за последний день по каждому проекту
static bool CmpAbove( ProjectStat stat1, ProjectStat stat2 ) //для сортировки проектов true если дата stat1 > stat2
{
//суммарная для юзера и хоста
double score1 = stat1.userlastday + stat1.hostlastday;
double score2 = stat2.userlastday + stat2.hostlastday;
if (stat1.laststattime == stat2.laststattime)
return (score1 > score2); //даты равны -> больше тот у кого больше очков
else
return (stat1.laststattime > stat2.laststattime); //больше тот у кого дата больше
/*
//оба с нулевыми (или оба с ненеулевыми) очками -> ставниваем по датам
if ( ((score1 == 0)&&(score2 == 0)) ||
((score1 > 0)&&(score2 > 0)) )
{
if (stat1.laststattime == stat2.laststattime)
{
//даты равны -> больше тот у кого больше очков
return (score1 > score2);
}
else //больше stat1 если у него дата больше
return (stat1.laststattime > stat2.laststattime);
}
// если stat1 с ненулевыми очками (stat2 соотв с нулевыми) -> stat1 больше
return (score1 > 0 );
*/
};
};
class InfoPanel : public NView
{
public:
InfoPanel(NRect rect) : NView(rect) {};
void updatedata();
virtual void refresh();
void setserver(Srv* srv) { this->srv = srv; };
virtual void eventhandle(NEvent* ev); //обработчик событий
protected:
Srv* srv;
std::string getdayname(time_t ltime); //название дня "today" "yesterday" ""
//---для процессов---
int nalltasks;
int nactivetasks;
int nruntasks;
int nqueuetasks;
int ndonetasks;
int nothertasks;
//---для дисков---
double dtotal;
double dfree;
double dboinc;
double dallowed;
//---статистика cуммарная---
double usertotal;
double useravg;
double hosttotal;
double hostavg;
//---статистика за сегодня---
time_t laststattime; //дата последней статистики
double lastdayuser;
double lastdayhost;
std::vector projects; //статистика по отдельным проектам
};
#endif //INFOPANEL_H
boinctui-2.5.0/src/helpwin.cpp 0000644 0001750 0001750 00000006507 12742135224 014141 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include "helpwin.h"
#include "tuievent.h"
HelpWin::HelpWin(int rows, int cols) : NGroup(NRect(rows, cols, getmaxy(stdscr)/2-rows/2,getmaxx(stdscr)/2-cols/2))
{
caption = strdup(" Hot keys list ");
modalflag = true;
resize(17,60);
wattrset(win,getcolorpair(COLOR_WHITE, COLOR_BLACK) | A_BOLD);
if(asciilinedraw == 1)
wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
else
box(win,0,0);
mvwprintw(win,0,getwidth()/2-(strlen(caption)/2),caption);
text1 = new NStaticText(NRect(getheight()-2,getwidth()-2,/*rect.begrow+*/1,/*rect.begcol+*/1));
int attr1 = getcolorpair(COLOR_YELLOW, COLOR_BLACK) | A_BOLD;
int attr2 = getcolorpair(COLOR_WHITE, COLOR_BLACK) | A_BOLD;
text1->setstring(attr1, "\n Common Controls:\n");
text1->appendstring(attr2," \"N\" - Toogle between BOINC hosts\n");
text1->appendstring(attr2," \"C\" - Edit configuration\n");
text1->appendstring(attr2," \"Q\" - Quit boinctui\n");
text1->appendstring(attr2," \"F9\" - Toogle main menu\n");
text1->appendstring(attr2," \"PgUp\"/\"PgDn\" - Scroll Messages Window\n");
text1->appendstring(attr2,"\n");
text1->appendstring(attr1," Task Controls:\n");
text1->appendstring(attr2," \"Up\"/\"Dn\" - Select task\n");
text1->appendstring(attr2," \"S\" - Suspend selected running task\n");
text1->appendstring(attr2," \"R\" - Resume selected suspended task\n");
text1->appendstring(attr2," \"A\" - Abort selected task\n");
text1->appendstring(attr2," \"Enter\" - View selected task raw info\n");
insert(text1);
}
void HelpWin::eventhandle(NEvent* ev) //обработчик событий
{
NGroup::eventhandle(ev); //предок
if ( ev->done )
return;
//закрываем при любом клике независимо от координат
NMouseEvent* mevent = (NMouseEvent*)ev;
if (( ev->type == NEvent::evMOUSE ) && (mevent->cmdcode & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED)))
putevent(new TuiEvent(evKEYBIND));
if ( ev->type == NEvent::evKB )
{
ev->done = true;
switch(ev->cmdcode)
{
case 27:
case KEY_ENTER:
case ' ':
case '\n':
putevent(new TuiEvent(evKEYBIND)); //NEvent(NEvent::evPROG, 4)); //создаем событие с кодом 4 "окно Help"
break;
} //switch
if (ev->done) //если обработали, то нужно перерисоваться
refresh();
}
}
boinctui-2.5.0/src/nform.h 0000644 0001750 0001750 00000003520 13124150563 013247 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NFORM_H
#define NFORM_H
#include
#include
#if HAVE_LIBNCURSESW == 1 && NCURSESW_HAVE_SUBDIR == 1
#include
#else
#include
#endif
#include "ngroup.h"
class NForm : public NGroup
{
public:
NForm(int lines, int rows);
virtual ~NForm();
virtual void refresh();
virtual void resize(int rows, int cols);
virtual void settitle(const char* title);
virtual const char* gettitle() { return title; };
virtual void eventhandle(NEvent* ev); //обработчик событий
virtual FIELD* addfield(FIELD* field);
int getfieldcount() { return fieldcount; };
virtual void delfields(); //удаляет все поля
protected:
bool clickatfield(int mrow, int mcol, FIELD* f); //true если клик внутри этого поля
char* title; //заголовок
FIELD** fields;
int fieldcount; //число полей включая NULL
FORM* frm; //форма ncurses
WINDOW* subwin; //подокно curses
};
#endif //NFORM_H boinctui-2.5.0/src/nhline.h 0000644 0001750 0001750 00000002253 12742135224 013407 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NHLINE_H
#define NHLINE_H
#include "nview.h"
class NHLine : public NView
{
public:
NHLine(NRect rect, const char* s) : NView(rect) { bgcolor = 0; };
virtual ~NHLine() { };
void setbgcolor(int colorpair) { bgcolor = colorpair; };
virtual void refresh();
protected:
int bgcolor; //цвет фона
const char* mbsym; //символ
};
#endif //NHLINE_H boinctui-2.5.0/src/mbstring.h 0000644 0001750 0001750 00000002450 13124150563 013754 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef MBSTRING_H
#define MBSTRING_H
int mbstrlen(const char* s); //вернет размер строки utf8 в СИМВОЛАХ (не байтах) без учета '\0'
char* mbstrtrunc(char* s, int slen); //обрезать до длины slen символов (не байтов) без учета \0
char* rtrim(char* s); //удалить завершающие пробелы в строке
char* ltrim(char* s); //удалить начальные пробелы в строке
#endif // MBSTRING_H
boinctui-2.5.0/src/nvline.cpp 0000644 0001750 0001750 00000002051 12742135224 013754 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include "nvline.h"
void NVLine::refresh()
{
wbkgd(win,bgcolor);
wattrset(win,getcolorpair(COLOR_WHITE,COLOR_BLACK));
if (asciilinedraw == 1)
wvline(win, '|', getheight()-0);
else
wvline(win, ACS_VLINE, getheight()-0);
NView::refresh();
}; boinctui-2.5.0/src/mbstring.cpp 0000644 0001750 0001750 00000005340 13124150563 014310 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include
#include
#include "mbstring.h"
int mbstrlen(const char* s) //вернет размер строки utf8 в СИМВОЛАХ (не байтах) без учета '\0'
{
int bsize = strlen(s); //количество байт
int result = 0; //подсчитанное кол-во символов
int nbytes = 0; //просмотренное кол-во байтов
const char* p = s;
do
{
int symlen = mblen(p,bsize-nbytes);
if (symlen <= 0)
break;
nbytes = nbytes + symlen;
result++;
p = p + symlen; //адрес начала след символа
}
while ( (*p != 0)&&(nbytes < bsize) );
return result;
}
char* mbstrtrunc(char* s, int slen) //обрезать до длины slen символов (не байтов) без учета \0
{
if (mbstrlen(s)<=slen) //обрезать не надо и так короткая
return s;
int bsize = strlen(s); //количество байт
int nbytes = 0; //просмотренное кол-во байтов
int ns = 0; //просмотренное кол-во символов
char* p = s;
do
{
int symlen = mblen(p,bsize-nbytes);
nbytes = nbytes + symlen;
ns++;
p = p + symlen;
}
while ( (*p != '\0')&&(nbytes < bsize)&&(ns < slen) );
*p = '\0'; //обрезаем
return s;
}
char* rtrim(char* s) //удалить завершающие пробелы в строке
{
if (s == NULL)
return NULL;
if (strlen(s) == 0)
return s;
char* p = s + strlen(s) - 1;
while ( p >= s)
{
if (*p == ' ')
*p = 0;
else
break;
p--;
}
return s;
}
char* ltrim(char* s) //удалить начальные пробелы в строке
{
if (s == NULL)
return NULL;
if (strlen(s) == 0)
return s;
char* p = s;
while ( *p != '\0')
{
if (*p == ' ')
p++;
else
break;
}
memmove(s, p, strlen(p));
return s;
}
boinctui-2.5.0/src/resultparse.h 0000644 0001750 0001750 00000002401 12742135224 014476 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef RESULTPARSE_H
#define RESULTPARSE_H
#include "resultdom.h"
Item* xmlparse(const char* xml, int len, std::string& errmsg); //xml строка с xml len ее размер в байтах
char* stripinvalidtag(char* xml, int len); //ГРЯЗНЫЙ ХАК нужен чтобы до парсинга удалить кривые теги
//в сообщениях вида иначе будет ошибка парсинга
#endif // RESULTPARSE_H
boinctui-2.5.0/src/nscrollbar.h 0000644 0001750 0001750 00000003474 12742135224 014301 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013,2014 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NSCROLLBAR_H
#define NSCROLLBAR_H
#include "nview.h"
class NScrollBar : public NView
{
public:
NScrollBar(NRect rect, chtype chtop = 0, chtype chbottom = 0, chtype chinactive = ACS_VLINE);
virtual ~NScrollBar() { };
void setbgcolor(int colorpair) { bgcolor = colorpair; };
virtual void refresh();
void setpos(int vmin, int vmax, int vpos1, int vpos2);
void setvisible(bool value) { visible = value; };
protected:
int bgcolor; //цвет фона
chtype chtop; //символ вверху
chtype chbottom;//символ внизу
chtype chinactive; //символ которым заполняется когда неактивный
int vmin; //минимальное значение
int vmax; //максимальное значение
int vpos1; //минимальное видимое значение
int vpos2; //максимальное видимое значение
bool visible;//true если скроллер видимый
};
#endif //NSCROLLBAR_H boinctui-2.5.0/src/addprojectform.h 0000644 0001750 0001750 00000003154 12742135224 015136 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef ADDPROJECTFORM_H
#define ADDPROJECTFORM_H
#include
#include
#include "nform.h"
#include "nstatictext.h"
#include "srvdata.h"
class AddProjectForm : public NForm
{
public:
AddProjectForm(int lines, int rows, Srv* srv, const char* projname, bool userexist);
void genfields(int& line, Item* project); //создаст массив полей
virtual void eventhandle(NEvent* ev); //обработчик событий
protected:
int emailfield;
int passwfield;
int errmsgfield;
int usernamefield;
int teamfield;
Srv* srv;
std::string projname; //имя подключаемого проекта
std::string projurl; //url подключаемого проекта
bool userexist; //true если юзер уже создан
};
#endif //ADDPROJECTFORM_H boinctui-2.5.0/src/nmenu.h 0000644 0001750 0001750 00000004730 12763755520 013270 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#ifndef NMENU_H
#define NMENU_H
#if HAVE_LIBNCURSESW == 1 && NCURSESW_HAVE_SUBDIR == 1
#include
#else
#include
#endif
#include
#include "ngroup.h"
#include "nscrollbar.h"
class NMenu : public NGroup
{
public:
NMenu(NRect rect, bool horis = false);
virtual ~NMenu();
virtual void refresh();
void additem(const char* name, const char* comment); //добавить эл-т в меню
virtual void eventhandle(NEvent* ev); //обработчик событий
void setbackground(int attr) { set_menu_back(menu, attr); wattrset(win, attr); bgattr = attr; wbkgdset(win,attr); };
void setforeground(int attr) { set_menu_fore(menu, attr); fgattr = attr; };
void postmenu() { if (!posted) {post_menu(menu); posted = true;} };
void unpostmenu() { if (posted) {unpost_menu(menu); posted = false;} };
virtual bool createsubmenu() { return false; }; //открыть субменю
virtual void destroysubmenu(); //закрыть субменю
virtual bool action() { return false; }; //вызывается при нажатии Enter
protected:
MENU* menu;
ITEM** mitems; //масив элементов
std::list itemnames; //имена эл-тов меню
std::list itemcomments; //комментарии к эл-там меню
int bgattr; //цвет текста и фона невыделенного эл-та
int fgattr; //цвет текста и фона выделенного эл-та
bool ishoris;//true если меню горизонтальное
private:
bool posted; //true после post_menu()
NScrollBar* scrollbar;
};
#endif //NMENU_H boinctui-2.5.0/src/nview.cpp 0000644 0001750 0001750 00000010142 12763755520 013623 0 ustar ss ss // =============================================================================
// This file is part of boinctui.
// http://boinctui.googlecode.com
// Copyright (C) 2012,2013 Sergey Suslov
//
// boinctui is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// boinctui is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details
// .
// =============================================================================
#include "nview.h"
#include "ngroup.h"
#include "kclog.h"
#include