changed organization of static files

removed: item.auth item.auth_path
added:   item.file_path, item.file_fs, item.file_type
now the path to a static file is a relative path
added: thumbnails (not finished yet)
fixed: db didn't correctly return the number of deleted items /DelItem() method/




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@696 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2010-12-10 21:07:01 +00:00
parent 9b29cce1a4
commit 36c8822e6c
41 changed files with 435 additions and 364 deletions

View File

@@ -7,6 +7,7 @@
*
*/
#include "wand/MagickWand.h"
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
@@ -142,17 +143,24 @@ bool App::Init()
templates.ReadTemplates();
// init notify after templates (it uses locales from templates)
system.notify.ReadTemplates();
session_manager.LoadSessions();
CreateStaticTree();
MagickWandGenesis();
plugin.Call(WINIX_PLUGIN_INIT);
return true;
}
void App::Uninit()
{
MagickWandTerminus();
}
void App::Close()
{
@@ -165,30 +173,14 @@ void App::Close()
bool App::BaseUrlRedirect()
{
if( request.role == Request::responder )
{
if( config.base_url_http_host.empty() )
return false;
if( Equal(config.base_url_http_host.c_str(), request.env_http_host) )
return false;
if( config.base_url_http_host.empty() )
return false;
if( Equal(config.base_url_http_host.c_str(), request.env_http_host) )
return false;
request.redirect_to = config.base_url;
AssignString(request.env_request_uri, request.redirect_to, false);
}
else
{
// authorizer
if( config.base_url_auth_http_host.empty() )
return false;
if( Equal(config.base_url_auth_http_host.c_str(), request.env_http_host) )
return false;
request.redirect_to = config.base_url_auth;
AssignString(request.env_request_uri, request.redirect_to, false);
}
request.redirect_to = config.base_url;
AssignString(request.env_request_uri, request.redirect_to, false);
log << log3 << "RC: BaseUrlRedirect from: " << request.env_http_host << logend;
@@ -294,7 +286,7 @@ bool sent = false;
return;
if( request.is_item && request.item.auth == Item::auth_none &&
if( request.is_item && request.item.file_type == WINIX_ITEM_FILETYPE_NONE &&
request.item.content_type == Item::ct_raw && request.status == WINIX_ERR_OK && request.function )
{
if( request.function == &functions.fun_cat )
@@ -669,7 +661,7 @@ bool App::CanSendContent(Header header)
// if there is a redirect or a file to send then we do not send a content
return false;
if( header == h_200 && request.role == Request::authorizer && request.is_item && request.item.auth != Item::auth_none )
if( header == h_200 && request.role == Request::authorizer && request.is_item && request.item.file_type != WINIX_ITEM_FILETYPE_NONE )
// if there is an item and the item has 'file' storage we do not send a content
return false;
@@ -1063,3 +1055,21 @@ sigset_t set;
void App::CreateStaticTree()
{
if( config.upload_dir.empty() )
{
log << log1 << "App: config: upload_dir not set, you are not allowed to upload static content" << logend;
return;
}
CreateDirs(L"/", config.upload_dir.c_str(), config.upload_dirs_chmod);
CreateDirs(config.upload_dir.c_str(), L"simplefs/normal", config.upload_dirs_chmod);
CreateDirs(config.upload_dir.c_str(), L"simplefs/thumb", config.upload_dirs_chmod);
CreateDirs(config.upload_dir.c_str(), L"hashfs/normal", config.upload_dirs_chmod);
CreateDirs(config.upload_dir.c_str(), L"hashfs/thumb", config.upload_dirs_chmod);
CreateDirs(config.upload_dir.c_str(), L"tmp", config.upload_dirs_chmod);
}

View File

@@ -49,6 +49,7 @@ public:
bool InitFCGI();
bool DropPrivileges();
bool Init();
void Uninit();
void Start();
void Close();
void LogUserGroups();
@@ -166,6 +167,8 @@ private:
static void * SpecialThreadForSignals(void*);
void FetchPageOnExit();
void CreateStaticTree();
// !! dodac do session managera?
time_t last_sessions_save;
};

View File

@@ -109,10 +109,13 @@ void Config::AssignValues(bool stdout_is_closed)
log_db_query = Bool(L"log_db_query", false);
log_plugin_call = Bool(L"log_plugin_call", false);
post_file_max = Size(L"post_file_max", 8388608); // 8 MB
auth_simplefs_dir = Text(L"auth_simplefs_dir");
auth_hashfs_dir = Text(L"auth_hashfs_dir");
auth_tmp_dir = Text(L"auth_tmp_dir");
post_file_max = Size(L"post_file_max", 8388608); // 8 MB
upload_dir = Text(L"upload_dir");
upload_dirs_chmod = Int(L"upload_dirs_chmod", 0750);
upload_files_chmod = Int(L"upload_files_chmod", 0640);
create_thumb = Bool(L"create_thumb", false); // !! will be true
thumb_cx = Size(L"thumb_cx", 150);
thumb_cy = Size(L"thumb_cy", 150);
templates_dir = Text(L"templates_dir");
templates_dir_default = Text(L"templates_dir_default");
@@ -131,13 +134,11 @@ void Config::AssignValues(bool stdout_is_closed)
base_server = Text(L"base_server");
base_url = Text(L"base_url");
base_url_auth = Text(L"base_url_auth");
base_url_static = Text(L"base_url_static");
base_url_common = Text(L"base_url_common");
NoLastSlash(base_server);
NoLastSlash(base_url);
NoLastSlash(base_url_auth);
NoLastSlash(base_url_static);
NoLastSlash(base_url_common);
@@ -187,7 +188,6 @@ void Config::AssignValues(bool stdout_is_closed)
void Config::SetAdditionalVariables()
{
SetHttpHost(base_url, base_url_http_host);
SetHttpHost(base_url_auth, base_url_auth_http_host);
if( html_filter_orphans_lang_str == "pl" )
html_filter_orphans_lang = HTMLFilter::lang_pl;

View File

@@ -186,13 +186,28 @@ public:
// 0 - not used
size_t post_file_max;
// directories for static files
std::wstring auth_simplefs_dir;
std::wstring auth_hashfs_dir;
// directory for static files
std::wstring upload_dir;
// temporary directory for static content used by the upload function
// should be on the same partition as auth_simplefs_dir and auth_hashfs_dir
std::wstring auth_tmp_dir;
// chmod of newly created directories (under upload_dir)
// default: 0750
int upload_dirs_chmod;
// chmod of newly created files (under upload_dir)
// default: 0640
int upload_files_chmod;
// create a thumbnail from an image
// default: false (!!will be true)
bool create_thumb;
// width of thumbnails
// default: 150
size_t thumb_cx;
// height of thumbnails
// default: 150
size_t thumb_cy;
// locale: en, pl
// default: en
@@ -210,9 +225,6 @@ public:
// the main address of the site (e.g. http://www.someserver.com)
std::wstring base_url;
// static content authorized by winix
std::wstring base_url_auth;
// static content not authorized by winix
std::wstring base_url_static;
@@ -265,7 +277,6 @@ public:
// set by SetAdditionalVariables()
// without the first part http:// (or https://) or the whole string is empty
std::wstring base_url_http_host;
std::wstring base_url_auth_http_host;
Config();

View File

@@ -54,10 +54,13 @@ void Item::Clear()
content_id = -1;
auth = auth_none;
auth_path.clear();
file_path.clear();
file_fs = -1;
file_type = WINIX_ITEM_FILETYPE_NONE;
html_template.clear();
SetDateToNow();
}

View File

@@ -13,6 +13,11 @@
#include <string>
#define WINIX_ITEM_FILETYPE_NONE 0
#define WINIX_ITEM_FILETYPE_IMAGE 1
#define WINIX_ITEM_FILETYPE_DOCUMENT 2
#define WINIX_ITEM_FILETYPE_UNKNOWN 3
struct Item
{
@@ -67,17 +72,25 @@ long default_item;
// external static file authorized by winix
/*
enum Auth
{
auth_none = 0, /* there is not an external file */
auth_image = 1, /* png, gif, jpg - only types available to render by a web browser*/
auth_document = 2, /* pdf doc xls txt */
auth_other = 3 /* other file */
auth_none = 0, // there is not an external file
auth_image = 1, // png, gif, jpg - only types available to render by a web browser
auth_document = 2, // pdf doc xls txt
auth_other = 3 // other file
};
Auth auth;
std::wstring auth_path; // path to a file (if auth!=auth_none)
*/
// static file (if exists)
std::wstring file_path; // relative file path
int file_fs; // file system type where the file was saved
int file_type; // file type (none, image, doc, etc)
std::wstring html_template;

View File

@@ -12,6 +12,7 @@
#include "misc.h"
#include "log.h"
#include "templates/templates.h"
#include "utf8.h"
int Toi(const std::string & str, int base)
@@ -621,11 +622,12 @@ bool IsFile(const wchar_t * file)
struct stat sb;
static std::string afile;
AssignString(file, afile); // or it can be UTF-8 used
Ezc::WideToUTF8(file, afile);
return (stat(afile.c_str(), &sb) == 0);
}
bool IsFile(const std::wstring & file)
{
return IsFile(file.c_str());
@@ -638,17 +640,11 @@ static std::string adir;
if( !IsFile(dir) )
{
AssignString(dir, adir);
Ezc::WideToUTF8(dir, adir);
if( mkdir(adir.c_str(), priv) < 0 )
{
log << log1 << "Can't create a directory on fs: " << adir;
if( !Equal(dir, adir.c_str()) )
log << " original name was: " << dir;
log << logend;
log << log1 << "Can't create a directory on fs: " << adir << logend;
return false;
}
}
@@ -666,7 +662,7 @@ bool CreateDir(const std::wstring & dir, int priv)
// creating directories (can be more than one)
// 'dirs' can begin with a slash (will be skipped)
bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv)
bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv, bool skip_last)
{
static std::wstring temp;
const wchar_t * p = dirs;
@@ -688,11 +684,12 @@ const wchar_t * p = dirs;
break;
// taking the name
for( ; *p && *p!='/' ; ++p )
for( ; *p!=0 && *p!='/' ; ++p )
temp += *p;
if( !CreateDir(temp.c_str(), priv) )
return false;
if( !skip_last || *p!=0 )
if( !CreateDir(temp.c_str(), priv) )
return false;
temp += '/';
}
@@ -702,9 +699,9 @@ return true;
bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv)
bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv, bool skip_last)
{
return CreateDirs(base_dir.c_str(), dirs.c_str(), priv);
return CreateDirs(base_dir.c_str(), dirs.c_str(), priv, skip_last);
}
@@ -736,8 +733,8 @@ bool CopyFile(const wchar_t * src, const wchar_t * dst)
static std::string asrc, adst;
FILE * in, * out;
AssignString(src, asrc);
AssignString(dst, adst);
Ezc::WideToUTF8(src, asrc);
Ezc::WideToUTF8(dst, adst);
in = fopen(asrc.c_str(), "rb");
@@ -778,7 +775,7 @@ bool RemoveFile(const wchar_t * file)
{
static std::string afile;
AssignString(file, afile);
Ezc::WideToUTF8(file, afile);
return unlink(afile.c_str()) == 0;
}
@@ -795,8 +792,8 @@ bool RenameFile(const wchar_t * from, const wchar_t * to)
{
static std::string afrom, ato;
AssignString(from, afrom);
AssignString(to, ato);
Ezc::WideToUTF8(from, afrom);
Ezc::WideToUTF8(to, ato);
return rename(afrom.c_str(), ato.c_str()) == 0;
}
@@ -835,7 +832,7 @@ return name + i + 1;
}
Item::Auth SelectFileType(const wchar_t * file_name)
int SelectFileType(const wchar_t * file_name)
{
const wchar_t * ext = GetFileExt(file_name);
@@ -849,7 +846,7 @@ Item::Auth SelectFileType(const wchar_t * file_name)
EqualNoCase(ext, L"gif") ||
EqualNoCase(ext, L"bmp") ||
EqualNoCase(ext, L"png") )
return Item::auth_image;
return WINIX_ITEM_FILETYPE_IMAGE;
if( EqualNoCase(ext, L"pdf") ||
EqualNoCase(ext, L"doc") ||
@@ -857,9 +854,9 @@ Item::Auth SelectFileType(const wchar_t * file_name)
EqualNoCase(ext, L"txt") ||
EqualNoCase(ext, L"ods") ||
EqualNoCase(ext, L"odt") )
return Item::auth_document;
return WINIX_ITEM_FILETYPE_DOCUMENT;
return Item::auth_other;
return WINIX_ITEM_FILETYPE_UNKNOWN;
}

