From 3c5a7cd66459c97dab2790ba9a98a3cd19001521 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 12 Feb 2010 23:16:13 +0000 Subject: [PATCH] changed: upload function select file type by the extension param: multi fixed: uptime function it showed incorrect uptime time (minuts were badly calculated) git-svn-id: svn://ttmath.org/publicrep/winix/trunk@575 e52654a7-88a9-db11-a3e9-0013d4bc506e --- content/content.cpp | 2 +- content/content.h | 7 +- content/upload.cpp | 167 +++++++++++++++++++++++++++++++-------- core/item.h | 7 +- core/misc.cpp | 69 ++++++++++++++-- core/misc.h | 4 +- core/request.cpp | 11 ++- html/fun_emacs_post.html | 12 ++- html/fun_upload.html | 36 ++++----- html/fun_uptime.html | 10 ++- locale/en | 7 +- locale/pl | 10 ++- templates/item.cpp | 8 +- templates/templates.cpp | 1 + templates/templates.h | 1 + templates/uptime.cpp | 4 +- 16 files changed, 275 insertions(+), 81 deletions(-) diff --git a/content/content.cpp b/content/content.cpp index 21c069a..58ec3d9 100755 --- a/content/content.cpp +++ b/content/content.cpp @@ -476,7 +476,7 @@ void Content::ReadAdditionalInfo() void Content::PrepareUrl(Item & item) { TrimWhite(item.url); - + if( item.url.empty() ) item.url = item.subject; // if the subject is empty then the url will be corrected by CorrectUrlOnlyAllowedChar() diff --git a/content/content.h b/content/content.h index cd84895..a6a8af1 100755 --- a/content/content.h +++ b/content/content.h @@ -110,8 +110,13 @@ class Content void PostFunCreateThreadLogAndRedirect(); void PostFunCreateThread(); - void UploadSaveFile(); + bool UploadCreatePath(std::string & path); + void UploadSaveFile(const std::string & tmp_filename, const std::string & destination); + void UploadMulti(); + void UploadSingle(); + bool FunUploadCheckAbuse(); void PostFunUpload(); + std::string tmp_path, tmp_path2; bool FunCreateTicketCheckAccess(); void FunCreateTicket(); diff --git a/content/upload.cpp b/content/upload.cpp index 22ef4b5..16dc829 100755 --- a/content/upload.cpp +++ b/content/upload.cpp @@ -14,6 +14,7 @@ #include "content.h" #include "../core/request.h" #include "../core/data.h" +#include "../core/misc.h" @@ -38,37 +39,35 @@ return true; -void Content::UploadSaveFile() +bool Content::UploadCreatePath(std::string & path) { -static std::string path; -struct stat sb; - + path.clear(); request.MakePath(path); - if( stat(path.c_str(), &sb) < 0 ) + if( !request.MakeDirsOnFS() ) { - if( !request.MakeDirsOnFS() ) - { - request.status = Error::permission_denied; - return; - } + request.status = Error::permission_denied; + return false; } +return true; +} - path += '/'; - path += request.item.url; - const std::string & tmp_filename = request.post_file_table.begin()->second.tmp_filename; - if( rename(tmp_filename.c_str(), path.c_str()) == 0 ) + + +void Content::UploadSaveFile(const std::string & tmp_filename, const std::string & destination) +{ + if( rename(tmp_filename.c_str(), destination.c_str()) == 0 ) { - log << log1 << "Content: uploaded a new file: " << path << logend; + log << log1 << "Content: uploaded a new file: " << destination << logend; } else { int err = errno; - // !! skasowac takze plik z bazy danych - log << log1 << "Content: can't move the tmp file from: " << tmp_filename << ", to: " << path << ", "; + // !! skasowac takze plik z bazy danych? + log << log1 << "Content: can't move the tmp file from: " << tmp_filename << ", to: " << destination << ", "; log.SystemErr(err); log << logend; @@ -78,7 +77,120 @@ struct stat sb; +bool Content::FunUploadCheckAbuse() +{ + if( !CheckRebus() ) + { + request.status = Error::incorrect_rebus; + request.session->done = Done::added_thread; + request.session->done_status = Error::incorrect_rebus; + + return false; + } + CheckGetPostTimes(4); + + if( request.session->spam_score > 0 ) + { + request.status = Error::spam; + request.session->done = Done::added_thread; + request.session->done_status = Error::spam; + + log << log1 << "Content: ignoring due to suspected spamming" << logend; + return false; + } + +return true; +} + + + + + + +void Content::UploadMulti() +{ + request.item.Clear(); // clearing and setting date + request.item.parent_id = request.dir_table.back()->id; + request.item.type = Item::file; + request.item.privileges = 0644; // !! tymczasowo + SetUser(request.item); + + if( !UploadCreatePath(tmp_path) ) + return; + + tmp_path2 = tmp_path; // remember the path + + PostFileTable::iterator i = request.post_file_table.begin(); + + for( ; i != request.post_file_table.end() ; ++i) + { + const char * file_name = i->second.filename.c_str(); + + request.item.subject = file_name; + request.item.url = file_name; + request.item.static_auth = SelectFileType(file_name); + + PrepareUrl(request.item); + PostFunEmacsAdd(); // always adding a new item + + if( request.session->done_status == Error::ok ) + { + tmp_path += '/'; + tmp_path += request.item.url; // item.url could have been changed + + UploadSaveFile(i->second.tmp_filename, tmp_path); + tmp_path = tmp_path2; // restoring the oryginal path + } + } + + RedirectToLastDir(); +} + + +void Content::UploadSingle() +{ + std::string * new_subject = request.PostVar("subject"); + std::string * new_url = request.PostVar("url"); + bool has_subject = (new_subject && (*new_subject)[0] != 0 ); + bool has_url = (new_url && (*new_url)[0] != 0 ); + + ReadItem(request.item, Item::file); // ReadItem() changes the url if it is empty + request.item.privileges = 0644; // !! tymczasowo + + const char * file_name = request.post_file_table.begin()->second.filename.c_str(); + request.item.static_auth = SelectFileType(file_name); + + if( !has_subject ) + request.item.subject = file_name; + + if( !has_url ) + { + request.item.url = file_name; + PrepareUrl(request.item); + } + + PostFunEmacsAdd(); // always adding a new item + + + if( request.session->done_status == Error::ok ) + { + const std::string & tmp_filename = request.post_file_table.begin()->second.tmp_filename; + + if( !UploadCreatePath(tmp_path) ) + return; + + tmp_path += '/'; + tmp_path += request.item.url; // item.url could have been changed + + UploadSaveFile(tmp_filename, tmp_path); + } + + if( request.session->done_status == Error::ok ) + RedirectTo(request.item); +} + +// !! dodac usuwanie plikow statycznych przez rm void Content::PostFunUpload() { if( !FunUploadCheckAccess() ) @@ -89,23 +201,14 @@ void Content::PostFunUpload() request.status = Error::permission_denied; return; } - - // !! moze request.session->done_status trzeba ustawic na Error::ok na poczatku? (i podobnie w innych metodach, mkdir, emacs ...) - ReadItem(request.item, Item::file); - // !! sprawdzanie rebusa? + if( !FunUploadCheckAbuse() ) + return; - // !! tutaj w zaleznosci od rozszerzenia dobrac odpowiedni static_auth - request.item.static_auth = Item::static_other; - - PostFunEmacsAdd(); // always adding a new item - - - if( request.session->done_status == Error::ok ) - UploadSaveFile(); - - if( request.session->done_status == Error::ok ) - RedirectTo(request.item); + if( request.post_file_table.size() > 1 ) + UploadMulti(); + else + UploadSingle(); } diff --git a/core/item.h b/core/item.h index 2f5d766..7334dbe 100755 --- a/core/item.h +++ b/core/item.h @@ -72,9 +72,10 @@ long content_id; // the direct url is the same but the prefix is: base_url_static_auth enum StaticAuth { - static_none = 0, - static_image = 1, - static_other = 2 + static_none = 0, + static_image = 1, /* png, gif, jpg - only types available to render by a web browser*/ + static_document = 2, /* pdf doc xls txt */ + static_other = 3 }; diff --git a/core/misc.cpp b/core/misc.cpp index 5b032d5..d701efe 100755 --- a/core/misc.cpp +++ b/core/misc.cpp @@ -50,6 +50,9 @@ return false; } + +// this function checks how many dots there are in the url +// if there are more than one (last) dot then the first dots will be changed into '_' void CorrectUrlDots(std::string & url) { size_t i = url.size(); @@ -73,7 +76,7 @@ void CorrectUrlChars(std::string & url) { std::string::iterator i; - for(i = url.begin(); i!=url.end() ; ++i) + for(i=url.begin(); i != url.end() ; ++i) { if( !CorrectUrlChar(*i) ) { @@ -215,6 +218,9 @@ void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in) std::string::const_iterator i; int was_enter = 0; // how many enteres there were before + if( in.empty() ) + return; + out << "

