fixed: UGContainer<Type> used a std::vector<Type> and when a new item was inserted

then current iterators (and pointers) were invalidated
         now we are using std::vector<Type*>
         this caused some crashes when a new user was added by 'adduser' winix function
added:   plugin 'export' is able to upload files on a remote server now
         (not finished yet)
changed: Thumb class is now called: Image
         and we are able to resize images too
         (some new options in the config and in mount points)
added:   some new plugin messages



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@764 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2011-09-13 06:08:34 +00:00
parent 72be443414
commit 39923d6617
58 changed files with 2258 additions and 654 deletions

View File

@@ -10,7 +10,6 @@
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <curl/curl.h>
#include <string.h>
#include "exportthread.h"
#include "core/log.h"
@@ -28,6 +27,9 @@ ExportThread::ExportThread()
{
exp_thread = 0;
utf8 = false;
browser_name = "Winix Export";
conn_timeout = 5;
conn_max_errors = 3;
}
@@ -38,12 +40,15 @@ void ExportThread::SetUTF8(bool use_utf8)
}
void ExportThread::SetBaseUrl(const std::wstring & url)
{
base_url = url;
}
void ExportThread::AddMessage(const Message & message)
{
message_tab.insert(message_tab.end(), message);
WakeUpThread();
log << log1 << "yes ser" << logend;
}
@@ -64,8 +69,6 @@ void ExportThread::AddMessage(int type, const std::wstring & url, const std::wst
// objects are locked
bool ExportThread::SignalReceived()
{
log << log1 << "------------- a ---------------" << logend;
return !message_tab.empty();
}
@@ -79,7 +82,6 @@ MessageTab::iterator i;
bool end;
Lock();
log << log1 << "------------- swinka ---------------" << logend;
i = message_tab.begin();
Unlock();
@@ -90,7 +92,19 @@ bool end;
if( i != message_tab.end() )
{
message_work = *i;
message_tab.erase(i++);
Unlock();
DoMessage();
Lock();
// although there was Unlock() used we can use the same iterator 'i' here
// it will *not* be invalidated (MessageTab is a std::list)
// and we are deleting only here
i->errors = message_work.errors;
if( message_work.can_remove )
message_tab.erase(i++);
end = false;
}
else
@@ -98,11 +112,8 @@ bool end;
end = true;
}
WaitForSignalSleep(5);
Unlock();
if( !end )
DoMessage();
}
while( !end && !IsExitSignal() );
}
@@ -113,24 +124,45 @@ bool end;
// current message we have in 'message_work'
void ExportThread::DoMessage()
{
Lock();
bool sent_ok = false;
if( utf8 )
Ezc::WideToUTF8(message_work.url, url_a);
Convert(message_work.url, url_a);
if( message_work.type == WINIX_PL_EXPORT_TYPE_CREATE_FILE )
{
if( Fetch(url_a.c_str()) )
{
ChangeAdresses(buffer);
if( Put() )
sent_ok = true;
}
}
else
AssignString(message_work.url, url_a);
{
if( Put() )
sent_ok = true;
}
Unlock();
Fetch(url_a.c_str());
if( sent_ok )
{
message_work.can_remove = true;
}
else
{
message_work.errors += 1;
message_work.can_remove = false;
Lock();
log << log1 << "sciagnalem takie cos ---------------------------------------------------" << logend;
if( message_work.errors > conn_max_errors )
{
message_work.can_remove = true;
log << "rozmiar: " << buffer.size() << logend;
log << log1 << "koniec takiego cosia ---------------------------------------------------" << logend << logsave;
Unlock();
Lock();
log << log1 << "Export: too many errors for uploading " << message_work.path << " (skipping)" << logend << logsave;
Unlock();
}
}
}
@@ -142,11 +174,7 @@ void ExportThread::DoMessage()
// objects are not locked
bool ExportThread::Fetch(const char * url)
{
CURL * curl;
CURLcode res;
long code;
curl = curl_easy_init();
CURL * curl = curl_easy_init();
if( !curl )
{
@@ -156,26 +184,29 @@ long code;
return false;
}
exp_thread = this;
error_buf[0] = 0;
exp_thread = this;
buffer.clear();
/*
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); // the http code will be from the last request
*/
//curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, StaticSaveFunction);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Winix");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, StaticSaveFunction);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USERAGENT, browser_name.c_str());
curl_easy_setopt(curl, CURLOPT_TIMEOUT, conn_timeout);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buf);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 20);
CURLcode res = curl_easy_perform(curl);
//long code; // http code
//curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
curl_easy_cleanup(curl);
if( res!=0 || code!=200 )
if( res != 0 )
{
Lock();
log << log1 << "Ezport: error: operation result: " << (int)res << ", http code: " << code << logend;
log << log1 << "Export: download failed: " << error_buf << logend << logsave;
Unlock();
return false;
}
@@ -201,14 +232,274 @@ size_t ExportThread::SaveFunction(char * ptr, size_t size, size_t nmemb, void *u
if( len > 0 )
buffer.append(ptr, len);
Lock();
log << log1 << "odebralem cosik: size: " << size << ", nmemb: " << nmemb << logend;
Unlock();
return len;
}
// second thread
// objects are not locked
void ExportThread::Convert(const std::wstring & in, std::string & out, bool clear)
{
Lock();
if( utf8 )
Ezc::WideToUTF8(in, out, clear);
else
AssignString(in, out, clear);
Unlock();
}
// second thread
// objects are not locked
bool ExportThread::Put()
{
FILE * file = 0;
if( message_work.type == WINIX_PL_EXPORT_TYPE_CREATE_FILE_STATIC )
{
Convert(message_work.url, local_path);
file = fopen(local_path.c_str(), "r");
if( !file )
{
Lock();
log << log1 << "Export: I cannot open the file: " << local_path << logend;
Unlock();
return false;
}
else
{
log << log3 << "Export: sending a static file: " << local_path << logend;
}
}
CURL * curl = curl_easy_init();
if( !curl )
{
Lock();
log << log1 << "Export: I can't use curl (sending)" << logend;
Unlock();
if( file )
fclose(file);
return false;
}
exp_thread = this;
error_buf[0] = 0;
buffer_read_index = 0;
ftp_server = "ftp://";
Convert(message_work.ftp_server, ftp_server, false);
Convert(message_work.path, ftp_server, false);
Convert(message_work.ftp_login, ftp_login);
Convert(message_work.ftp_pass, ftp_pass);
curl_easy_setopt(curl, CURLOPT_URL, ftp_server.c_str());
curl_easy_setopt(curl, CURLOPT_USERNAME, ftp_login.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, ftp_pass.c_str());
curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 2);
curl_easy_setopt(curl, CURLOPT_USERAGENT, browser_name.c_str());
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, conn_timeout);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buf);
if( file )
{
curl_easy_setopt(curl, CURLOPT_READDATA, file);
}
else
{
curl_easy_setopt(curl, CURLOPT_READFUNCTION, StaticReadFunction);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer.size());
}
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if( file )
fclose(file);
if( res != 0 )
{
Lock();
log << log1 << "Export: upload failed: " << error_buf << " (" << ftp_server << ")" << logend << logsave;
Unlock();
return false;
}
else
{
Lock();
log << log2 << "Export: uploaded: " << ftp_server << logend << logsave;
Unlock();
}
return true;
}
size_t ExportThread::StaticReadFunction(char * ptr, size_t size, size_t nmemb, void *userdata)
{
if( exp_thread )
return exp_thread->ReadFunction(ptr, size, nmemb, userdata);
return 0;
}
size_t ExportThread::ReadFunction(char * ptr, size_t size, size_t nmemb, void *userdata)
{
size_t max_len = size * nmemb;
size_t i;
for(i=0 ; i<max_len && buffer_read_index < buffer.size() ; ++i, ++buffer_read_index )
{
ptr[i] = buffer[buffer_read_index];
}
return i;
}
void ExportThread::CreateBaseUrl(std::string & buf)
{
buf = "http://";
Convert(base_url, buf, false);
}
void ExportThread::ChangeAdresses(std::string & buf)
{
// !! mozna lock skasowac jesli loger nie bedzie uzywany
Lock();
ChangeAdressesThumb(buf);
CreateBaseUrl(look_for_url);
look_for_url += "/static";
Convert(message_work.src_dir, look_for_url, false);
Convert(message_work.http_server, repl_url);
repl_url += "/static/";
log << log1 << "zamiana: |" << look_for_url << "|, na: |" << repl_url << "|" << logend << logsave;
ReplaceString(buf, look_for_url, repl_url);
/*
CreateBaseUrl(look_for_url);
look_for_url += "/common/";
Convert(message_work.http_server, repl_url);
repl_url += "/common/";
log << log1 << "zamiana: |" << look_for_url << "|, na: |" << repl_url << "|" << logend << logsave;
ReplaceString(buf, look_for_url, repl_url);
*/
CreateBaseUrl(look_for_url);
Convert(message_work.src_dir, look_for_url, false);
Convert(message_work.http_server, repl_url);
repl_url += "/";
log << log1 << "zamiana: |" << look_for_url << "|, na: |" << repl_url << "|" << logend << logsave;
ReplaceString(buf, look_for_url, repl_url);
NoLastSlash(look_for_url);
Convert(message_work.http_server, repl_url);
look_for_url += '\"';
repl_url += '\"';
log << log1 << "zamiana: |" << look_for_url << "|, na: |" << repl_url << "|" << logend << logsave;
ReplaceString(buf, look_for_url, repl_url);
Convert(message_work.src_dir, look_for_url);
repl_url = '/';
log << log1 << "zamiana: |" << look_for_url << "|, na: |" << repl_url << "|" << logend << logsave;
ReplaceString(buf, look_for_url, repl_url);
NoLastSlash(look_for_url);
look_for_url += '\"';
repl_url = "/\"";
log << log1 << "zamiana: |" << look_for_url << "|, na: |" << repl_url << "|" << logend << logsave;
ReplaceString(buf, look_for_url, repl_url);
Unlock();
}
void ExportThread::ChangeAdressesThumb(std::string & buf)
{
size_t i;
CreateBaseUrl(look_for_url);
Convert(message_work.src_dir, look_for_url, false);
for(i=0 ; i<buf.size() ; ++i)
{
if( IsSubStringp(look_for_url.c_str(), &buf[i]) )
{
i += look_for_url.size() - 1; // without skipping the last slash
if( HasThumbInAdress(buf, i) )
{
if( i <= buf.size() )
buf.insert(i, "/download"); //!! do konfiga
}
}
}
}
bool ExportThread::HasThumbInAdress(std::string & buf, size_t i)
{
const char * thumb1 = "/-/thumb";
const char * thumb2 = "/download/thumb";
size_t len1 = strlen(thumb1);
size_t len2 = strlen(thumb2);
for( ; i<buf.size() ; ++i)
{
if( IsSubStringp(thumb1, &buf[i]) )
{
buf.erase(i, len1);
return true;
}
if( IsSubStringp(thumb2, &buf[i]) )
{
buf.erase(i, len2);
return true;
}
if( buf[i] == 10 || buf[i] == '"' || buf[i] == ' ' || buf[i] == '\t' ||
buf[i] == '>' ||buf[i] == '<' )
{
return false;
}
}
return false;
}
} // namespace