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; +    }  }  }  | 
