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
pull/3/head
Tomasz Sowa 12 years ago
parent 72be443414
commit 39923d6617

@ -18,7 +18,7 @@ app.o: ../../ezc/src/stringconv.h ../notify/notifythread.h
app.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
app.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
app.o: ../templates/misc.h ../templates/htmltextstream.h mounts.h
app.o: mountparser.h crypt.h run.h users.h groups.h group.h loadavg.h thumb.h
app.o: mountparser.h crypt.h run.h users.h groups.h group.h loadavg.h image.h
app.o: basethread.h threadmanager.h sessionmanager.h sessioncontainer.h
app.o: ../functions/functions.h ../functions/functionbase.h ../core/request.h
app.o: ../core/system.h ../core/synchro.h ../functions/functionparser.h
@ -64,7 +64,7 @@ config.o: ../notify/notifythread.h ../core/basethread.h synchro.h
config.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
config.o: ugcontainer.h lastcontainer.h ../templates/misc.h
config.o: ../templates/htmltextstream.h mounts.h mountparser.h crypt.h run.h
config.o: users.h groups.h group.h loadavg.h thumb.h basethread.h
config.o: users.h groups.h group.h loadavg.h image.h basethread.h
config.o: threadmanager.h sessionmanager.h sessioncontainer.h
config.o: ../functions/functions.h ../functions/functionbase.h
config.o: ../core/request.h ../core/system.h ../core/synchro.h
@ -124,6 +124,44 @@ groups.o: user.h plugindata.h rebus.h mount.h ../templates/locale.h
groups.o: ../core/confparser.h
htmlfilter.o: htmlfilter.h
httpsimpleparser.o: httpsimpleparser.h
image.o: image.h basethread.h textstream.h ../db/db.h ../db/dbbase.h
image.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h misc.h
image.o: item.h requesttypes.h ../core/error.h ../db/dbitemquery.h
image.o: ../core/item.h ../db/dbitemcolumns.h ../core/user.h ../core/group.h
image.o: ../core/dircontainer.h ../core/ugcontainer.h log.h logmanipulators.h
image.o: slog.h cur.h request.h error.h config.h confparser.h htmlfilter.h
image.o: ../templates/htmltextstream.h session.h user.h plugindata.h rebus.h
image.o: mount.h ../templates/locale.h ../core/confparser.h ../core/config.h
image.o: ../../ezc/src/utf8.h system.h dirs.h dircontainer.h
image.o: ../notify/notify.h ../notify/notifypool.h ../templates/patterns.h
image.o: ../templates/locale.h ../templates/localefilter.h
image.o: ../../ezc/src/ezc.h ../../ezc/src/generator.h
image.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
image.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
image.o: ../notify/notifythread.h ../core/basethread.h synchro.h
image.o: ../notify/templatesnotify.h ../core/users.h ugcontainer.h
image.o: lastcontainer.h ../templates/misc.h ../templates/htmltextstream.h
image.o: mounts.h mountparser.h crypt.h run.h users.h groups.h group.h
image.o: loadavg.h threadmanager.h plugin.h pluginmsg.h sessionmanager.h
image.o: sessioncontainer.h ../functions/functions.h
image.o: ../functions/functionbase.h ../core/request.h ../core/system.h
image.o: ../core/synchro.h ../functions/functionparser.h ../core/cur.h
image.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
image.o: ../functions/privchanger.h ../functions/chown.h
image.o: ../functions/ckeditor.h ../functions/cp.h ../functions/default.h
image.o: ../functions/download.h ../functions/emacs.h ../functions/last.h
image.o: ../functions/login.h ../functions/logout.h ../functions/ln.h
image.o: ../functions/ls.h ../functions/mkdir.h ../functions/mv.h
image.o: ../functions/nicedit.h ../functions/node.h ../functions/passwd.h
image.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
image.o: ../functions/sort.h ../functions/specialdefault.h
image.o: ../functions/stat.h ../functions/subject.h ../functions/template.h
image.o: ../functions/tinymce.h ../functions/uname.h ../functions/upload.h
image.o: ../functions/uptime.h ../functions/who.h ../functions/vim.h
image.o: ../core/htmlfilter.h ../templates/templates.h
image.o: ../templates/patterncacher.h ../templates/indexpatterns.h
image.o: ../templates/patterns.h ../templates/changepatterns.h
image.o: ../core/sessionmanager.h
item.o: item.h misc.h requesttypes.h crypt.h run.h config.h confparser.h
item.o: htmlfilter.h user.h
lastcontainer.o: lastcontainer.h log.h textstream.h logmanipulators.h slog.h
@ -196,7 +234,7 @@ mounts.o: ../notify/notifythread.h ../core/basethread.h synchro.h
mounts.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
mounts.o: ugcontainer.h lastcontainer.h ../templates/misc.h
mounts.o: ../templates/htmltextstream.h mountparser.h plugin.h pluginmsg.h
mounts.o: system.h crypt.h run.h users.h groups.h group.h loadavg.h thumb.h
mounts.o: system.h crypt.h run.h users.h groups.h group.h loadavg.h image.h
mounts.o: basethread.h threadmanager.h sessionmanager.h sessioncontainer.h
mounts.o: ../functions/functions.h ../functions/functionbase.h
mounts.o: ../core/request.h ../core/system.h ../core/synchro.h
@ -234,7 +272,7 @@ plugin.o: ../notify/notifythread.h ../core/basethread.h synchro.h
plugin.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
plugin.o: ugcontainer.h lastcontainer.h ../templates/misc.h
plugin.o: ../templates/htmltextstream.h mounts.h mountparser.h crypt.h run.h
plugin.o: users.h groups.h group.h loadavg.h thumb.h basethread.h
plugin.o: users.h groups.h group.h loadavg.h image.h basethread.h
plugin.o: threadmanager.h sessionmanager.h sessioncontainer.h
plugin.o: ../functions/functions.h ../functions/functionbase.h
plugin.o: ../core/request.h ../core/system.h ../core/synchro.h
@ -274,7 +312,7 @@ plugindata.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
plugindata.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
plugindata.o: ../templates/misc.h ../templates/htmltextstream.h mounts.h
plugindata.o: mountparser.h crypt.h run.h users.h groups.h group.h loadavg.h
plugindata.o: thumb.h basethread.h threadmanager.h sessionmanager.h
plugindata.o: image.h basethread.h threadmanager.h sessionmanager.h
plugindata.o: sessioncontainer.h ../functions/functions.h
plugindata.o: ../functions/functionbase.h ../core/request.h ../core/system.h
plugindata.o: ../core/synchro.h ../functions/functionparser.h ../core/cur.h
@ -326,7 +364,7 @@ request.o: ../notify/notifythread.h ../core/basethread.h synchro.h
request.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
request.o: ugcontainer.h lastcontainer.h ../templates/misc.h
request.o: ../templates/htmltextstream.h mounts.h mountparser.h crypt.h run.h
request.o: users.h groups.h group.h loadavg.h thumb.h basethread.h
request.o: users.h groups.h group.h loadavg.h image.h basethread.h
request.o: threadmanager.h sessionmanager.h sessioncontainer.h
request.o: ../functions/functions.h ../functions/functionbase.h
request.o: ../core/request.h ../core/system.h ../core/synchro.h
@ -381,7 +419,7 @@ sessionmanager.o: ../notify/notifythread.h ../core/basethread.h synchro.h
sessionmanager.o: ../notify/templatesnotify.h ../core/config.h
sessionmanager.o: ../core/users.h ugcontainer.h ../templates/misc.h
sessionmanager.o: ../templates/htmltextstream.h mounts.h mountparser.h
sessionmanager.o: crypt.h run.h users.h groups.h group.h loadavg.h thumb.h
sessionmanager.o: crypt.h run.h users.h groups.h group.h loadavg.h image.h
sessionmanager.o: basethread.h threadmanager.h sessionparser.h plugin.h
sessionmanager.o: pluginmsg.h ../functions/functions.h
sessionmanager.o: ../functions/functionbase.h ../core/request.h
@ -435,7 +473,7 @@ system.o: ../notify/notifythread.h ../core/basethread.h synchro.h
system.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
system.o: ugcontainer.h lastcontainer.h ../templates/misc.h
system.o: ../templates/htmltextstream.h mounts.h mountparser.h crypt.h run.h
system.o: users.h groups.h group.h loadavg.h thumb.h basethread.h
system.o: users.h groups.h group.h loadavg.h image.h basethread.h
system.o: threadmanager.h ../templates/templates.h
system.o: ../templates/patterncacher.h ../templates/indexpatterns.h
system.o: ../templates/patterns.h ../templates/changepatterns.h ../core/cur.h
@ -462,23 +500,4 @@ threadmanager.o: item.h error.h config.h confparser.h htmlfilter.h
threadmanager.o: ../templates/htmltextstream.h ../core/textstream.h misc.h
threadmanager.o: session.h user.h plugindata.h rebus.h mount.h
threadmanager.o: ../templates/locale.h ../core/confparser.h
thumb.o: thumb.h basethread.h textstream.h ../db/db.h ../db/dbbase.h
thumb.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h misc.h
thumb.o: item.h requesttypes.h ../core/error.h ../db/dbitemquery.h
thumb.o: ../core/item.h ../db/dbitemcolumns.h ../core/user.h ../core/group.h
thumb.o: ../core/dircontainer.h ../core/ugcontainer.h log.h logmanipulators.h
thumb.o: slog.h cur.h request.h error.h config.h confparser.h htmlfilter.h
thumb.o: ../templates/htmltextstream.h session.h user.h plugindata.h rebus.h
thumb.o: mount.h ../templates/locale.h ../core/confparser.h ../core/config.h
thumb.o: ../../ezc/src/utf8.h system.h dirs.h dircontainer.h
thumb.o: ../notify/notify.h ../notify/notifypool.h ../templates/patterns.h
thumb.o: ../templates/locale.h ../templates/localefilter.h
thumb.o: ../../ezc/src/ezc.h ../../ezc/src/generator.h
thumb.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
thumb.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
thumb.o: ../notify/notifythread.h ../core/basethread.h synchro.h
thumb.o: ../notify/templatesnotify.h ../core/users.h ugcontainer.h
thumb.o: lastcontainer.h ../templates/misc.h ../templates/htmltextstream.h
thumb.o: mounts.h mountparser.h crypt.h run.h users.h groups.h group.h
thumb.o: loadavg.h threadmanager.h
users.o: users.h