"; // skipping first new line characters @@ -485,15 +491,15 @@ return false; } -bool EqualNoCase(const char * short_str, const char * long_str) +bool EqualNoCase(const char * str1, const char * str2) { - while( *short_str && *long_str && ToSmall(*short_str) == ToSmall(*long_str) ) + while( *str1 && *str2 && ToSmall(*str1) == ToSmall(*str2) ) { - ++short_str; - ++long_str; + ++str1; + ++str2; } - if( *short_str == 0 && *long_str == 0 ) + if( *str1 == 0 && *str2 == 0 ) return true; return false; @@ -555,3 +561,54 @@ bool IsFile(const std::string & file) { return IsFile(file.c_str()); } + + +// if there is not an extension it returns a pointer to the last '\0' character +const char * GetFileExt(const char * name) +{ +size_t i, ilast; + + // looking for the end of the name + for(i=0 ; name[i] != 0 ; ++i); + + if( i == 0 ) + return name; // ops, the name is empty + + // remember the end of the string + ilast = i; + + // looking for the last dot + for(--i ; i>0 && name[i] != '.' ; --i); + + if( name[i] != '.' ) + return name + ilast; // ops, there is not a dot + + // the extensions starts from i+1 + // and can be empty (if the last character is a dot) + +return name + i + 1; +} + + +Item::StaticAuth SelectFileType(const char * file_name) +{ + const char * ext = GetFileExt(file_name); + + // as an image we're using only those types which can be rendered + // by a web browser + if( EqualNoCase(ext, "jpg") || + EqualNoCase(ext, "gif") || + EqualNoCase(ext, "png") ) + return Item::static_image; + + if( EqualNoCase(ext, "pdf") || + EqualNoCase(ext, "doc") || + EqualNoCase(ext, "xls") || + EqualNoCase(ext, "txt") || + EqualNoCase(ext, "ods") || + EqualNoCase(ext, "odt") ) + return Item::static_document; + +return Item::static_other; +} + diff --git a/core/misc.h b/core/misc.h index 6686201..c3ea832 100755 --- a/core/misc.h +++ b/core/misc.h @@ -57,12 +57,14 @@ const char * ToStr(int value); bool IsSubString(const char * short_str, const char * long_str); bool IsSubStringNoCase(const char * short_str, const char * long_str); -bool EqualNoCase(const char * short_str, const char * long_str); +bool EqualNoCase(const char * str1, const char * str2); bool ValidateEmail(const std::string & email); bool IsFile(const char * file); bool IsFile(const std::string & file); +const char * GetFileExt(const char * name); +Item::StaticAuth SelectFileType(const char * file_name); #endif diff --git a/core/request.cpp b/core/request.cpp index 85b7d6c..aa42d1d 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -911,6 +911,7 @@ void Request::MakePath(std::string & path) } } + bool Request::MakeDirsOnFS() { size_t i; @@ -922,11 +923,13 @@ bool Request::MakeDirsOnFS() path += '/'; path += dir_table[i]->url; - if( mkdir(path.c_str(), 0755) < 0 ) + if( !IsFile(path.c_str()) ) { - // oops - log << log1 << "Request: can't create the directory on fs: " << path << logend; - return false; + if( mkdir(path.c_str(), 0755) < 0 ) + { + log << log1 << "Request: can't create the directory on fs: " << path << logend; + return false; + } } } diff --git a/html/fun_emacs_post.html b/html/fun_emacs_post.html index d2c43e0..14a6b9b 100755 --- a/html/fun_emacs_post.html +++ b/html/fun_emacs_post.html @@ -1,9 +1,13 @@ -[if-one mount_type_is_cms]

