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:
@@ -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
|
||||
|
Reference in New Issue
Block a user