@ -1 +1 @@
o = acceptbaseparser.o app.o basethread.o bbcodeparser.o compress.o config.o confparser.o crypt.o dircontainer.o dirs.o groups.o htmlfilter.o httpsimpleparser.o item.o lastcontainer.o loadavg.o log.o misc.o mount.o mountparser.o mounts.o plugin.o plugindata.o postmultiparser.o rebus.o request.o run.o session.o sessioncontainer.o sessionmanager.o sessionparser.o slog.o synchro.o system.o textstream.o threadmanager.o thumb.o users.o
o = acceptbaseparser.o app.o basethread.o bbcodeparser.o compress.o config.o confparser.o crypt.o dircontainer.o dirs.o groups.o htmlfilter.o httpsimpleparser.o image.o item.o lastcontainer.o loadavg.o log.o misc.o mount.o mountparser.o mounts.o plugin.o plugindata.o postmultiparser.o rebus.o request.o run.o session.o sessioncontainer.o sessionmanager.o sessionparser.o slog.o synchro.o system.o textstream.o threadmanager.o users.o

@ -127,6 +127,12 @@ void Config::AssignValues(bool stdout_is_closed)
thumb_mode = Int(L"thumb_mode", 2);
thumb_cx = Size(L"thumb_cx", 150);
thumb_cy = Size(L"thumb_cy", 150);
thumb_quality = Int(L"thumb_quality", 92);
image_resize = Bool(L"image_resize", true);
image_mode = Int(L"image_mode", 6);
image_cx = Size(L"image_cx", 1000);
image_cy = Size(L"image_cy", 800);
image_quality = Int(L"image_quality", 92);
convert_cmd = Text(L"convert_cmd", L"/usr/local/bin/convert");
templates_dir = Text(L"templates_dir");