{form_emacs_content_cms}

[end] -[if-one mount_type_is_thread]

{form_emacs_content_thread}

[end] -[if-one mount_type_is_ticket]

{form_emacs_content_ticket}

[end] +[is winix_function_is "upload"] +

{upload_content}

+[else] + [if-one mount_type_is_cms]

{form_emacs_content_cms}

[end] + [if-one mount_type_is_thread]

{form_emacs_content_thread}

[end] + [if-one mount_type_is_ticket]

{form_emacs_content_ticket}

[end] +[end] - +

{form_emacs_content_type}

diff --git a/html/fun_upload.html b/html/fun_upload.html index dd75c1e..1e227fa 100755 --- a/html/fun_upload.html +++ b/html/fun_upload.html @@ -1,4 +1,4 @@ -[if-one item_is]

{edit}

[else]

{add}

[end] +

{upload_header}

[include "err_abuse.html"] @@ -6,30 +6,29 @@
{upload_form_legend} - + [is winix_function_param_is "multi"] +

{upload_form_file_multi}

+ + + + + - [if-one mount_type_is_cms] + [else] + +

{upload_form_file}

+ +

{title}:

-

{url}:

+

{suggested_url}:

- [end] - [if-one mount_type_is_thread] - [is mount_thread_is "subject"] -

{title}:

- - -

{url}:

- - [end] + [include "fun_emacs_post.html"] + [end] - - -

{upload_content}:

- [if-no user_logged]

{nick}:

@@ -39,8 +38,7 @@ [end] - - +
diff --git a/html/fun_uptime.html b/html/fun_uptime.html index 7c4557f..ebca5d9 100755 --- a/html/fun_uptime.html +++ b/html/fun_uptime.html @@ -1,14 +1,16 @@

