changed the way how prefixes are added to urls

instead at the end we adding a prefix before an extension, e.g: filename_(2).jpg
This commit is contained in:
Tomasz Sowa 2021-02-25 00:12:45 +01:00
parent 51b1aed483
commit afbe82e9f4
4 changed files with 165 additions and 66 deletions

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2018, Tomasz Sowa * Copyright (c) 2008-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -1161,30 +1161,55 @@ bool GetUTF8File(const std::wstring & file_path, std::wstring & content, bool cl
} }
// if there is not an extension it returns a pointer to the last '\0' character // if there is no an extension it returns a pointer to the last '\0' character
const wchar_t * GetFileExt(const wchar_t * name) const wchar_t * GetFileExt(const wchar_t * name)
{ {
size_t i, ilast; const wchar_t * dot_ptr = nullptr;
// looking for the end of the name for( ; *name != 0 ; ++name)
for(i=0 ; name[i] != 0 ; ++i); {
if( *name == '.' )
{
dot_ptr = name;
}
}
if( i == 0 ) return dot_ptr ? dot_ptr + 1 : name;
return name; // ops, the name is empty }
// remember the end of the string
ilast = i;
// looking for the last dot void PrepareNewFileName(const wchar_t * src, const wchar_t * postfix, std::wstring & res, bool clear_res)
for(--i ; i>0 && name[i] != '.' ; --i); {
bool has_ext = false;
const wchar_t * ext = GetFileExt(src);
if( name[i] != '.' ) if( clear_res )
return name + ilast; // ops, there is not a dot res.clear();
// the extensions starts from i+1 size_t len = ext - src;
// and can be empty (if the last character is a dot)
return name + i + 1; if( len > 0 )
{
if( *(ext-1) == '.' )
{
len -= 1;
has_ext = true;
}
}
res.append(src, len);
res.append(postfix);
if( has_ext )
res.append(1, '.');
res.append(ext);
}
void PrepareNewFileName(const std::wstring & src, const std::wstring & postfix, std::wstring & res, bool clear_res)
{
return PrepareNewFileName(src.c_str(), postfix.c_str(), res, clear_res);
} }

View File

@ -77,6 +77,7 @@ double Tod(const wchar_t * str);
// if the buffer is too small it will be terminated at the beginning (empty string) // if the buffer is too small it will be terminated at the beginning (empty string)
// and the function returns false // and the function returns false
// IMPROVEME now we can use Toa from Pikotools
template<class CharType> template<class CharType>
bool Toa(unsigned long value, CharType * buffer, size_t buf_len, int base = 10) bool Toa(unsigned long value, CharType * buffer, size_t buf_len, int base = 10)
{ {
@ -663,6 +664,11 @@ bool GetUTF8File(const std::wstring & file_path, std::wstring & content, bool cl
const wchar_t * GetFileExt(const wchar_t * name); const wchar_t * GetFileExt(const wchar_t * name);
void PrepareNewFileName(const wchar_t * src, const wchar_t * postfix, std::wstring & res, bool clear_res = true);
void PrepareNewFileName(const std::wstring & src, const std::wstring & postfix, std::wstring & res, bool clear_res = true);
int SelectFileType(const wchar_t * file_name); int SelectFileType(const wchar_t * file_name);
int SelectFileType(const std::wstring & file_name); int SelectFileType(const std::wstring & file_name);

View File

@ -33,6 +33,7 @@
*/ */
#include "models/item.h" #include "models/item.h"
#include "core/misc.h"
#include "finder.h" #include "finder.h"
@ -60,7 +61,6 @@ void Item::map_fields()
field(L"subject", subject); field(L"subject", subject);
field(L"template", html_template); field(L"template", html_template);
field(L"sort_index", sort_index); field(L"sort_index", sort_index);
//field(L"content_id", content_id);
field(L"content_id", item_content, true, true, true); field(L"content_id", item_content, true, true, true);
// may we should add a method setTypeFromInt(int t)? // may we should add a method setTypeFromInt(int t)?
@ -76,42 +76,73 @@ void Item::table_name(PT::TextStream & stream)
void Item::before_insert() void Item::before_insert()
{ {
// IMPROVEME if prepare_status is false then update the 'url' with the 'id'
// add a method: update_url()
url_was_prepared_correctly = prepare_url();
} }
void Item::after_insert() void Item::after_insert()
{ {
get_last_sequence(L"core.item_id_seq", id); get_last_sequence(L"core.item_id_seq", id);
if( !url_was_prepared_correctly )
{
// update_url();
// what about an error from update_url()?
}
} }
bool Item::insert(morm::ModelData * model_data, bool update_whole_tree)
{
bool url_prepared_correctly = prepare_url();
bool insert_status = morm::Model::insert(model_data, update_whole_tree);
if( insert_status )
{
if( !url_prepared_correctly )
{
PT::Toa(id, url);
morm::Model::update(model_data, false);
}
}
return insert_status;
}
bool Item::insert(morm::ModelData & model_data, bool update_whole_tree)
{
return insert(&model_data, update_whole_tree);
}
bool Item::insert(bool update_whole_tree)
{
return insert(nullptr, update_whole_tree);
}
/*
*
* this can be done better
* instead of calculating if more than zero items are in a directory
* just get the one item (should be one in normal circumstances)
* and compare its 'id' with 'this.id' and if these ids are different
* then prepare a new url
*
*
*/
bool Item::update(morm::ModelData * model_data, bool url_was_changed, bool update_whole_tree) bool Item::update(morm::ModelData * model_data, bool url_was_changed, bool update_whole_tree)
{ {
bool prepare_url_status = true; bool url_prepared_correctly = true;
if( url_was_changed ) if( url_was_changed )
{ {
prepare_url_status = prepare_url(); url_prepared_correctly = prepare_url();
} }
bool update_status = morm::Model::update(model_data, update_whole_tree); bool update_status = morm::Model::update(model_data, update_whole_tree);
if( update_status ) if( update_status )
{ {
if( !prepare_url_status ) if( !url_prepared_correctly )
{ {
// IMPROVEME add update_url() method PT::Toa(id, url);
// set 'url' to the same value as 'id' morm::Model::update(model_data, false);
//update_status = update_url();
} }
} }
@ -132,6 +163,41 @@ bool Item::update(bool url_was_changed, bool update_whole_tree)
bool Item::save(morm::ModelData * model_data, bool url_was_changed, bool save_whole_tree)
{
bool url_prepared_correctly = true;
if( save_mode == DO_INSERT_ON_SAVE || (save_mode == DO_UPDATE_ON_SAVE && url_was_changed) )
{
url_prepared_correctly = prepare_url();
}
bool save_status = morm::Model::save(model_data, save_whole_tree);
if( save_status )
{
if( !url_prepared_correctly )
{
PT::Toa(id, url);
morm::Model::save(model_data, false);
}
}
return save_status;
}
bool Item::save(morm::ModelData & model_data, bool url_was_changed, bool save_whole_tree)
{
return save(&model_data, url_was_changed, save_whole_tree);
}
bool Item::save(bool url_was_changed, bool save_whole_tree)
{
return save(nullptr, url_was_changed, save_whole_tree);
}
void Item::Clear() void Item::Clear()
@ -143,11 +209,7 @@ void Item::Clear()
subject.clear(); subject.clear();
html_template.clear(); html_template.clear();
sort_index = 0; sort_index = 0;
content_id = -1;
item_content.Clear(); item_content.Clear();
// used only when inserting, not saved to the database
url_was_prepared_correctly = true;
} }
@ -167,32 +229,36 @@ long Item::calc_items_by_url(long parent_id, const std::wstring & url)
} }
/*
* may we should check for '.' and '..' here too?
*/
bool Item::prepare_url() bool Item::prepare_url()
{ {
std::wstring temp_url; std::wstring temp_url;
bool is_that_url; bool is_that_url;
int index = 1; int index = 1;
const int max_index = 99; const int max_index = 99;
wchar_t appendix[20]; std::wstring postfix;
size_t appendix_len = sizeof(appendix) / sizeof(wchar_t);
appendix[0] = 0;
// only root dir may not have the url // only root dir may not have the url
if( parent_id != -1 && url.empty() ) if( parent_id != -1 && url.empty() )
url = L"empty"; // IMPROVEME move me to locales url = L"_";
do do
{ {
temp_url = url; if( index > 1 )
temp_url += appendix; {
postfix = L"_(";
PT::Toa(index, postfix, false);
postfix += L")";
}
PrepareNewFileName(url, postfix, temp_url);
long size = calc_items_by_url(parent_id, temp_url); long size = calc_items_by_url(parent_id, temp_url);
if( size > 0 ) if( size > 0 )
{ {
swprintf(appendix, appendix_len, L"_(%d)", ++index);
is_that_url = true; is_that_url = true;
} }
else else
@ -200,6 +266,8 @@ size_t appendix_len = sizeof(appendix) / sizeof(wchar_t);
url = temp_url; url = temp_url;
is_that_url = false; is_that_url = false;
} }
index += 1;
} }
while( is_that_url && index <= max_index ); while( is_that_url && index <= max_index );
@ -207,7 +275,6 @@ return !is_that_url;
} }
void Item::do_migration(morm::ModelConnector * model_connector) void Item::do_migration(morm::ModelConnector * model_connector)
{ {
return; return;
@ -217,11 +284,11 @@ void Item::do_migration(morm::ModelConnector * model_connector)
std::list<Item> list = finder.select().where().eq(L"type", static_cast<int>(Item::dir)).eq(L"content_id", -1).get_list(); std::list<Item> list = finder.select().where().eq(L"type", static_cast<int>(Item::dir)).eq(L"content_id", -1).get_list();
for(Item & item : list) // for(Item & item : list)
{ // {
item.item_content.set_save_mode(morm::Model::DO_INSERT_ON_SAVE); // item.item_content.set_save_mode(morm::Model::DO_INSERT_ON_SAVE);
item.save(); // item.save();
} // }
} }