@ -259,7 +259,36 @@ public:
// default: 150
size_t thumb_cy;
// the convert program
// quality of thumbnails
// from 0 (the worst) to 100 (the best)
// more info: http://www.imagemagick.org/script/command-line-options.php?ImageMagick=p4jtel7557hovd34ui3tgb54h6#quality
// default: 92
int thumb_quality;
// resizing images
// this not affects thumbnails
// default: true
bool image_resize;
// the mode of resizing an image
// the same as 'thumb_mode' above
// default: 6
int image_mode;
// width of images
// default: 1000
size_t image_cx;
// height of images
// default: 800
size_t image_cy;
// quality of an image (the same as in thumbnails)
// from 0 (the worst) to 100 (the best)
// default: 92
int image_quality;
// the convert program (for images and thumbnails)
// default: /usr/local/bin/convert
std::wstring convert_cmd;

@ -158,10 +158,10 @@ DirContainer::ParentIterator Dirs::ParentEnd()
}
// dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
// !! dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
// albo tutaj stringa nie czyscic?
// O(m * log n) (m- how many parts are in 'id')
// path with a slash at the end
// path with a slash at the end and at the beginning
bool Dirs::MakePath(long id, std::wstring & path, bool clear_path)
{
DirContainer::Iterator i;

@ -39,7 +39,7 @@ Group * Groups::GetGroup(long group_id)
if( i == table.End() )
return 0;
return &(*i);
return &(**i);
}
@ -50,7 +50,7 @@ Group * Groups::GetGroup(const std::wstring & name)
if( i == table.End() )
return 0;
return &(*i);
return &(**i);
}