View File

@@ -397,8 +397,11 @@ bool IsFile(const wchar_t * file);
bool IsFile(const std::wstring & file);
bool CreateDir(const wchar_t * dir, int priv);
bool CreateDir(const std::wstring & dir, int priv);
bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv);
bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv);
// creating directories (dirs) under base_dir (base_dir must exist)
// if skip_last == true then last part from dir is treated as a file (the last directory is not created)
bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv = 0755, bool skip_last = false);
bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv = 0755, bool skip_last = false);
bool CopyFile(FILE * in, FILE * out);
bool CopyFile(const wchar_t * src, const wchar_t * dst);
@@ -411,7 +414,7 @@ bool RenameFile(const wchar_t * from, const wchar_t * to);
bool RenameFile(const std::wstring & from, const std::wstring & to);
const wchar_t * GetFileExt(const wchar_t * name);
Item::Auth SelectFileType(const wchar_t * file_name);
int SelectFileType(const wchar_t * file_name);
time_t Time(const tm & par);
time_t Time(const tm * par);

View File

@@ -476,29 +476,30 @@ void PostMultiParser::CreateTmpFile()
wchar_t buf[1024];
size_t buf_len = sizeof(buf)/sizeof(wchar_t);
if( config->auth_tmp_dir.empty() )
if( config->upload_dir.empty() )
{
log << log1 << "PMP: auth_tmp_dir is not set in the config" << logend;
log << log1 << "PMP: upload_dir is not set in the config" << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
swprintf(buf, buf_len, L"%ls/winix_%u_%d_%u", config->auth_tmp_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand());
swprintf(buf, buf_len, L"%ls/tmp/winix_%u_%d_%u", config->upload_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand());
tmp_filename_postfix += 1;
AssignString(buf, atmp_filename);
AssignString(atmp_filename, tmp_filename); // this make sure that the names are exactly the same
tmp_filename = buf;
Ezc::WideToUTF8(tmp_filename, atmp_filename);
tmp_file.open(atmp_filename.c_str(), std::ios_base::binary | std::ios_base::out);
// !! dodac ustawienie chmod config.upload_files_chmod dla tymczasowego pliku
if( !tmp_file )
{
log << log1 << "PMP: can't create a temporary file: " << tmp_filename << logend;
log << log1 << "PMP: can't create a temporary file: " << atmp_filename << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
log << log3 << "PMP: using temporary file for the content: " << tmp_filename << logend;
log << log3 << "PMP: using temporary file for the content: " << atmp_filename << logend;
}

View File

@@ -392,31 +392,30 @@ return puser->IsMemberOf(group);
bool System::MakePathSimpleFs(std::wstring & path, long dir_id, bool create_dir)
// the path depends on parent_id
bool System::CreateNewFileSimpleFs(Item & item)
{
if( config->auth_simplefs_dir.empty() )
bool res = dirs.MakePath(item.parent_id, item.file_path);
if( res )
{
log << log1 << "System: auth_simplefs_dir is not set in the config file" << logend;
return false;
if( !item.file_path.empty() && item.file_path[0] == '/' )
item.file_path.erase(0, 1);
}
else
{
log << log1 << "System: CreateNewFileSimpleFs: can't create a path to item.id: " << item.id
<< ", item.parent_id: " << item.parent_id << logend;
}
if( !dirs.MakePath(dir_id, path) )
return false;
if( create_dir && !CreateDirs(config->auth_simplefs_dir, path, 0755) )
return false;
path.insert(0, config->auth_simplefs_dir);
return true;
return res;
}
// the path depends on id
bool System::MakePathHashFs(std::wstring & path, long id, bool create_dir)
bool System::CreateNewFileHashFs(Item & item)
{
wchar_t buffer[50];
wchar_t * hash = buffer;
@@ -424,79 +423,112 @@ size_t buffer_len = sizeof(buffer)/sizeof(wchar_t);
// get 'id' as hexadecimal
buffer[0] = '0';
swprintf(buffer+1, buffer_len, L"%lx", (unsigned long)id);
swprintf(buffer+1, buffer_len, L"%lx", (unsigned long)item.id);
path = config->auth_hashfs_dir;
if( path.empty() )
{
log << log1 << "System: auth_hashfs_dir is not set in the config file" << logend;
return false;
}
path += '/';
item.file_path.clear();
// make sure that the length is even
if( (wcslen(hash) & 1) != 0 )
hash = buffer + 1; // the first character was zero
// creating dirs without the last part
// the last part is a part of a file
for(size_t i=0 ; hash[i] != 0 ; i+=2)
{
path += hash[i];
path += hash[i+1];
item.file_path += hash[i];
item.file_path += hash[i+1];
if( hash[i+2] != 0 )
{
if( create_dir && !CreateDir(path, 0755) )
return false;
path += '/';
}
item.file_path += '/';
}
// one character more to make sure the path is unique
// (we can have a directory without the character)
path += '_';
item.file_path += '_';
return true;
}
// making a complete path to a static file
bool System::MakePath(const Item & item, std::wstring & path, bool create_dir)
// creating item.file_path and item.file_fs
// you should set file_type yourself
// this method uses: item.id, item.url, item.parent_id (for selecting a mountpoint)
bool System::CreateNewFile(Item & item)
{
bool res;
if( item.type != Item::file )
{
log << log1 << "System: CreateNewFile: the item should be a file" << logend;
return false;
}
Mount * pmount = mounts.CalcMount(item.parent_id);
if( !pmount || pmount->fs == mounts.MountFsSimplefs() )
if( !pmount || pmount->fs != mounts.MountFsHashfs() )
{
res = MakePathSimpleFs(path, item.parent_id, create_dir);
res = CreateNewFileSimpleFs(item);
item.file_fs = mounts.MountFsSimplefs();
}
else
{
res = MakePathHashFs(path, item.id, create_dir);
res = CreateNewFileHashFs(item);
item.file_fs = mounts.MountFsHashfs();
}
if( res )
path += item.url;
item.file_path += item.url;
else
path.clear();
item.file_path.clear();
return res;
}
bool System::MakePath(Item & item, bool create_dir)
// making a global file path
// you should call CreateNewFile before
bool System::MakeFilePath(const Item & item, std::wstring & path, bool thumb, bool create_dir, int chmod)
{
return MakePath(item, item.auth_path, create_dir);
path.clear();
if( config->upload_dir.empty() )
{
log << log1 << "System: MakePath: upload_dir is not set in the config file" << logend;
return false;
}
if( item.file_path.empty() || item.file_type == WINIX_ITEM_FILETYPE_NONE )
{
log << log1 << "System: MakePath: this item has not a static file" << logend;
return false;
}
path = config->upload_dir;
if( item.file_fs == mounts.MountFsHashfs() )
path += L"/hashfs";
else
path += L"/simplefs";
if( thumb )
path += L"/thumb";
else
path += L"/normal";
if( create_dir && !CreateDirs(path, item.file_path, chmod, true) )
return false;
path += '/';
path += item.file_path;
return true;
}
Error System::AddFile(Item & item, int notify_code)
{
if( item.type == Item::dir )

View File

@@ -85,8 +85,9 @@ public:
bool IsMemberOfGroup(long user_id, const wchar_t * group_name);
bool MakePath(const Item & item, std::wstring & path, bool create_dir);
bool MakePath(Item & item, bool create_dir); // output path is: item.auth_path
// creating item.file_path and item.file_fs (the mountpoint where the item is located)
bool CreateNewFile(Item & item);
bool MakeFilePath(const Item & item, std::wstring & path, bool thumb = false, bool create_dir = false, int chmod = 0755);
Error AddFile(Item & item, int notify_code = 0);
Error EditFile(Item & item, bool with_url = true, int notify_code = 0);
@@ -105,8 +106,8 @@ private:
Synchro * synchro;
std::wstring path;
bool MakePathSimpleFs(std::wstring & path, long dir_id, bool create_dir);
bool MakePathHashFs(std::wstring & path, long id, bool create_dir);
bool CreateNewFileSimpleFs(Item & item);
bool CreateNewFileHashFs(Item & item);
};