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.
*
* 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)
{
size_t i, ilast;
const wchar_t * dot_ptr = nullptr;
// looking for the end of the name
for(i=0 ; name[i] != 0 ; ++i);
for( ; *name != 0 ; ++name)
{
if( *name == '.' )
{
dot_ptr = name;
}
}
if( i == 0 )
return name; // ops, the name is empty
return dot_ptr ? dot_ptr + 1 : name;
}
// remember the end of the string
ilast = i;
// looking for the last dot
for(--i ; i>0 && name[i] != '.' ; --i);
void PrepareNewFileName(const wchar_t * src, const wchar_t * postfix, std::wstring & res, bool clear_res)
{
bool has_ext = false;
const wchar_t * ext = GetFileExt(src);
if( name[i] != '.' )
return name + ilast; // ops, there is not a dot
if( clear_res )
res.clear();
// the extensions starts from i+1
// and can be empty (if the last character is a dot)
size_t len = ext - src;
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)
// and the function returns false
// IMPROVEME now we can use Toa from Pikotools
template<class CharType>
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);
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 std::wstring & file_name);

View File

@ -33,6 +33,7 @@
*/
#include "models/item.h"
#include "core/misc.h"
#include "finder.h"
@ -60,7 +61,6 @@ void Item::map_fields()
field(L"subject", subject);
field(L"template", html_template);
field(L"sort_index", sort_index);
//field(L"content_id", content_id);
field(L"content_id", item_content, true, true, true);
// may we should add a method setTypeFromInt(int t)?
@ -76,42 +76,73 @@ void Item::table_name(PT::TextStream & stream)
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()
{
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 prepare_url_status = true;
bool url_prepared_correctly = true;
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);
if( update_status )
{
if( !prepare_url_status )
if( !url_prepared_correctly )
{
// IMPROVEME add update_url() method
// set 'url' to the same value as 'id'
//update_status = update_url();
PT::Toa(id, url);
morm::Model::update(model_data, false);
}
}
@ -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()
@ -143,11 +209,7 @@ void Item::Clear()
subject.clear();
html_template.clear();
sort_index = 0;
content_id = -1;
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()
{
std::wstring temp_url;
bool is_that_url;
int index = 1;
const int max_index = 99;
wchar_t appendix[20];
size_t appendix_len = sizeof(appendix) / sizeof(wchar_t);
appendix[0] = 0;
std::wstring postfix;
// only root dir may not have the url
if( parent_id != -1 && url.empty() )
url = L"empty"; // IMPROVEME move me to locales
url = L"_";
do
{
temp_url = url;
temp_url += appendix;
if( index > 1 )
{
postfix = L"_(";
PT::Toa(index, postfix, false);
postfix += L")";
}
PrepareNewFileName(url, postfix, temp_url);
long size = calc_items_by_url(parent_id, temp_url);
if( size > 0 )
{
swprintf(appendix, appendix_len, L"_(%d)", ++index);
is_that_url = true;
}
else
@ -200,6 +266,8 @@ size_t appendix_len = sizeof(appendix) / sizeof(wchar_t);
url = temp_url;
is_that_url = false;
}
index += 1;
}
while( is_that_url && index <= max_index );
@ -207,7 +275,6 @@ return !is_that_url;
}
void Item::do_migration(morm::ModelConnector * model_connector)
{
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();
for(Item & item : list)
{
item.item_content.set_save_mode(morm::Model::DO_INSERT_ON_SAVE);
item.save();
}
// for(Item & item : list)
// {
// item.item_content.set_save_mode(morm::Model::DO_INSERT_ON_SAVE);
// item.save();
// }
}

View File

@ -50,6 +50,12 @@ public:
long size;
/*
* add an id of an item and compare it in 'update' method
* (in a case size==1)
*
*/
void map_fields()
{
field(L"size", size);
@ -109,12 +115,6 @@ public:
*/
int sort_index;
/*
* may not needed?
* the id is in the ItemContent object
*/
long content_id;
/*
*
*/
@ -139,19 +139,23 @@ public:
bool prepare_url();
/*
* CHECKME
* make sure update(...) methods from Model are not available
*/
bool insert(morm::ModelData * model_data, bool update_whole_tree = true);
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(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
* 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
*
*/
@ -164,9 +168,6 @@ public:
protected:
bool url_was_prepared_correctly;
long calc_items_by_url(long parent_id, const std::wstring & url);