@ -0,0 +1,415 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010-2011, Tomasz Sowa
* All rights reserved.
*
*/
#include <ctime>
#include "image.h"
#include "utf8.h"
#include "log.h"
#include "system.h"
#include "plugin.h"
void Image::SetDb(Db * pdb)
{
db = pdb;
}
void Image::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Image::SetSystem(System * psystem)
{
system = psystem;
}
// first thread (objects locked)
void Image::Resize(const Item & item, size_t cx, size_t cy, int aspect_mode, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_RESIZE;
item_temp.file = item;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.aspect_mode = aspect_mode;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
// first thread (objects locked)
void Image::CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_CREATE_THUMB;
item_temp.file = item;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.aspect_mode = aspect_mode;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
void Image::CheckParam(ImageItem & item)
{
if( item.aspect_mode < 1 )
item.aspect_mode = 1;
if( item.aspect_mode > 7 )
item.aspect_mode = 7;
if( item.quality < 0 )
item.quality = 0;
if( item.quality > 100 )
item.quality = 100;
if( item_temp.cx < 5 )
item_temp.cx = 5;
if( item_temp.cy < 5 )
item_temp.cy = 5;
if( item_temp.cx > 10000 )
item_temp.cx = 10000;
if( item_temp.cy > 10000 )
item_temp.cy = 10000;
}
// second thread (objects locked)
bool Image::SignalReceived()
{
return !image_tab.empty();
}
// second thread (objects not locked)
void Image::Do()
{
ImageTab::iterator i;
bool end;
Lock();
i = image_tab.begin();
Unlock();
do
{
Lock();
if( i != image_tab.end() )
{
item_work = *i;
image_tab.erase(i++);
end = false;
}
else
{
end = true;
}
Unlock();
if( !end )
CreateImage();
}
while( !end && !IsExitSignal() );
}
void Image::Add(const std::wstring & in, TextStream<std::string> & out)
{
Ezc::WideToUTF8(in, add_tempa);
out << add_tempa;
}
void Image::EscapePath(const std::string & path, TextStream<std::string> & out, bool clear_stream)
{
if( clear_stream )
out.Clear();
out << '"';
for(size_t i=0 ; i<path.size() ; ++i)
{
if( path[i] == '"' )
out << '\\';
out << path[i];
}
out << '\"';
}
/*
from: http://www.imagemagick.org/script/command-line-processing.php#geometry
scale% Height and width both scaled by specified percentage.
scale-x%xscale-y% Height and width individually scaled by specified percentages. (Only one % symbol needed.)
width Width given, height automagically selected to preserve aspect ratio.
xheight Height given, width automagically selected to preserve aspect ratio.
widthxheight Maximum values of height and width given, aspect ratio preserved.
widthxheight^ Minimum values of width and height given, aspect ratio preserved.
widthxheight! Width and height emphatically given, original aspect ratio ignored.
widthxheight> Change as per widthxheight but only if an image dimension exceeds a specified dimension.
widthxheight< Change dimensions only if both image dimensions exceed specified dimensions.
*/
void Image::SelectAspect()
{
switch( item_work.aspect_mode )
{
case WINIX_IMAGE_MODE_1:
command << item_work.cx;
break;
case WINIX_IMAGE_MODE_3:
command << item_work.cx << "x" << item_work.cy;
break;
case WINIX_IMAGE_MODE_4:
command << '"' << item_work.cx << "x" << item_work.cy << "^\"";
break;
case WINIX_IMAGE_MODE_5:
command << '"' << item_work.cx << "x" << item_work.cy << "!\"";
break;
case WINIX_IMAGE_MODE_6:
command << '"' << item_work.cx << "x" << item_work.cy << ">\"";
break;
case WINIX_IMAGE_MODE_7:
command << '"' << item_work.cx << "x" << item_work.cy << "<\"";
break;
case WINIX_IMAGE_MODE_2:
default:
command << "x" << item_work.cy;
break;
}
}
// second thread (objects locked)
bool Image::CreateInputFileName()
{
if( system->MakeFilePath(item_work.file, src_path) )
{
Ezc::WideToUTF8(src_path, input_file_name);
return true;
}
else
{
log << log1 << "Image: cannot create a source path" << logend;
return false;
}
}
// second thread (objects locked)
void Image::CreateTmpFileName()
{
stream_tmp_path.Clear();
stream_tmp_path << config->upload_dir << L"/tmp/image_" << std::time(0);
Ezc::WideToUTF8(stream_tmp_path.Str(), tmp_file_name);
}
// second thread (objects are not locked)
bool Image::CreateCommand()
{
Lock();
iq.SetAll(true, false);
iq.WhereId(item_work.file.id);
// !! skoro teraz i tak wczytujemy caly obiekt
// to teraz w kolejce wystarczy zapamietywac tylko samo item.id (a nie caly obiekt item)
// the file could have been changed especially when there is a long queue of files
if( db->GetItem(item_work.file, iq) != WINIX_ERR_OK )
{
Unlock();
return false;
}
if( !CreateInputFileName() )
{
Unlock();
return false;
}
command.Clear();
Add(config->convert_cmd, command);
command << " ";
EscapePath(input_file_name, command, false);
command << " -quiet -quality " << item_work.quality;
if( item_work.type == WINIX_IMAGE_TYPE_RESIZE )
command << " -resize ";
else
command << " -strip -thumbnail ";
SelectAspect();
CreateTmpFileName();
command << " ";
EscapePath(tmp_file_name, command, false);
log << log4 << "Image: running: " << command.Str() << logend;
Unlock();
return true;
}
// second thread (objects are not locked)
void Image::SaveImage()
{
bool moved = false;
Lock();
// the file could have been changed especially when creating the image lasted too long
iq.SetAll(true, false);
iq.WhereId(item_work.file.id);
if( db->GetItem(item_work.file, iq) == WINIX_ERR_OK )
{
bool thumb = (item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB);
if( system->MakeFilePath(item_work.file, dst_path, thumb, true, config->upload_dirs_chmod) )
{
if( RenameFile(stream_tmp_path.Str(), dst_path) )
{
if( thumb )
{
item_work.file.has_thumb = true;
db->EditHasThumbById(true, item_work.file.id);
log << log3 << "Image: generated a thumbnail: " << dst_path << logend;
plugin.Call(WINIX_CREATED_THUMB, &item_work.file);
}
else
{
log << log3 << "Image: image resized: " << dst_path << logend;
plugin.Call(WINIX_IMAGE_RESIZED, &item_work.file);
}
moved = true;
}
else
{
log << log1 << "Image: cannot move a temporary file: " << stream_tmp_path.Str() << ", to: " << dst_path << logend;
}
}
else
{
log << log1 << "Image: cannot create a destination path" << logend;
}
}
if( !moved )
::RemoveFile(stream_tmp_path.Str());
Unlock();
}
// second thread (objects are not locked)
void Image::CreateImage()
{
if( !CreateCommand() )
return;
int res = std::system(command.CStr());
if( res == 0 )
{
SaveImage();
}
else
{
Lock();
log << log3 << "Image: some problems with creating an image"
<< ", 'convert' process returned: " << res << logend;
Unlock();
}
}
// second thread (objects are not locked)
// !! there is a problem with GIF files
// Bus error (core dumped)
/*
#include "wand/MagickWand.h"
// compiler options:
// include: -I/usr/local/include/ImageMagick
// link with: `MagickWand-config --ldflags --libs`
void Image::CreateThumbnail()
{
Ezc::WideToUTF8(item_work.source, sourcea);
Ezc::WideToUTF8(item_work.dst, dsta);
MagickWandGenesis();
MagickWand * wand = NewMagickWand();
if( MagickReadImage(wand, sourcea.c_str()) )
{
MagickThumbnailImage(wand, item_work.cx, item_work.cy);
if( MagickWriteImage(wand, dsta.c_str()) )
{
Lock();
log << log3 << "Image: created a thumbnail: " << dsta << logend;
Unlock();
}
}
DestroyMagickWand(wand);
MagickWandTerminus();
}
*/

@ -2,13 +2,13 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* Copyright (c) 2010-2011, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_core_thumb
#define headerfile_winix_core_thumb
#ifndef headerfile_winix_core_image
#define headerfile_winix_core_image
#include <string>
#include <list>
@ -24,73 +24,90 @@ class System;
// Width given, height automagically selected to preserve aspect ratio.
#define WINIX_THUMB_MODE_1 1
#define WINIX_IMAGE_MODE_1 1
// Height given, width automagically selected to preserve aspect ratio.
#define WINIX_THUMB_MODE_2 2
#define WINIX_IMAGE_MODE_2 2
// Maximum values of height and width given, aspect ratio preserved.
#define WINIX_THUMB_MODE_3 3
#define WINIX_IMAGE_MODE_3 3
// Minimum values of width and height given, aspect ratio preserved.
#define WINIX_THUMB_MODE_4 4
#define WINIX_IMAGE_MODE_4 4
// Width and height emphatically given, original aspect ratio ignored.
#define WINIX_THUMB_MODE_5 5
#define WINIX_IMAGE_MODE_5 5
// Change as per widthxheight but only if an image dimension exceeds a specified dimension.
#define WINIX_THUMB_MODE_6 6
#define WINIX_IMAGE_MODE_6 6
// Change dimensions only if both image dimensions are less than specified dimensions.
#define WINIX_THUMB_MODE_7 7
#define WINIX_IMAGE_MODE_7 7
// resizing
#define WINIX_IMAGE_TYPE_RESIZE 1
// generating a thumbnail
#define WINIX_IMAGE_TYPE_CREATE_THUMB 2
class Thumb : public BaseThread
class Image : public BaseThread
{
public:
void CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode);
void SetDb(Db * pdb);
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
void Resize(const Item & item, size_t cx, size_t cy, int aspect_mode, int quality);
void CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode, int quality);
private:
Db * db;
Config * config;
System * system;
struct ThumbItem
struct ImageItem
{
int type; // WINIX_IMAGE_TYPE_*
Item file;
size_t cx;
size_t cy;
int aspect_mode;
int quality;
};
// queue of thumbnails to create
typedef std::list<ThumbItem> ThumbTab;
ThumbTab thumb_tab;
ThumbItem item_temp;
typedef std::list<ImageItem> ImageTab;
ImageTab image_tab;
ImageItem item_temp;
// only for second thread
ThumbItem item_work;
ImageItem item_work;
std::wstring src_path, dst_path;
std::string tempa, string_tmp_patha;
TextStream<std::string> command;
TextStream<std::wstring> stream_tmp_path;
DbItemQuery iq;
std::string add_tempa;
std::string input_file_name;
std::string tmp_file_name;
virtual bool SignalReceived();
virtual void Do();
bool CreateCommand();
void SaveTmpThumbnail();
void CreateThumbnail();
bool CreateInputFileName();
void CreateTmpFileName();
void SaveImage();
void CreateImage();
void SelectAspect();
void EscapePath(const std::string & path);
void EscapePath(const std::string & path, TextStream<std::string> & out, bool clear_stream = true);
void CheckParam(ImageItem & item);
void Add(const std::wstring & in, TextStream<std::string> & out);
};