View File

@ -50,6 +50,12 @@ public:
long size; long size;
/*
* add an id of an item and compare it in 'update' method
* (in a case size==1)
*
*/
void map_fields() void map_fields()
{ {
field(L"size", size); field(L"size", size);
@ -109,12 +115,6 @@ public:
*/ */
int sort_index; int sort_index;
/*
* may not needed?
* the id is in the ItemContent object
*/
long content_id;
/* /*
* *
*/ */
@ -139,19 +139,23 @@ public:
bool prepare_url(); bool prepare_url();
/*
* CHECKME bool insert(morm::ModelData * model_data, bool update_whole_tree = true);
* make sure update(...) methods from Model are not available bool insert(morm::ModelData & model_data, bool update_whole_tree = true);
*/ bool insert(bool update_whole_tree = true);
bool update(morm::ModelData * model_data, bool url_was_changed, bool update_whole_tree = true); bool update(morm::ModelData * model_data, bool url_was_changed, bool update_whole_tree = true);
bool update(morm::ModelData & model_data, bool url_was_changed, bool update_whole_tree = true); bool update(morm::ModelData & model_data, bool url_was_changed, bool update_whole_tree = true);
bool update(bool url_was_changed, bool update_whole_tree = true); bool update(bool url_was_changed, bool update_whole_tree = true);
// IMPROVEME make the same for save() methods
bool save(morm::ModelData * model_data, bool url_was_changed, bool save_whole_tree = true);
bool save(morm::ModelData & model_data, bool url_was_changed, bool save_whole_tree = true);
bool save(bool url_was_changed, bool save_whole_tree = true);
/* /*
* IMPROVEME * IMPROVEME
* when removing we should check whether the item_content.references is zero and them remove it * when removing we should check whether the item_content.references is zero and then remove it
* in other cases only decrement item_content.references * in other cases only decrement item_content.references
* *
*/ */
@ -164,9 +168,6 @@ public:
protected: protected:
bool url_was_prepared_correctly;
long calc_items_by_url(long parent_id, const std::wstring & url); long calc_items_by_url(long parent_id, const std::wstring & url);