Commit 1318cb57 authored by Murray Cumming's avatar Murray Cumming
Browse files

utils: Move some functions into file_utils

parent 1d39c456
......@@ -252,6 +252,8 @@ set(SOURCE_FILES
glom/libglom/standard_table_prefs_fields.h
glom/libglom/translations_po.cc
glom/libglom/translations_po.h
glom/libglom/file_utils.cc
glom/libglom/file_utils.h
glom/libglom/string_utils.cc
glom/libglom/string_utils.h
glom/libglom/utils.cc
......
......@@ -24,6 +24,7 @@
#include <glom/dialog_existing_or_new.h>
#include <glom/bakery/dialog_offersave.h>
#include <libglom/string_utils.h>
#include <libglom/file_utils.h>
#ifndef GLOM_ENABLE_CLIENT_ONLY
#include <glom/mode_design/translation/dialog_change_language.h>
......
......@@ -32,6 +32,7 @@
#include <libglom/init.h>
#include <libglom/privs.h>
#include <libglom/db_utils.h>
#include <libglom/file_utils.h>
#include <libglom/utils.h>
#include <giomm/file.h>
#include <glibmm/optioncontext.h>
......
......@@ -21,6 +21,7 @@
#include <libglom/connectionpool_backends/postgres_self.h>
#include <libglom/utils.h>
#include <libglom/db_utils.h>
#include <libglom/file_utils.h>
#include <libglom/spawn_with_feedback.h>
#include <giomm/file.h>
#include <glib/gstdio.h> // For g_remove
......
......@@ -22,6 +22,7 @@
#include <libglom/libglom_config.h>
#include <libglom/connectionpool_backends/sqlite.h>
#include <libglom/utils.h>
#include <libglom/file_utils.h>
#include <libglom/algorithms_utils.h>
#include <libglom/db_utils.h>
#include <giomm/file.h>
......
......@@ -20,6 +20,7 @@
#include <libglom/data_structure/layout/layoutitem_image.h>
#include <libglom/utils.h>
#include <libglom/file_utils.h>
#include <libglom/data_structure/glomconversions.h>
#include <glibmm/i18n.h>
......
......@@ -22,6 +22,7 @@
#include <libglom/xml_utils.h>
#include <libglom/algorithms_utils.h>
#include <libglom/utils.h>
#include <libglom/file_utils.h>
#include <libglom/string_utils.h>
//#include <libglom/data_structure/glomconversions.h>
#include <libglom/data_structure/layout/report_parts/layoutitem_summary.h>
......
/* Glom
*
* Copyright (C) 2001-2016 Murray Cumming
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/
#include <libglom/file_utils.h>
#include <libglom/string_utils.h>
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
#include <glibmm/convert.h>
#include <giomm/resource.h>
#include <libglom/utils.h>
#include <fstream>
#include <iostream>
namespace Glom
{
namespace Utils
{
bool file_exists(const Glib::ustring& uri)
{
if(uri.empty())
return false;
//Check whether file exists already:
// Try to examine the input file.
auto file = Gio::File::create_for_uri(uri);
return file_exists(file);
}
bool file_exists(const Glib::RefPtr<Gio::File>& file)
{
try
{
return file->query_exists();
}
catch(const Gio::Error& /* ex */)
{
return false; //Something went wrong. It does not exist.
}
}
bool delete_directory(const Glib::RefPtr<Gio::File>& directory)
{
try
{
if(!(directory->query_exists()))
return true;
//(Recursively) Delete any child files and directories,
//so we can delete this directory.
auto enumerator = directory->enumerate_children();
auto info = enumerator->next_file();
while(info)
{
auto child = directory->get_child(info->get_name());
bool removed_child = false;
if(child->query_file_type() == Gio::FILE_TYPE_DIRECTORY)
removed_child = delete_directory(child);
else
removed_child = child->remove();
if(!removed_child)
return false;
info = enumerator->next_file();
}
//Delete the actual directory:
if(!directory->remove())
return false;
}
catch(const Glib::Error& ex)
{
std::cerr << G_STRFUNC << ": Exception from Gio::File: " << ex.what() << std::endl;
return false;
}
return true;
}
bool delete_directory(const std::string& uri)
{
auto file = Gio::File::create_for_uri(uri);
return delete_directory(file);
}
bool delete_file(const std::string& uri)
{
auto file = Gio::File::create_for_uri(uri);
if(file->query_file_type() == Gio::FILE_TYPE_DIRECTORY)
{
std::cerr << G_STRFUNC << ": The file is a directory.\n";
return false;
}
try
{
if(!file->remove())
return false;
}
catch(const Glib::Error& ex)
{
std::cerr << G_STRFUNC << ": Exception from Gio::File: " << ex.what() << std::endl;
return false;
}
return true;
}
/** For instance, to find the first file in the directory with a .glom extension.
*/
Glib::ustring get_directory_child_with_suffix(const Glib::ustring& uri_directory, const std::string& suffix, bool recursive)
{
auto directory = Gio::File::create_for_uri(uri_directory);
auto enumerator = directory->enumerate_children();
auto info = enumerator->next_file();
while(info)
{
Glib::RefPtr<const Gio::File> child = directory->get_child(info->get_name());
const Gio::FileType file_type = child->query_file_type();
if(file_type == Gio::FILE_TYPE_REGULAR)
{
//Check the filename:
const std::string basename = child->get_basename();
if(string_remove_suffix(basename, suffix) != basename)
return child->get_uri();
}
else if(recursive && file_type == Gio::FILE_TYPE_DIRECTORY)
{
//Look in sub-directories too:
const Glib::ustring result = get_directory_child_with_suffix(child->get_uri(), suffix, recursive);
if(!result.empty())
return result;
}
info = enumerator->next_file();
}
return Glib::ustring();
}
Glib::ustring get_file_uri_without_extension(const Glib::ustring& uri)
{
if(uri.empty())
return uri;
auto file = Gio::File::create_for_uri(uri);
if(!file)
return uri; //Actually an error.
const Glib::ustring filename_part = file->get_basename();
const Glib::ustring::size_type pos_dot = filename_part.rfind(".");
if(pos_dot == Glib::ustring::npos)
return uri; //There was no extension, so just return the existing URI.
else
{
const Glib::ustring filename_part_without_ext = filename_part.substr(0, pos_dot);
//Use the Gio::File API to manipulate the URI:
auto parent = file->get_parent();
auto file_without_extension = parent->get_child(filename_part_without_ext);
return file_without_extension->get_uri();
}
}
std::string get_file_path_without_extension(const std::string& filepath)
{
if(filepath.empty())
return filepath;
auto file = Gio::File::create_for_path(filepath);
if(!file)
return filepath; //Actually an error.
const Glib::ustring filename_part = file->get_basename();
const Glib::ustring::size_type pos_dot = filename_part.rfind(".");
if(pos_dot == Glib::ustring::npos)
return filepath; //There was no extension, so just return the existing URI.
else
{
const Glib::ustring filename_part_without_ext = filename_part.substr(0, pos_dot);
//Use the Gio::File API to manipulate the URI:
auto parent = file->get_parent();
auto file_without_extension = parent->get_child(filename_part_without_ext);
return file_without_extension->get_path();
}
}
std::string get_temp_file_path(const std::string& prefix, const std::string& extension)
{
//Get a temporary file path:
std::string filepath;
try
{
const std::string prefix_pattern = prefix + "XXXXXX" + extension;
const int filehandle = Glib::file_open_tmp(filepath, prefix_pattern);
::close(filehandle);
}
catch(const Glib::Error& ex)
{
std::cerr << G_STRFUNC << ": Glib::file_open_tmp() failed\n";
return filepath;
}
if(filepath.empty())
{
std::cerr << G_STRFUNC << ": Glib::file_open_tmp() returned an empty filepath\n";
}
return filepath;
}
Glib::ustring get_temp_file_uri(const std::string& prefix, const std::string& extension)
{
try
{
const std::string filepath = get_temp_file_path(prefix, extension);
return Glib::filename_to_uri(filepath);
}
catch(const Glib::Error& ex)
{
std::cerr << G_STRFUNC << ": Exception from filename_to_uri(): " << ex.what() << std::endl;
return std::string();
}
}
std::string get_temp_directory_path(const std::string& prefix)
{
std::string result;
const std::string pattern = Glib::build_filename(
Glib::get_tmp_dir(), prefix + "XXXXXX");
//We must copy the pattern, because mkdtemp() modifies it:
char* c_pattern = g_strdup(pattern.c_str());
const char* filepath = g_mkdtemp(c_pattern);
if(filepath)
result = filepath;
return result;
}
Glib::ustring get_temp_directory_uri(const std::string& prefix)
{
try
{
const std::string filepath = get_temp_directory_path(prefix);
return Glib::filename_to_uri(filepath);
}
catch(const Glib::Error& ex)
{
std::cerr << G_STRFUNC << ": Exception from filename_to_uri(): " << ex.what() << std::endl;
return Glib::ustring();
}
}
Glib::ustring create_local_image_uri(const Gnome::Gda::Value& value)
{
static guint m_temp_image_uri_number = 0;
Glib::ustring result;
if(value.get_value_type() == GDA_TYPE_BINARY)
{
long size = 0;
gconstpointer pData = value.get_binary(size);
if(size && pData)
{
// Note that this is regular binary data, not escaped text representing the data:
//Save the image to a temporary file and provide the file URI.
char pchExtraNum[10];
sprintf(pchExtraNum, "%d", m_temp_image_uri_number);
result = ("/tmp/glom_report_image_" + Glib::ustring(pchExtraNum) + ".png");
++m_temp_image_uri_number;
std::fstream the_stream(result, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
if(the_stream)
{
the_stream.write((char*)pData, size);
}
}
else
std::cerr << G_STRFUNC << ": binary GdaValue contains no data.\n";
}
//else
// std::cerr << G_STRFUNC << ": type != BINARY\n";
if(result.empty())
result = "/tmp/glom_report_image_invalid.png";
return ("file://" + result);
}
} //namespace Utils
} //namespace Glom
/* Glom
*
* Copyright (C) 2001-2016 Murray Cumming
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/
#ifndef GLOM_FILE_UTILS_H
#define GLOM_FILE_UTILS_H
#include <giomm/file.h>
#include <libgdamm/value.h>
namespace Glom
{
namespace Utils
{
bool file_exists(const Glib::ustring& uri);
bool file_exists(const Glib::RefPtr <Gio::File>& file);
Glib::ustring create_local_image_uri(const Gnome::Gda::Value& value);
/** Delete a directory, if it exists, and its contents.
* Unlike g_file_delete(), this does not fail if the directory is not empty.
*/
bool delete_directory(const Glib::RefPtr<Gio::File>& directory);
/** Delete a directory, if it exists, and its contents.
* Unlike g_file_delete(), this does not fail if the directory is not empty.
* See also delete_file().
*/
bool delete_directory(const std::string& uri);
/** Delete a file, if it exists.
* See also delete_directory().
*/
bool delete_file(const std::string& uri);
/** For instance, to find the first file in the directory with a .glom extension.
*/
Glib::ustring get_directory_child_with_suffix(const Glib::ustring& uri_directory, const std::string& suffix, bool recursive);
/** Get a URI with the extension (any extension, not just .glom) removed.
*/
Glib::ustring get_file_uri_without_extension(const Glib::ustring& uri);
/** Get a filepath with the extension (any extension, not just .glom) removed.
*/
std::string get_file_path_without_extension(const std::string& filepath);
std::string get_temp_file_path(const std::string& prefix = std::string(), const std::string& extension = std::string());
Glib::ustring get_temp_file_uri(const std::string& prefix = std::string(), const std::string& extension = std::string());
/** This actually creates the directory.
*/
std::string get_temp_directory_path(const std::string& prefix = std::string());
/** This actually creates the directory.
*/
Glib::ustring get_temp_directory_uri(const std::string& prefix = std::string());
} //namespace Utils
} //namespace Glom
#endif //GLOM_FILE_UTILS_H
......@@ -108,6 +108,8 @@ libglom_sources = \
glom/libglom/db_utils.h \
glom/libglom/db_utils_export.cc \
glom/libglom/db_utils_export.h \
glom/libglom/file_utils.cc \
glom/libglom/file_utils.h \
glom/libglom/glom_postgres.cc \
glom/libglom/glom_postgres.h \
glom/libglom/init.cc \
......
......@@ -22,6 +22,7 @@
#include <libglom/utils.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/db_utils.h>
#include <libglom/file_utils.h>
#include <libglom/xsl_utils.h>
#include <libglom/xml_utils.h>
#include <iostream>
......
......@@ -577,67 +577,6 @@ Glib::ustring Utils::locale_language_id(const Glib::ustring& locale_id)
}
}
Glib::ustring Utils::create_local_image_uri(const Gnome::Gda::Value& value)
{
static guint m_temp_image_uri_number = 0;
Glib::ustring result;
if(value.get_value_type() == GDA_TYPE_BINARY)
{
long size = 0;
gconstpointer pData = value.get_binary(size);
if(size && pData)
{
// Note that this is regular binary data, not escaped text representing the data:
//Save the image to a temporary file and provide the file URI.
char pchExtraNum[10];
sprintf(pchExtraNum, "%d", m_temp_image_uri_number);
result = ("/tmp/glom_report_image_" + Glib::ustring(pchExtraNum) + ".png");
++m_temp_image_uri_number;
std::fstream the_stream(result, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
if(the_stream)
{
the_stream.write((char*)pData, size);
}
}
else
std::cerr << G_STRFUNC << ": binary GdaValue contains no data.\n";
}
//else
// std::cerr << G_STRFUNC << ": type != BINARY\n";
if(result.empty())
result = "/tmp/glom_report_image_invalid.png";
return ("file://" + result);
}
bool Utils::file_exists(const Glib::ustring& uri)
{
if(uri.empty())
return false;
//Check whether file exists already:
// Try to examine the input file.
auto file = Gio::File::create_for_uri(uri);
return file_exists(file);
}
bool Utils::file_exists(const Glib::RefPtr<Gio::File>& file)
{
try
{
return file->query_exists();
}
catch(const Gio::Error& /* ex */)
{
return false; //Something went wrong. It does not exist.
}
}
//TODO: This is a duplicate of the one in db_utils.cc:
//Merge all db utilities into db_utils in glom 1.24:
static Glib::RefPtr<Gnome::Gda::Connection> get_connection()
......@@ -841,161 +780,6 @@ Glib::RefPtr<Gnome::Gda::SqlBuilder> Utils::build_sql_update_with_where_clause(
return builder;
}
bool Utils::delete_directory(const Glib::RefPtr<Gio::File>& directory)
{
try
{
if(!(directory->query_exists()))
return true;
//(Recursively) Delete any child files and directories,
//so we can delete this directory.
auto enumerator = directory->enumerate_children();
auto info = enumerator->next_file();
while(info)
{
auto child = directory->get_child(info->get_name());
bool removed_child = false;
if(child->query_file_type() == Gio::FILE_TYPE_DIRECTORY)
removed_child = delete_directory(child);
else
removed_child = child->remove();
if(!removed_child)
return false;
info = enumerator->next_file();
}
//Delete the actual directory:
if(!directory->remove())
return false;
}
catch(const Glib::Error& ex)
{
std::cerr << G_STRFUNC << ": Exception from Gio::File: " << ex.what() << std::endl;
return false;
}
return true;
}
bool Utils::delete_directory(const std::string& uri)
{
auto file = Gio::File::create_for_uri(uri);
return delete_directory(file);