@ -1102,9 +1102,6 @@ void RemovePostFileTmp(PostFileTab & post_file_tab)
if( !tmp_filename.empty() && RemoveFile(tmp_filename) )
log << log3 << "Deleted tmp file: " << tmp_filename << logend;
else
if( !tmp_filename.empty() )
log << "swinka" << logend; //!!usunac
}
}

@ -258,7 +258,7 @@ const wchar_t * SkipWhite(const wchar_t * s);
template<class StringType1, class StringType2>
bool IsSubString(const StringType1 * short_str, const StringType2 * long_str)
bool IsSubStringp(const StringType1 * short_str, const StringType2 * long_str)
{
while( *short_str && *long_str && wchar_t(*short_str) == wchar_t(*long_str) )
{
@ -274,12 +274,18 @@ return false;
template<class StringType1, class StringType2>
bool IsSubString(const StringType1 & short_str, const StringType2 & long_str)
bool IsSubString(const StringType1 * short_str, const StringType2 * long_str)
{
return IsSubString(short_str.c_str(), long_str.c_str());
return IsSubStringp(short_str, long_str);
}
template<class StringType1, class StringType2>
bool IsSubString(const StringType1 & short_str, const StringType2 & long_str)
{
return IsSubStringp(short_str.c_str(), long_str.c_str());
}
template<class StringType1, class StringType2>
bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str)
@ -353,6 +359,36 @@ bool EqualNoCase(const StringType1 & str1, const StringType2 & str2)
/*
looking for 'look_for' string in 'buf' and replacing it with 'replace'
'replace' can be empty (so only 'look_for' will be deleted)
*/
template<class StringType>
void ReplaceString(StringType & buf, const StringType & look_for, const StringType & replace)
{
size_t i = 0;
if( look_for.empty() )
return;
while( i < buf.size() )
{
if( IsSubString(look_for.c_str(), buf.c_str() + i) )
{
buf.erase(i, look_for.size());
buf.insert(i, replace);
i += replace.size();
}
else
{
i += 1;
}
}
}
template<class StringType>
void NoLastSlash(StringType & s)
{

@ -49,6 +49,10 @@ void Mounts::CreateMountPar()
mount_par_page = AddMountPar(L"page");
mount_par_thumb_size = AddMountPar(L"thumb_size");
mount_par_thumb_mode = AddMountPar(L"thumb_mode");
mount_par_thumb_quality = AddMountPar(L"thumb_quality");
mount_par_image_size = AddMountPar(L"image_size");
mount_par_image_mode = AddMountPar(L"image_mode");
mount_par_image_quality = AddMountPar(L"image_quality");
//mount_par_thread = AddMountPar(L"thread");
//mount_par_createthread_on = AddMountPar(L"createthread_on");
mount_par_only_root_remove = AddMountPar(L"only_root_remove");

@ -69,6 +69,10 @@ public:
int MountParPage() { return mount_par_page; }
int MountParThumbSize() { return mount_par_thumb_size; }
int MountParThumbMode() { return mount_par_thumb_mode; }
int MountParThumbQuality() { return mount_par_thumb_quality; }
int MountParImageSize() { return mount_par_image_size; }
int MountParImageMode() { return mount_par_image_mode; }
int MountParImageQuality() { return mount_par_image_quality; }
//int MountParThread() { return mount_par_thread; }
//int MountParCreatethreadOn() { return mount_par_createthread_on; }
int MountParOnlyRootRemove() { return mount_par_only_root_remove; }
@ -139,6 +143,10 @@ private:
int mount_par_page;
int mount_par_thumb_size;
int mount_par_thumb_mode;
int mount_par_thumb_quality;
int mount_par_image_size;
int mount_par_image_mode;
int mount_par_image_quality;
//int mount_par_thread;
//int mount_par_createthread_on;
int mount_par_only_root_remove;

@ -245,6 +245,11 @@ bool Plugin::HasPlugin(const std::wstring & name)
}
bool Plugin::HasMessage(int message)
{
return (slots.find(message) != slots.end());
}
void Plugin::Call(int message, Slots::iterator & slot, PluginInfo & info)
{

@ -156,6 +156,8 @@ public:
bool HasPlugin(const wchar_t * name);
bool HasPlugin(const std::wstring & name);
bool HasMessage(int message);
void Call(int message);
void Call(int message, void * p1_);
void Call(int message, void * p1_, void * p2_);

@ -105,6 +105,43 @@
// in p1 you have a pointer to the Item struct
#define WINIX_FILE_CHANGED 3016
// a file (page) has been copied
// in p1 you have a pointer to the Item struct
// not every fields of Item struct are filled
#define WINIX_FILE_COPIED 3017
// a file will be moved
// in p1 you have a pointer to the Item struct
// not every fields of Item struct are filled
#define WINIX_FILE_PREPARE_TO_MOVE 3018
// a file has been moved
// in p1 you have a pointer to the Item struct (new file)
// not every fields of Item struct are filled
#define WINIX_FILE_MOVED 3019
// a thumbnail was created
// this message is called from another thread
// the thread is called Lock() before sending this message
// in p1 you have a pointer to the Item struct
#define WINIX_CREATED_THUMB 3020
// an image has been resized
// this message is called from another thread
// the thread is called Lock() before sending this message
// in p1 you have a pointer to the Item struct
#define WINIX_IMAGE_RESIZED 3022
// content of a directory was sorted
// (winix 'sort' function was used)
// in p1 you have a pointer to the Item struct (of the directory)
// this is from system->dirs so you should not change the item
#define WINIX_DIR_CONTENT_SORTED 3030
// here you add your own html templates
// call TemplatesFunctions::patterns.Add(L"file_name.html")
// the method returns an index which you have to remember
@ -113,7 +150,7 @@
// the message will be sent too whenever 'reload/templates' winix function is called
// templates you should add only in this message
// in other cases after 'reload' function the indexes would be wrong
#define WINIX_ADD_TEMPLATE 3017
#define WINIX_ADD_TEMPLATE 3100

@ -74,10 +74,10 @@ void System::Init()
notify.SetThreadManager(&thread_manager);
notify.Init();
thumb.SetDb(db);
thumb.SetConfig(config);
thumb.SetSystem(this);
thread_manager.Add(&thumb);
image.SetDb(db);
image.SetConfig(config);
image.SetSystem(this);
thread_manager.Add(&image);
crypt.SetConfig(config);
}
@ -664,7 +664,7 @@ return res;
Error System::AddFile(Item & item, int notify_code)
Error System::AddFile(Item & item, int notify_code, bool call_plugins)
{
if( item.type != Item::file )
return WINIX_ERR_FILE_EXPECTED;
@ -679,7 +679,8 @@ Error System::AddFile(Item & item, int notify_code)
if( notify_code )
notify.ItemChanged(notify_code, item);
plugin.Call(WINIX_FILE_ADDED, &item);
if( call_plugins )
plugin.Call(WINIX_FILE_ADDED, &item);
}
return status;
@ -688,7 +689,7 @@ return status;
Error System::EditFile(Item & item, bool with_url, int notify_code)
Error System::EditFile(Item & item, bool with_url, int notify_code, bool call_plugins)
{
if( item.type != Item::file )
return WINIX_ERR_FILE_EXPECTED;
@ -710,7 +711,8 @@ Error System::EditFile(Item & item, bool with_url, int notify_code)
if( notify_code )
notify.ItemChanged(notify_code, item);
plugin.Call(WINIX_FILE_CHANGED, &item);
if( call_plugins )
plugin.Call(WINIX_FILE_CHANGED, &item);
}

@ -22,7 +22,7 @@
#include "rebus.h"
#include "loadavg.h"
#include "synchro.h"
#include "thumb.h"
#include "image.h"
#include "threadmanager.h"
#include "notify/notify.h"
@ -55,8 +55,8 @@ public:
// notifications (by emails)
Notify notify;
// thumbnails (special thread)
Thumb thumb;
// images (resizing, generating thumbnails)
Image image;
// the time when the winix starts
time_t system_start;
@ -109,8 +109,8 @@ public:
bool MakePath(const Item & item, std::wstring & path, bool clear_path = true);
Error AddFile(Item & item, int notify_code = 0);
Error EditFile(Item & item, bool with_url = true, int notify_code = 0);
Error AddFile(Item & item, int notify_code = 0, bool call_plugins = true);
Error EditFile(Item & item, bool with_url = true, int notify_code = 0, bool call_plugins = true);
// converting GMT time to local time (different for each user)
time_t LocalTime(time_t gmt_time);

@ -1,309 +0,0 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <ctime>
#include "thumb.h"
#include "utf8.h"
#include "log.h"
#include "system.h"
void Thumb::SetDb(Db * pdb)
{
db = pdb;
}
void Thumb::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Thumb::SetSystem(System * psystem)
{
system = psystem;
}
// first thread (objects locked)
void Thumb::CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode)
{
item_temp.file = item;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.aspect_mode = aspect_mode;
thumb_tab.insert(thumb_tab.end(), item_temp);
WakeUpThread();
}
// second thread (objects locked)
bool Thumb::SignalReceived()
{
return !thumb_tab.empty();
}
// second thread (objects not locked)
void Thumb::Do()
{
ThumbTab::iterator i;
bool end;
Lock();
i = thumb_tab.begin();
Unlock();
do
{
Lock();
if( i != thumb_tab.end() )
{
item_work = *i;
thumb_tab.erase(i++);
end = false;
}
else
{
end = true;
}
Unlock();
if( !end )
CreateThumbnail();
}
while( !end && !IsExitSignal() );
}
void Thumb::EscapePath(const std::string & path)
{
command << '"';
for(size_t i=0 ; i<path.size() ; ++i)
{
if( path[i] == '"' )
command << '\\';
command << path[i];
}
command << "\" ";
}
/*
from: http://www.imagemagick.org/script/command-line-processing.php#geometry
scale% Height and width both scaled by specified percentage.
scale-x%xscale-y% Height and width individually scaled by specified percentages. (Only one % symbol needed.)
width Width given, height automagically selected to preserve aspect ratio.
xheight Height given, width automagically selected to preserve aspect ratio.
widthxheight Maximum values of height and width given, aspect ratio preserved.
widthxheight^ Minimum values of width and height given, aspect ratio preserved.
widthxheight! Width and height emphatically given, original aspect ratio ignored.
widthxheight> Change as per widthxheight but only if an image dimension exceeds a specified dimension.
widthxheight< Change dimensions only if both image dimensions exceed specified dimensions.
*/
void Thumb::SelectAspect()
{
switch( item_work.aspect_mode )
{
case WINIX_THUMB_MODE_1:
command << item_work.cx;
break;
case WINIX_THUMB_MODE_3:
command << item_work.cx << "x" << item_work.cy;
break;
case WINIX_THUMB_MODE_4:
command << '"' << item_work.cx << "x" << item_work.cy << "^\"";
break;
case WINIX_THUMB_MODE_5:
command << '"' << item_work.cx << "x" << item_work.cy << "!\"";
break;
case WINIX_THUMB_MODE_6:
command << '"' << item_work.cx << "x" << item_work.cy << ">\"";
break;
case WINIX_THUMB_MODE_7:
command << '"' << item_work.cx << "x" << item_work.cy << "<\"";
break;
case WINIX_THUMB_MODE_2:
default:
command << "x" << item_work.cy;
break;
}
}
// second thread (objects are not locked)
bool Thumb::CreateCommand()
{
bool res;
command.Clear();
stream_tmp_path.Clear();
Lock();
Ezc::WideToUTF8(config->convert_cmd, tempa);
command << tempa << " -quiet -strip -thumbnail ";
SelectAspect();
command << " ";
if( system->MakeFilePath(item_work.file, src_path) )
{
Ezc::WideToUTF8(src_path, tempa);
EscapePath(tempa);
stream_tmp_path << config->upload_dir << L"/tmp/thumb_" << std::time(0);
Ezc::WideToUTF8(stream_tmp_path.Str(), string_tmp_patha);
EscapePath(string_tmp_patha);
res = true;
}
else
{
log << log1 << "Thumb: cannot create a source path" << logend;
res = false;
}
Unlock();
return res;
}
// second thread (objects are not locked)
void Thumb::SaveTmpThumbnail()
{
bool moved = false;
Lock();
// the file could have been changed especially when creating thumbnail lasted too long
iq.SetAll(false, false);
iq.sel_parent_id = true;
iq.sel_file = true;
iq.sel_url = true;
iq.sel_type = true;
iq.WhereId(item_work.file.id);
if( db->GetItem(item_work.file, iq) == WINIX_ERR_OK )
{
if( system->MakeFilePath(item_work.file, dst_path, true, true, config->upload_dirs_chmod) )
{
if( RenameFile(stream_tmp_path.Str(), dst_path) )
{
log << log3 << "Thumb: created a thumbnail: " << dst_path << logend;
db->EditHasThumbById(true, item_work.file.id);
moved = true;
}
else
{
log << log1 << "Thumb: cannot move a temporary file: " << stream_tmp_path.Str() << ", to: " << dst_path << logend;
}
}
else
{
log << log1 << "Thumb: cannot create a destination path" << logend;
}
}
if( !moved )
::RemoveFile(stream_tmp_path.Str());
Unlock();
}
// second thread (objects are not locked)
void Thumb::CreateThumbnail()
{
if( !CreateCommand() )
return;
int res = std::system(command.CStr());
if( res == 0 )
{
SaveTmpThumbnail();
}
else
{
Lock();
log << log3 << "Thumb: some problems with creating a thumbnail " << tempa
<< ", 'convert' process returned: " << res << logend;
Unlock();
}
}
// second thread (objects are not locked)
// !! there is a problem with GIF files
// Bus error (core dumped)
/*
#include "wand/MagickWand.h"
// compiler options:
// include: -I/usr/local/include/ImageMagick
// link with: `MagickWand-config --ldflags --libs`
void Thumb::CreateThumbnail()
{
Ezc::WideToUTF8(item_work.source, sourcea);
Ezc::WideToUTF8(item_work.dst, dsta);
MagickWandGenesis();
MagickWand * wand = NewMagickWand();
if( MagickReadImage(wand, sourcea.c_str()) )
{
MagickThumbnailImage(wand, item_work.cx, item_work.cy);
if( MagickWriteImage(wand, dsta.c_str()) )
{
Lock();
log << log3 << "Thumb: created a thumbnail: " << dsta << logend;
Unlock();
}
}
DestroyMagickWand(wand);
MagickWandTerminus();
}
*/

@ -11,6 +11,7 @@
#define headerfile_winix_core_ugcontainer
#include <vector>
#include <list>
#include <map>
#include <stdexcept>
@ -21,11 +22,16 @@
template<class Type>
class UGContainer
{
public:
typedef typename std::vector<Type> Table;
typedef typename Table::iterator Iterator;
typedef typename Table::size_type SizeType;
~UGContainer();
// we have to use a pointer (Type*) here
// because we are remembering some pointers to the items elsewhere
// so the pointers should not be invalidated
typedef typename std::vector<Type*> Table;
typedef typename Table::iterator Iterator;
typedef typename Table::size_type SizeType;
typedef typename std::map<long, SizeType> TableId;
typedef typename std::map<std::wstring, SizeType> TableName;
@ -65,7 +71,14 @@ private:
template<class Type>