{uptime_header}

-

[winix_cur_time], {uptime_up} +

{uptime_current_time}: [winix_cur_time]
+{uptime_up}: [if-one uptime_more_than_one_day] - [uptime_days] {uptime_days}, + [uptime_days] {uptime_days} [else] - [uptime_hours], + [uptime_hours] [end] +
-[winix_users_logged] {uptime_users} +{uptime_users}: [winix_users_logged]

diff --git a/locale/en b/locale/en index 50d1462..a21e8c7 100755 --- a/locale/en +++ b/locale/en @@ -146,8 +146,12 @@ ticket_info_expected = Expected in ticket_info_progress = Progress ticket_reply_in_this_thread = Replay in this thread +upload_header = Upload a file +upload_form_file = Browse for a file +upload_form_file_multi = Browse for files upload_form_legend = Upload form upload_content = File description +upload_submit = Upload who_header = Sessions who_table_index = Ind. @@ -169,7 +173,8 @@ admin_upload = Upload an image or file (upload) login_header = Login uptime_header = Uptime -uptime_up = up +uptime_current_time = current time +uptime_up = system running for uptime_users = users uptime_days = days diff --git a/locale/pl b/locale/pl index 4e5b89f..0a9ed03 100755 --- a/locale/pl +++ b/locale/pl @@ -145,8 +145,13 @@ ticket_info_expected = Oczekiwany w ticket_info_progress = Postęp prac ticket_reply_in_this_thread = Odpowiedz w tym wątku +upload_header = Prześlij plik +upload_form_file = Wybierz plik +upload_form_file_multi = Wybierz pliki upload_form_legend = Formularz do wysłania pliku upload_content = Opis pliku +upload_submit = Wyślij + who_header = Lista sesji who_table_index = L.p. @@ -166,8 +171,9 @@ admin_upload = Wy login_header = Logowanie -uptime_header = Uptime -uptime_up = uruchomiony przez +uptime_header = Czas pracy systemu +uptime_current_time = aktualna godzina +uptime_up = system uruchomiony przez uptime_users = zalogowanych użytkowników uptime_days = dni diff --git a/templates/item.cpp b/templates/item.cpp index 91d8997..d76b6a9 100755 --- a/templates/item.cpp +++ b/templates/item.cpp @@ -107,7 +107,8 @@ void item_print_content(std::ostringstream & out, const std::string & content, I else if( content_type == Item::ct_bbcode ) { - out << content; // !! tutaj bedzie parsowanie bbcodu i tworzenie odpowiadajacego mu html-a + //out << content; // !! tutaj bedzie parsowanie bbcodu i tworzenie odpowiadajacego mu html-a + out << "bbcode is not implemented yet"; } else if( content_type == Item::ct_raw ) @@ -117,6 +118,11 @@ void item_print_content(std::ostringstream & out, const std::string & content, I } +void item_content_is_empty(Info & i) +{ + i.result = request.item.content.empty(); +} + void item_print_content(Info & i) { item_print_content(i.out, request.item.content, request.item.content_type); diff --git a/templates/templates.cpp b/templates/templates.cpp index 881990e..33a64f6 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -185,6 +185,7 @@ void Templates::CreateFunctions() functions.Insert("item_id", item_id); functions.Insert("item_subject", item_subject); functions.Insert("item_subject_noescape", item_subject_noescape); + functions.Insert("item_content_is_empty", item_content_is_empty); functions.Insert("item_content", item_content); functions.Insert("item_content_noescape", item_content_noescape); functions.Insert("item_content_type_is", item_content_type_is); diff --git a/templates/templates.h b/templates/templates.h index 2b2e9d0..ca6ce6f 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -103,6 +103,7 @@ namespace TemplatesFunctions void item_content(Info & i); void item_content_noescape(Info & i); void item_content_type_is(Info & i); + void item_content_is_empty(Info & i); void item_print_content(std::ostringstream & out, const std::string & content, Item::ContentType content_type); void item_print_content(Info & i); void item_privileges(Info & i); diff --git a/templates/uptime.cpp b/templates/uptime.cpp index cf4f001..ec94e30 100755 --- a/templates/uptime.cpp +++ b/templates/uptime.cpp @@ -44,9 +44,9 @@ char buf[50]; time_t hour = min / 60; if( hour == 0 && min == 0 ) - sprintf(buf, "%d:%02d:%02d", (int)hour, (int)min, (int)sec); + sprintf(buf, "%d:%02d:%02d", (int)hour, (int)(min%60), (int)(sec%60)); else - sprintf(buf, "%d:%02d", (int)hour, (int)min); + sprintf(buf, "%d:%02d", (int)hour, (int)(min%60)); i.out << buf; }