diff options
Diffstat (limited to 'src/utilities')
-rw-r--r-- | src/utilities/archiveReader.vala | 123 | ||||
-rw-r--r-- | src/utilities/archiveWriter.vala | 139 | ||||
-rw-r--r-- | src/utilities/config.vala | 35 |
3 files changed, 289 insertions, 8 deletions
diff --git a/src/utilities/archiveReader.vala b/src/utilities/archiveReader.vala new file mode 100644 index 0000000..16e4541 --- /dev/null +++ b/src/utilities/archiveReader.vala @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// 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 3 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, see <http://www.gnu.org/licenses/>. +///////////////////////////////////////////////////////////////////////// + +namespace GnomePie { + +///////////////////////////////////////////////////////////////////////// +/// This class can be used to unpack an archive to a directory. +///////////////////////////////////////////////////////////////////////// + +public class ArchiveReader : GLib.Object { + + private Archive.Read archive; + private Archive.WriteDisk writer; + + ///////////////////////////////////////////////////////////////////// + /// Constructs a new ArchiveReader + ///////////////////////////////////////////////////////////////////// + + public ArchiveReader() { + this.archive = new Archive.Read(); + this.archive.support_format_all(); + this.archive.support_filter_all(); + + this.writer = new Archive.WriteDisk(); + this.writer.set_options( + Archive.ExtractFlags.TIME | + Archive.ExtractFlags.PERM | + Archive.ExtractFlags.ACL | + Archive.ExtractFlags.FFLAGS + ); + this.writer.set_standard_lookup(); + } + + ///////////////////////////////////////////////////////////////////// + /// Call this once after you created the ArchiveReader. Pass the + /// path to the target archive location. + ///////////////////////////////////////////////////////////////////// + + public bool open(string path) { + return this.archive.open_filename(path, 10240) == Archive.Result.OK; + } + + ///////////////////////////////////////////////////////////////////// + /// Extracts all files from the previously opened archive. + ///////////////////////////////////////////////////////////////////// + + public bool extract_to(string directory) { + while (true) { + unowned Archive.Entry entry; + var r = this.archive.next_header(out entry); + + if (r == Archive.Result.EOF) { + break; + } + + if (r != Archive.Result.OK) { + warning(this.archive.error_string()); + return false; + } + + entry.set_pathname(directory + "/" + entry.pathname()); + + r = this.writer.write_header(entry); + + if (r != Archive.Result.OK) { + warning(this.writer.error_string()); + return false; + } + + if (entry.size() > 0) { + while (true) { + size_t offset, size; + void *buff; + + r = this.archive.read_data_block(out buff, out size, out offset); + if (r == Archive.Result.EOF) { + break; + } + + if (r != Archive.Result.OK) { + warning(this.archive.error_string()); + return false; + } + + this.writer.write_data_block(buff, size, offset); + } + } + + r = this.writer.finish_entry(); + + if (r != Archive.Result.OK) { + warning(this.writer.error_string()); + return false; + } + } + return true; + } + + ///////////////////////////////////////////////////////////////////// + /// When all files have been added, close the directory again. + ///////////////////////////////////////////////////////////////////// + + public void close() { + this.archive.close(); + this.writer.close(); + } +} + +} diff --git a/src/utilities/archiveWriter.vala b/src/utilities/archiveWriter.vala new file mode 100644 index 0000000..92bd31b --- /dev/null +++ b/src/utilities/archiveWriter.vala @@ -0,0 +1,139 @@ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// 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 3 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, see <http://www.gnu.org/licenses/>. +///////////////////////////////////////////////////////////////////////// + +namespace GnomePie { + +///////////////////////////////////////////////////////////////////////// +/// This class can be used to pack a directory of files recursively into +/// a *.tar.gz archive. +///////////////////////////////////////////////////////////////////////// + +public class ArchiveWriter : GLib.Object { + + private Archive.Write archive; + + ///////////////////////////////////////////////////////////////////// + /// Constructs a new ArchiveWriter + ///////////////////////////////////////////////////////////////////// + + public ArchiveWriter() { + this.archive = new Archive.Write(); + this.archive.add_filter_gzip(); + this.archive.set_format_pax_restricted(); + + } + + ///////////////////////////////////////////////////////////////////// + /// Call this once after you created the ArchiveWriter. Pass the + /// path to the target archive location. + ///////////////////////////////////////////////////////////////////// + + public bool open(string path) { + return this.archive.open_filename(path) == Archive.Result.OK; + } + + ///////////////////////////////////////////////////////////////////// + /// Adds all files of a given directory to the previously opened + /// archive. + ///////////////////////////////////////////////////////////////////// + + public bool add(string directory) { + return add_directory(directory, directory); + } + + ///////////////////////////////////////////////////////////////////// + /// When all files have been added, close the directory again. + ///////////////////////////////////////////////////////////////////// + + public void close() { + this.archive.close(); + } + + ///////////////////////////////////////////////////////////////////// + /// Private helper function which traveres a directory recursively. + ///////////////////////////////////////////////////////////////////// + + private bool add_directory(string directory, string relative_to) { + try { + var d = Dir.open(directory); + string name; + while ((name = d.read_name()) != null) { + string path = Path.build_filename(directory, name); + if (FileUtils.test(path, FileTest.IS_DIR)) { + if (!add_directory(path, relative_to)) { + return false; + } + + } else if (FileUtils.test(path, FileTest.IS_REGULAR)) { + if (!add_file(path, relative_to)) { + return false; + } + + } else { + warning("Packaging theme: Ignoring irregular file " + name); + } + } + } catch (Error e) { + warning (e.message); + return false; + } + + return true; + + } + + ///////////////////////////////////////////////////////////////////// + /// Private halper which adds a file to the archive. + ///////////////////////////////////////////////////////////////////// + + public bool add_file(string path, string relative_to) { + var entry = new Archive.Entry(); + entry.set_pathname(path.replace(relative_to, "")); + + Posix.Stat st; + Posix.stat(path, out st); + entry.copy_stat(st); + entry.set_size(st.st_size); + + if (this.archive.write_header(entry) == Archive.Result.OK) { + try { + var reader = File.new_for_path(path).read(); + uint8 buffer[4096]; + + var len = reader.read(buffer); + + while(len > 0) { + this.archive.write_data(buffer, len); + len = reader.read(buffer); + } + + this.archive.finish_entry(); + } catch (Error e) { + warning (e.message); + return false; + } + + } else { + warning("Failed to include file " + path + " into archive"); + return false; + } + + return true; + } +} + +} diff --git a/src/utilities/config.vala b/src/utilities/config.vala index 538602d..5dedddb 100644 --- a/src/utilities/config.vala +++ b/src/utilities/config.vala @@ -161,7 +161,9 @@ public class Config : GLib.Object { load_themes(theme_name); - if (error_occrured) save(); + if (error_occrured) { + save(); + } } ///////////////////////////////////////////////////////////////////// @@ -177,18 +179,19 @@ public class Config : GLib.Object { // load global themes var d = Dir.open(Paths.global_themes); while ((name = d.read_name()) != null) { - var theme = new Theme(Paths.global_themes + "/" + name); + var new_theme = new Theme(Paths.global_themes + "/" + name); - if (theme.load()) - themes.add(theme); + if (new_theme.load()) { + themes.add(new_theme); + } } // load local themes d = Dir.open(Paths.local_themes); while ((name = d.read_name()) != null) { - var theme = new Theme(Paths.local_themes + "/" + name); - if (theme.load()) - themes.add(theme); + var new_theme = new Theme(Paths.local_themes + "/" + name); + if (new_theme.load()) + themes.add(new_theme); } } catch (Error e) { @@ -211,10 +214,26 @@ public class Config : GLib.Object { warning("Theme \"" + current + "\" not found! Using fallback..."); } theme.load_images(); + } else { + error("No theme found!"); } - else error("No theme found!"); } + ///////////////////////////////////////////////////////////////////// + /// Returns true if a loaded theme has the given name or is in a + /// directory with the given name. + ///////////////////////////////////////////////////////////////////// + + public bool has_theme(string name) { + + foreach (var theme in themes) { + if (theme.name == name || theme.directory.has_suffix(name)) { + return true; + } + } + + return false; + } } } |