diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/crunchy.geany crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/crunchy.geany --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/crunchy.geany 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/crunchy.geany 2016-05-16 15:31:29.000000000 +0000 @@ -17,31 +17,36 @@ long_line_column=80 [files] -current_page=19 +current_page=28 FILE_NAME_0=8449;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FAboutWindow.vala;0;4 -FILE_NAME_1=3990;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FCreateArchiveWindow.vala;0;4 -FILE_NAME_2=4348;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FCrunchyGtk.vala;0;4 +FILE_NAME_1=44030;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FCreateArchiveWindow.vala;0;4 +FILE_NAME_2=2074;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FCrunchyGtk.vala;0;4 FILE_NAME_3=3169;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FCustomMessageDialog.vala;0;4 FILE_NAME_4=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FDonationWindow.vala;0;4 -FILE_NAME_5=1622;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FGtkHelper.vala;0;4 +FILE_NAME_5=1025;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FGtkHelper.vala;0;4 FILE_NAME_6=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FPasswordDialog.vala;0;4 -FILE_NAME_7=15882;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FProgressWindow.vala;0;4 +FILE_NAME_7=18929;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FProgressWindow.vala;0;4 FILE_NAME_8=7656;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FPropertiesWindow.vala;0;4 -FILE_NAME_9=3680;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FSettingsDialog.vala;0;4 +FILE_NAME_9=2881;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FSettingsDialog.vala;0;4 FILE_NAME_10=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FSimpleProgressWindow.vala;0;4 -FILE_NAME_11=57031;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FViewArchiveWindow.vala;0;4 -FILE_NAME_12=5792;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FAsyncTask.vala;0;4 -FILE_NAME_13=2886;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FFileItem.vala;0;4 -FILE_NAME_14=15067;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FMain.vala;0;4 +FILE_NAME_11=3074;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FGtk%2FViewArchiveWindow.vala;0;4 +FILE_NAME_12=7379;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FAsyncTask.vala;0;4 +FILE_NAME_13=11062;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FFileItem.vala;0;4 +FILE_NAME_14=10961;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FMain.vala;0;4 FILE_NAME_15=4538;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FMimeTypes.vala;0;4 -FILE_NAME_16=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FThunarMenuEntry.vala;0;4 -FILE_NAME_17=18098;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FUtility.vala;0;4 -FILE_NAME_18=8778;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fselene%2Fsrc%2FBatchEditWindow.vala;0;4 -FILE_NAME_19=31515;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Faptik%2Fsrc%2FMainWindow.vala;0;4 -FILE_NAME_20=60004;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fselene%2Fsrc%2FEncoderConfigWindow.vala;0;4 -FILE_NAME_21=2007;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FArchiveFile.vala;0;4 -FILE_NAME_22=18722;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FArchiver.vala;0;4 -FILE_NAME_23=839;Make;0;EUTF-8;1;1;1;%2Fmnt%2Fsdcard%2FDropbox%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fmakefile;0;4 +FILE_NAME_16=5522;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FThunarMenuEntry.vala;0;4 +FILE_NAME_17=3659;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FUtility.vala;0;4 +FILE_NAME_18=2385;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FArchiveFile.vala;0;4 +FILE_NAME_19=2526;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2FCommon%2FArchiver.vala;0;4 +FILE_NAME_20=179;None;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fdebian%2Fchangelog;0;4 +FILE_NAME_21=627;Conf;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fdebian%2Fcontrol;0;4 +FILE_NAME_22=0;Python;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy.py;0;4 +FILE_NAME_23=0;None;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy-compress.nemo_action;0;4 +FILE_NAME_24=0;Python;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy-compress.py;0;4 +FILE_NAME_25=0;None;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy-extract-here.nemo_action;0;4 +FILE_NAME_26=620;Python;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy-extract-here.py;0;4 +FILE_NAME_27=0;None;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy-extract-to.nemo_action;0;4 +FILE_NAME_28=944;Python;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Fcrunchy%2Fsrc%2Fshare%2Fcrunchy%2Factions%2Fcrunchy-extract-to.py;0;4 [VTE] last_dir=/home/teejee diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/debian/bzr-builder.manifest crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/debian/bzr-builder.manifest --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/debian/bzr-builder.manifest 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/debian/bzr-builder.manifest 2016-05-16 15:31:29.000000000 +0000 @@ -1,2 +1,2 @@ -# bzr-builder format 0.3 deb-version {debupstream}~4 -lp:aptik-7zip revid:tony.george.kol@gmail.com-20160513163404-4yaow33zrut32u16 +# bzr-builder format 0.3 deb-version {debupstream}~18 +lp:aptik-7zip revid:tony.george.kol@gmail.com-20160516152139-f63vqmb8vqmfd01g diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/debian/changelog crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/debian/changelog --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/debian/changelog 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/debian/changelog 2016-05-16 15:31:29.000000000 +0000 @@ -1,11 +1,20 @@ -crunchy-archive-manager (16.5.1~4~ubuntu16.04.1) xenial; urgency=low +crunchy-archive-manager (16.5.2~18~ubuntu16.04.1) xenial; urgency=low * Auto build. - -- Tony George Fri, 13 May 2016 16:55:22 +0000 + -- Tony George Mon, 16 May 2016 15:31:29 +0000 -crunchy-archive-manager (16.5.1) xenial; urgency=low +crunchy-archive-manager (16.5.2) xenial; urgency=low * Renamed project to Crunchy Archive Manager - -- Tony George Thu, 12 Sep 2016 10:00:00 +0530 + * Fixed: Show error message when archive creation fails + + * Fixed: Error on creating archive with LZMA and Store + + * Fixed: Archive title was not parsed correctly for creating subdir + in action: --extract-same + + * Remove temp files on exit + + -- Tony George Mon, 16 May 2016 10:00:00 +0530 diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/NOTES crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/NOTES --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/NOTES 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/NOTES 2016-05-16 15:31:29.000000000 +0000 @@ -3,5 +3,7 @@ 7z x '/home/teejee/aam/samples/atom.7z' -so '-w/tmp/crunchy/0t9VJHWD/14616630804292682152/rrsv6Nh3' -y -bb1 -p -- > /dev/null -* 7zip cannot handle LZOP files (both single or tarred). TAR can list TAR.LZO files. LZO files can be listed only with 'lzop -l'. LZO can store multiple files but cannot store paths (directories). +* 7zip cannot handle LZOP files (both single or tarred). TAR can list tarred LZO files. LZO files can be listed only with 'lzop -l'. LZO can store multiple files but cannot store paths (directories). + +* xz supports multi-threaded compression with v5.2 onwards. However, it doesn't seem to be working with v5.2.2? pixz has limited options and the file format is pxz (indexed XZ) instead of xz. diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/ArchiveFile.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/ArchiveFile.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/ArchiveFile.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/ArchiveFile.vala 2016-05-16 15:31:29.000000000 +0000 @@ -62,6 +62,7 @@ public ArchiveFile(string archive_file_path = "") { base.from_path_and_type(archive_file_path, FileType.REGULAR); is_archive = true; + source_archive = this; //this.tag = this; @@ -72,6 +73,13 @@ dir_create (temp_dir); } + public void remove_temp_files(){ + if (dir_exists(temp_dir)){ + log_debug("Removing temp dir: %s".printf(temp_dir)); + dir_delete(temp_dir); + } + } + public void add_items(Gee.ArrayList item_list){ if (item_list.size > 0){ foreach(string item in item_list){ diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/Archiver.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/Archiver.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/Archiver.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/Archiver.vala 2016-05-16 15:31:29.000000000 +0000 @@ -75,8 +75,6 @@ public double compression_ratio; private static Gee.HashMap regex_list; - private MatchInfo match; - private double dblVal; public static string 7zip_version_name = ""; @@ -95,11 +93,17 @@ //Example: Extracting packages/option.d.ts //Example: Compressing packages/option.d.ts //Example: Compressing packages/option.d.ts 100% - regex_list["7z"] = new Regex("""[^ \t]{3,}[ ]{2}(.*)"""); + regex_list["7z"] = new Regex("""[A-Za-z]{3,}[ ]{1,2}([^ \t]+)"""); + + // --- % 22.7 MiB / 100.9 MiB = 0.225 3.2 MiB/s 0:31 + regex_list["xz"] = new Regex("""^[ \t]*[0-9\-]* %[ \t]*([0-9.]+ [KMGiB]+) \/ ([0-9.]+ [KMGiB]+) = ([0-9.]+)[ \t]*([0-9.]+) [KMGiB]+\/s[ \t]*[0-9:.]+"""); // 20% 12653 - atom/packages/atom-beautify/node_modules/.bin/uuid regex_list["7z1509"] = new Regex("""^[ \t]*([0-9]+)%[ \t]*[0-9]*[ \t]*-[ \t]*(.*)"""); + // 50M + regex_list["7z_size"] = new Regex("""^[ \t]*([0-9]+)M$"""); + //- atom/packages/atom-beautify/node_modules/.bin/uuid regex_list["7z1509prg"] = new Regex("""^[ \t]*([0-9]+)%[ \t]*.*"""); @@ -217,22 +221,27 @@ cmd += " '%s'".printf(escape_single_quote(file_basename(item.file_path))); } cmd += " | "; - cmd += "pv --size %lld -n".printf(archive.size); - cmd += " | "; + //cmd += "pv --size %lld -n".printf(archive.size); + //cmd += " | "; parser_name = "pv"; } //main archiver options switch (format) { + case "xz": + case "tar_xz": + // use xz program + //cmd += get_commands_compress_xz(); + //parser_name = "xz"; + //archiver_name = "xz"; + //break; case "7z": case "tar_7z": case "bz2": case "tar_bz2": case "gz": case "tar_gz": - case "xz": - case "tar_xz": case "zip": case "tar_zip": // use 7zip program @@ -295,7 +304,8 @@ public string get_commands_compress_7zip(){ string cmd = ""; - cmd += "7z a -bd"; + cmd += "7z a"; + //cmd += " -bd"; // take password from archiver (not archive) if (password.length > 0) { @@ -310,7 +320,9 @@ case "7z": case "tar_7z": cmd += " -t7z"; - cmd += " -m0=" + method; //format supports multiple methods + if (method.length > 0){ + cmd += " -m0=" + method; //format supports multiple methods + } break; case "bz2": case "tar_bz2": @@ -330,7 +342,9 @@ case "zip": case "tar_zip": cmd += " -tZip"; - cmd += " -mm=" + method; //format supports multiple methods + if (method.length > 0){ + cmd += " -mm=" + method; //format supports multiple methods + } break; } @@ -355,27 +369,49 @@ switch (method) { case "lzma": case "lzma2": - cmd += " -mx" + level; - cmd += " -md=" + dict_size; - cmd += " -mfb=" + word_size; + if (level.length > 0){ + cmd += " -mx" + level; + } + if (dict_size.length > 0){ + cmd += " -md=" + dict_size; + } + if (word_size.length > 0){ + cmd += " -mfb=" + word_size; + } break; case "ppmd": - cmd += " -mmem=" + dict_size; - cmd += " -mo=" + word_size; + if (dict_size.length > 0){ + cmd += " -mmem=" + dict_size; + } + if (word_size.length > 0){ + cmd += " -mo=" + word_size; + } break; case "bzip2": - cmd += " -mx" + level; - cmd += " -md=" + dict_size; - cmd += " -mpass=" + passes; + if (level.length > 0){ + cmd += " -mx" + level; + } + if (dict_size.length > 0){ + cmd += " -md=" + dict_size; + } + if (passes.length > 0){ + cmd += " -mpass=" + passes; + } break; case "deflate": case "deflate64": - cmd += " -mx" + level; - cmd += " -mfb=" + word_size; - cmd += " -mpass=" + passes; + if (level.length > 0){ + cmd += " -mx" + level; + } + if (word_size.length > 0){ + cmd += " -mfb=" + word_size; + } + if (passes.length > 0){ + cmd += " -mpass=" + passes; + } break; case "copy": @@ -392,10 +428,10 @@ case "lzma2": case "ppmd": case "bzip2": - if (block_size == "non-solid") { + if (block_size == "non-solid"){ cmd += " -ms=off"; } - else { + else if (block_size.length > 0){ cmd += " -ms=" + block_size; } break; @@ -441,6 +477,57 @@ return cmd; } + + public string get_commands_compress_xz(){ + string cmd = ""; + + cmd += "xz --compress --stdout --keep --verbose"; + + /* encryption not supported for XZ (only zip, 7z, bz2) */ + + switch (method) { + //case "lzma": + case "lzma2": + cmd += " --lzma2="; + if (level.length > 0){ + cmd += "preset=%s,".printf(level); + } + if (dict_size.length > 0){ + cmd += "dict=%s,".printf(dict_size); + } + cmd += "nice=%s".printf(word_size); + break; + } + + // TODO: split into volumes + //if (split_mb != "0"){ + // cmd += " -v%sm".printf(split_mb); + //} + + // verbose output + //if (Archiver.7zip_version >= 15.05){ + // cmd += " -bb1 -bsp1"; + //} + + // input file + if (format.has_prefix("tar_")) { + cmd += " -"; + } + else{ + foreach (string key in archive.children.keys) { + var item = archive.children[key]; + cmd += " '%s'".printf(escape_single_quote(item.file_path)); + break; // supports single file only + } + } + + //output file + if (archive.file_path.length > 0) { + cmd += " > '%s'".printf(escape_single_quote(archive.file_path)); + } + + return cmd; + } public string get_commands_compress_lzop(){ string cmd = ""; @@ -816,6 +903,8 @@ if (is_terminated) { return; } + + //log_msg(out_line); update_progress_parse_console_output(out_line); } @@ -824,6 +913,13 @@ if (is_terminated) { return; } + + // log error messages + MatchInfo match; + if (!regex_list["pv"].match(err_line, 0, out match)) { + log_error(err_line); + error_msg += err_line + "\n"; + } update_progress_parse_console_output(err_line); } @@ -840,7 +936,7 @@ if (line.down().contains("wrong password?")){ archive.archive_is_encrypted = true; - //stop task if password is not specified + // stop task if password is not specified if (archive.password.length == 0){ log_error(_("Password not set for encrypted archive")); is_terminated = true; @@ -849,6 +945,10 @@ } } + MatchInfo match; + double dblVal; + string txt = ""; + switch (parser_name) { case "pv": if (regex_list[parser_name].match(line, 0, out match)) { @@ -857,6 +957,26 @@ } break; + case "xz": + if (regex_list["xz"].match(line, 0, out match)) { + log_debug("xz: %s".printf(line)); + + status_line = ""; + + txt = match.fetch(1); + + if (txt.contains("MiB") || txt.contains("MB")){ + prg_bytes = int64.parse(txt) * 1024 * 1024; + } + else if (txt.contains("KiB") || txt.contains("KB")){ + prg_bytes = int64.parse(txt) * 1024; + } + else if (txt.contains("B")){ + prg_bytes = int64.parse(txt); + } + } + break; + case "7z": if (regex_list["7z"].match(line, 0, out match)) { log_debug("7z: %s".printf(line)); @@ -864,14 +984,22 @@ status_line = match.fetch(1); if (!status_line.has_suffix("/")){ processed_file_count += 1; + prg_count += 1; } } else if (regex_list["7z1509"].match(line, 0, out match)) { log_debug("7z1509: %s".printf(line)); - + status_line = match.fetch(2); progress = double.parse(match.fetch(1)); } + else if (regex_list["7z_size"].match(line, 0, out match)) { + log_debug("7z_size: %s".printf(line)); + + status_line = ""; + prg_bytes = int64.parse(match.fetch(1)) * 1024 * 1024; + progress = ((prg_bytes * 1.0) / prg_bytes_total); + } else if (regex_list["7z1509prg"].match(line, 0, out match)) { log_debug("7z1509prg: %s".printf(line)); @@ -1040,6 +1168,7 @@ item.source_archive = archive; } break; + case "zpaq": log_debug("zpaq: " + line); break; @@ -1090,7 +1219,7 @@ } // set some values for estimating progress - + prg_bytes_total = archive.size; log_debug("data_size: %lld".printf(prg_bytes_total)); @@ -1124,9 +1253,15 @@ } // set some values for estimating progress - prg_bytes_total = file_get_size(archive.file_path); + prg_bytes_total = file_get_size(archive.file_path) * 3; // assuming a ratio of 30% log_debug("archive_size: %lld".printf(prg_bytes_total)); - + + /* Note: Since we have not read the file we don't know the size of data in the archive. + * For 7z and zip this will be set by parsing the output during extraction. + * For tarred files, we never know the exact size so the estimated value is used. + * We are estimating the total bytes assuming an average compression ratio of 30% + * */ + // begin execute(arch, wait); } @@ -1153,9 +1288,15 @@ } // set some values for estimating progress - prg_bytes_total = file_get_size(archive.file_path); + prg_bytes_total = file_get_size(archive.file_path) * 3; // assuming a ratio of 30% log_debug("archive_size: %lld".printf(prg_bytes_total)); + /* Note: Since we have not read the file we don't know the size of data in the archive. + * For 7z and zip this will be set by parsing the output during extraction. + * For tarred files, we never know the exact size so the estimated value is used. + * We are estimating the total bytes assuming an average compression ratio of 30% + * */ + execute(arch, wait); } @@ -1233,8 +1374,8 @@ //log_debug("prg_count_total: %.0f, Progress: %.0f".printf(progress)); - if (percent > 0){ - progress = percent; + if (prg_percent > 0){ + progress = prg_percent; log_debug("Percent: Progress: %.2f".printf(progress)); } else if ((prg_count_total > 0) && (prg_count > 0)){ diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/AsyncTask.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/AsyncTask.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/AsyncTask.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/AsyncTask.vala 2016-05-16 15:31:29.000000000 +0000 @@ -5,19 +5,13 @@ using TeeJee.Misc; public abstract class AsyncTask : GLib.Object{ - - private string err_line = ""; - private string out_line = ""; - //protected string temp_line = ""; + private DataOutputStream dos_in; private DataInputStream dis_out; private DataInputStream dis_err; protected DataOutputStream dos_log; protected bool is_terminated = false; - private bool stdout_is_open = false; - private bool stderr_is_open = false; - protected Pid child_pid; private int input_fd; private int output_fd; @@ -37,7 +31,7 @@ public string error_msg = ""; public GLib.Timer timer; public double progress = 0.0; - public double percent = 0.0; + public double prg_percent = 0.0; public int64 prg_count = 0; public int64 prg_count_total = 0; public int64 prg_bytes = 0; @@ -57,11 +51,14 @@ public bool begin(){ bool has_started = true; is_terminated = false; - + + progress = 0; + prg_percent = 0; prg_count = 0; prg_bytes = 0; error_msg = ""; - + status_line = ""; + string[] spawn_args = new string[1]; spawn_args[0] = script_file; @@ -80,7 +77,7 @@ working_dir, // working dir spawn_args, // argv spawn_env, // environment - SpawnFlags.SEARCH_PATH, + SpawnFlags.SEARCH_PATH|SpawnFlags.DO_NOT_REAP_CHILD, null, // child_setup out child_pid, out input_fd, @@ -90,17 +87,12 @@ set_priority(); log_debug("AsyncTask: child_pid: %d".printf(child_pid)); - - // create stream readers - UnixOutputStream uos_in = new UnixOutputStream(input_fd, false); - UnixInputStream uis_out = new UnixInputStream(output_fd, false); - UnixInputStream uis_err = new UnixInputStream(error_fd, false); - dos_in = new DataOutputStream(uos_in); - dis_out = new DataInputStream(uis_out); - dis_err = new DataInputStream(uis_err); - dis_out.newline_type = DataStreamNewlineType.ANY; - dis_err.newline_type = DataStreamNewlineType.ANY; + // add watch for process exit + ChildWatch.add (child_pid, (pid, status) => { + finish(); + }); + // create log file if (log_file.length > 0){ var file = File.new_for_path (log_file); @@ -110,22 +102,43 @@ var file_stream = file.create (FileCreateFlags.REPLACE_DESTINATION); dos_log = new DataOutputStream (file_stream); } + + // stdin + var uos_in = new UnixOutputStream(input_fd, false); + dos_in = new DataOutputStream(uos_in); + // create stream readers + + UnixInputStream uis_out = new UnixInputStream(output_fd, false); + dis_out = new DataInputStream(uis_out); + dis_out.newline_type = DataStreamNewlineType.ANY; + + UnixInputStream uis_err = new UnixInputStream(error_fd, false); + dis_err = new DataInputStream(uis_err); + dis_err.newline_type = DataStreamNewlineType.ANY; + try { //start thread for reading output stream - Thread.create (read_stdout, true); - } catch (Error e) { - log_error (e.message); + //Thread.create (read_stdout, true); + new Thread.try("read_stdout_thread", read_stdout); + } + catch (Error e) { + log_error ("AsyncTask.begin():create_thread:read_stdout()"); + log_error(e.message); } try { //start thread for reading error stream - Thread.create (read_stderr, true); + //Thread.create (read_stderr, true); + new Thread.try("read_stderr_thread", read_stderr); } catch (Error e) { - log_error (e.message); + log_error ("AsyncTask.begin():create_thread:read_stderr()"); + log_error(e.message); } } catch (Error e) { + log_error ("AsyncTask.begin()"); + log_error(e.message); is_running = false; has_started = false; //status = AppStatus.FINISHED; @@ -134,11 +147,62 @@ return has_started; } - private void read_stdout() { - try { - stdout_is_open = true; + private void add_watch_for_output() { + // stdout + IOChannel output = new IOChannel.unix_new (output_fd); + output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { + if (condition == IOCondition.HUP) { + GLib.FileUtils.close(output_fd); + log_debug("fd closed: %s".printf("stdout")); + return false; + } + + try { + string out_line; + channel.read_line (out out_line, null, null); + out_line = out_line.replace("\r","").replace("\n",""); + + parse_stdout_line(out_line); + stdout_line_read(out_line); + return true; + } + catch (Error e) { + log_error("AsyncTask:begin():read_line():stdout"); + log_error(e.message); + return false; + } - out_line = dis_out.read_line (null); + }); + + // stderr + IOChannel error = new IOChannel.unix_new (error_fd); + error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { + if (condition == IOCondition.HUP) { + GLib.FileUtils.close(error_fd); + log_debug("fd closed: %s".printf("stderr")); + return false; + } + + try { + string err_line; + channel.read_line (out err_line, null, null); + err_line = err_line.replace("\r","").replace("\n",""); + + parse_stderr_line(err_line); + stderr_line_read(err_line); + return true; + } + catch (Error e) { + log_error("AsyncTask:begin():read_line():stderr"); + log_error(e.message); + return false; + } + }); + } + + private bool read_stdout() { + try { + var out_line = dis_out.read_line (null); while (out_line != null) { //log_msg("O: " + out_line); if (!is_terminated && (out_line.length > 0)){ @@ -147,70 +211,60 @@ } out_line = dis_out.read_line (null); //read next } + } + catch (Error e) { + log_error ("AsyncTask.read_stdout():read_line"); + log_error (e.message); + } - stdout_is_open = false; - + try{ // dispose stdout - dis_out.close(); - dis_out = null; - GLib.FileUtils.close(output_fd); - - // check if complete - if (!stdout_is_open && !stderr_is_open){ - finish(); + if ((dis_out != null) && !dis_out.is_closed()){ + dis_out.close(); } } catch (Error e) { + log_error ("AsyncTask.read_stdout():dispose"); log_error (e.message); } + + dis_out = null; + GLib.FileUtils.close(output_fd); + return false; } - private void read_stderr() { + private bool read_stderr() { try { - stderr_is_open = true; - - err_line = dis_err.read_line (null); + var err_line = dis_err.read_line (null); while (err_line != null) { + //log_msg("E: " + out_line); if (!is_terminated && (err_line.length > 0)){ - log_error(err_line); error_msg += "%s\n".printf(err_line); - parse_stderr_line(err_line); stderr_line_read(err_line); //signal } err_line = dis_err.read_line (null); //read next } - - stderr_is_open = false; - - // dispose stderr - dis_err.close(); - dis_err = null; - GLib.FileUtils.close(error_fd); - - // check if complete - if (!stdout_is_open && !stderr_is_open){ - finish(); - } } catch (Error e) { + log_error ("AsyncTask.read_stderr():read_line"); log_error (e.message); } - } - - public void write_stdin(string line){ - try{ - if (status == AppStatus.RUNNING){ - dos_in.put_string(line + "\n"); - } - else{ - log_error ("AsyncTask.write_stdin(): NOT RUNNING"); + + try { + // dispose stderr + if ((dis_err != null) && !dis_err.is_closed()){ + dis_err.close(); } } - catch(Error e){ - log_error ("AsyncTask.write_stdin(): %s".printf(line)); + catch (Error e) { + log_error ("AsyncTask.read_stderr():dispose"); log_error (e.message); } + + dis_err = null; + GLib.FileUtils.close(error_fd); + return false; } protected abstract void parse_stdout_line(string out_line); @@ -218,32 +272,25 @@ protected abstract void parse_stderr_line(string err_line); private void finish(){ + // dispose stdin - try{ - dos_in.close(); - } - catch(Error e){ - log_error ("AsyncTask.finish(): dos_in.close()"); - log_error (e.message); - } - - dos_in = null; GLib.FileUtils.close(input_fd); - // dispose child process - Process.close_pid(child_pid); //required on Windows, doesn't do anything on Unix - try{ // dispose log - if (dos_log != null){ - dos_log.close(); - dos_log = null; - } + dos_log.close(); + dos_log = null; } catch (Error e) { - log_error (e.message); + // error can be ignored + // dos_log is closed automatically when the last reference is set to null + // there may be pending operations which may throw an error } + // close process + Process.close_pid (child_pid); + log_debug("Process closed"); + read_exit_code(); is_running = false; diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/Main.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/Main.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/Main.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/Main.vala 2016-05-16 15:31:29.000000000 +0000 @@ -37,7 +37,7 @@ public Main App; public const string AppName = "Crunchy Archive Manager"; public const string AppShortName = "crunchy"; -public const string AppVersion = "16.5.1"; +public const string AppVersion = "16.5.2"; public const string AppAuthor = "Tony George"; public const string AppAuthorEmail = "teejeetech@gmail.com"; @@ -373,6 +373,7 @@ user_home, file_name); if (file_exists(file_py)){ + log_debug("Removed Nautilus action: %s".printf(file_name)); file_delete(file_py); } if (file_exists(file_pyc)){ @@ -389,6 +390,7 @@ if (file_exists(src_file) && !file_exists(dst_file)){ dir_create(file_parent(dst_file)); file_copy(src_file,dst_file); + log_debug("Added Nautilus action: %s".printf(file_name)); } } } @@ -403,6 +405,7 @@ user_home, file_name); if (file_exists(file_py)){ + log_debug("Removed Nautilus action: %s".printf(file_name)); file_delete(file_py); } if (file_exists(file_pyc)){ @@ -430,6 +433,7 @@ if (file_exists(src_file) && !file_exists(dst_file)){ dir_create(file_parent(dst_file)); file_copy(src_file,dst_file); + log_debug("Added Nemo action: %s".printf(file_name)); } } } @@ -442,6 +446,7 @@ if (file_exists(file_nemo)){ file_delete(file_nemo); + log_debug("Removed Nemo action: %s".printf(file_name)); } } } @@ -485,7 +490,7 @@ log_error (e.message); } - log_debug("\n" + _("App config saved") + ": '%s'".printf(app_conf_path)); + log_msg("\n" + _("App config saved") + ": '%s'".printf(app_conf_path)); } public void load_app_config() { @@ -516,23 +521,12 @@ use_large_icons_file_pane = json_get_bool(config, "use_large_icons_file_pane", false); hide_nav_pane = json_get_bool(config, "hide_nav_pane", false); - log_debug(_("App config loaded") + ": '%s'".printf(this.app_conf_path)); + log_msg(_("App config loaded") + ": '%s'".printf(this.app_conf_path)); } public void exit_app() { save_app_config(); - - try { - //delete temporary files - var f = File.new_for_path(temp_dir); - if (f.query_exists()) { - f.delete(); - } - } - catch (Error e) { - log_error (e.message); - } - + clear_tmp(); log_msg(_("Exiting Application")); } @@ -572,7 +566,7 @@ // select a subfolder in source path for extraction archiver.extraction_path = "%s/%s".printf( file_parent(archive.file_path), - file_basename(archive.file_path).split(".")[0]); + file_title(archive.file_path)); /* since user has not specified the directory we need to * make sure that files are not overwritten accidentally @@ -596,6 +590,39 @@ archiver.extraction_path = arg_outpath; } } + + public void merge_nested_extraction_directories(){ + if (arg_same_path && dir_exists(archiver.extraction_path)){ + try { + File file = File.parse_name(archiver.extraction_path); + FileInfo info; + var list = new Gee.ArrayList(); + var enumerator = file.enumerate_children ("%s".printf(FileAttribute.STANDARD_NAME), 0); + while ((info = enumerator.next_file()) != null) { + string child_path = GLib.Path.build_filename( + archiver.extraction_path, + info.get_name()); + + list.add(child_path); + } + + if ((list.size == 1) && (dir_exists(list[0]))){ + // move the nested folder one level up + var src = list[0]; + var dst = archiver.extraction_path; + var dst_tmp = GLib.Path.build_filename(file_parent(dst), random_string()); + if (dir_exists(src)){ + file_move(src, dst_tmp); + } + file_delete(dst); + file_move(dst_tmp, dst); + } + } + catch (Error e) { + log_error (e.message); + } + } + } public ArchiveFile new_archive() { archive = new ArchiveFile(); diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/ThunarMenuEntry.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/ThunarMenuEntry.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/ThunarMenuEntry.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/ThunarMenuEntry.vala 2016-05-16 15:31:29.000000000 +0000 @@ -216,6 +216,8 @@ action->new_text_child (null, "other-files", ""); } + log_debug("Added Thunar action: %s".printf(name)); + doc->save_file(xml_path); delete doc; @@ -284,6 +286,8 @@ } } + log_debug("Removed Thunar action: %s".printf(name)); + doc->save_file(xml_path); delete doc; diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/Utility.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/Utility.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Common/Utility.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Common/Utility.vala 2016-05-16 15:31:29.000000000 +0000 @@ -173,6 +173,15 @@ return File.new_for_path(file_path).get_basename(); } + public string file_title(string file_path){ + string txt = file_basename(file_path); + string title = txt[0:txt.last_index_of(".")]; + if (title.has_suffix(".tar")){ + title = title[0:txt.last_index_of(".tar")]; + } + return title; + } + // file helpers ----------------------------- public bool file_exists (string file_path){ @@ -783,6 +792,12 @@ //log_debug("TEMP_DIR=" + TEMP_DIR); } + public static void clear_tmp(){ + if (dir_exists(TEMP_DIR)){ + dir_delete(TEMP_DIR); + } + } + public string create_temp_subdir(){ var temp = "%s/%s".printf(TEMP_DIR, random_string()); dir_create(temp); diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/CreateArchiveWindow.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/CreateArchiveWindow.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/CreateArchiveWindow.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/CreateArchiveWindow.vala 2016-05-16 15:31:29.000000000 +0000 @@ -1,7 +1,7 @@ /* * CreateArchiveWindow.vala * - * Copyright 2015 Tony George + * Copyright 2016 Tony George * * 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 @@ -74,16 +74,13 @@ //private uint tmr_init = 0; public CreateArchiveWindow() { - destroy.connect(Gtk.main_quit); window_position = WindowPosition.CENTER; - init_window(); } public CreateArchiveWindow.with_parent(Window parent) { set_transient_for(parent); window_position = WindowPosition.CENTER_ON_PARENT; - init_window(); } @@ -103,6 +100,7 @@ // vbox_main var vbox_content = get_content_area(); vbox_content.margin = 6; + vbox_content.margin_right = 12; vbox_content.spacing = 6; vbox_main = new Box (Orientation.VERTICAL, 6); @@ -128,7 +126,7 @@ btn_commands.visible = false; load_selections(); - + set_default_archive_title_and_location(); init_command_area_update(); } @@ -168,8 +166,10 @@ try { task_is_running = true; - Thread.create (add_files_thread, true); - } catch (ThreadError e) { + //Thread.create (add_files_thread, true); + new Thread.try("add_files_thread", add_files_thread); + } + catch (Error e) { task_is_running = false; log_error (e.message); } @@ -191,9 +191,10 @@ gtk_do_events(); } - private void add_files_thread() { + private bool add_files_thread() { App.archive.add_items(App.arg_files); task_is_running = false; + return false; } // archive options ----------------------------------------------- @@ -1194,7 +1195,10 @@ } private void dict_size_changed() { - cmb_dict_size.sensitive = (((TreeModel) cmb_dict_size.model).iter_n_children(null) > 1); + if (cmb_dict_size.model != null){ + var model = (TreeModel) cmb_dict_size.model; + cmb_dict_size.sensitive = (model.iter_n_children(null) > 1); + } cmb_dict_size.visible = (dict_size.length > 0) && show_comp_advanced; } @@ -1360,7 +1364,10 @@ } private void word_size_changed() { - cmb_word_size.sensitive = (((TreeModel) cmb_word_size.model).iter_n_children(null) > 1); + if (cmb_word_size.model != null){ + var model = (TreeModel) cmb_word_size.model; + cmb_word_size.sensitive = (model.iter_n_children(null) > 1); + } cmb_word_size.visible = (word_size.length > 0) && show_comp_advanced; } @@ -1482,7 +1489,10 @@ } private void block_size_changed() { - cmb_block_size.sensitive = (((TreeModel) cmb_block_size.model).iter_n_children(null) > 1); + if (cmb_block_size.model != null){ + var model = (TreeModel) cmb_block_size.model; + cmb_block_size.sensitive = (model.iter_n_children(null) > 1); + } cmb_block_size.visible = (block_size.length > 0) && show_comp_advanced; } @@ -1734,8 +1744,8 @@ vbox_main.add(hbox); // label - var label = new Gtk.Label(_("Algorithm")); - label.xalign = (float) 0.0; + var label = new Gtk.Label(_("Method")); + label.xalign = (float) 1.0; hbox.add(label); size_label.add_widget(label); @@ -1927,6 +1937,8 @@ compress(); }); + btn_compress.grab_focus(); + // btn_cancel btn_cancel = (Gtk.Button) add_button(_("Cancel"), Gtk.ResponseType.CANCEL); diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/CrunchyGtk.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/CrunchyGtk.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/CrunchyGtk.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/CrunchyGtk.vala 2016-05-16 15:31:29.000000000 +0000 @@ -106,6 +106,10 @@ //start event loop Gtk.main(); + //if (App.archiver.dis_out != null){ + // log_msg(App.archiver.dis_out.is_closed().to_string()); + //} + App.exit_app(); return 0; diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/GtkHelper.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/GtkHelper.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/GtkHelper.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/GtkHelper.vala 2016-05-16 15:31:29.000000000 +0000 @@ -53,7 +53,8 @@ gtk_do_events (); } - public void gtk_messagebox(string title, string message, Gtk.Window? parent_win, bool is_error = false, bool hide_icon = false){ + public void gtk_messagebox(string title, string message, Gtk.Window? parent_win, + bool is_error = false, bool hide_icon = false){ /* Shows a simple message box */ diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/ProgressWindow.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/ProgressWindow.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/ProgressWindow.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/ProgressWindow.vala 2016-05-16 15:31:29.000000000 +0000 @@ -67,7 +67,6 @@ private bool task_is_running = false; public ProgressWindow() { - destroy.connect(Gtk.main_quit); init_window(); } @@ -92,11 +91,9 @@ init_labels(); init_progress_bar(); init_command_buttons(); - + show_all(); - log_msg("show_all()"); - gtk_do_events(); tmr_init = Timeout.add(500, init_delayed); @@ -366,8 +363,9 @@ //------ END CONTEXT --------------------------------------------------- } - - if ((App.archiver.action == ArchiveAction.CREATE)&&(App.archive.compression_ratio > 0)) { + if ((App.archiver.action == ArchiveAction.CREATE) + && (App.archiver.compression_ratio > 0)) { + //------ BEGIN CONTEXT ------------------------------------------------- //Draw compression ratio text @@ -381,7 +379,7 @@ x = 0; } context.move_to (x + 3, y + 3); - context.show_text("%.0f %%".printf(App.archive.compression_ratio)); + context.show_text("%.0f %%".printf(App.archiver.compression_ratio)); context.stroke(); //------ END CONTEXT --------------------------------------------------- } @@ -649,14 +647,16 @@ switch (App.archiver.action){ case ArchiveAction.CREATE: + break; case ArchiveAction.EXTRACT: + if (App.arg_same_path){ + App.merge_nested_extraction_directories(); + } break; case ArchiveAction.TEST: gtk_messagebox("","Archive is OK",this,false); break; } - - this.close(); } else if ((App.archiver.action == ArchiveAction.LIST) && (App.archive.archive_type.length == 0) @@ -670,9 +670,12 @@ else{ // valid archive, error switch (App.archiver.action){ + case ArchiveAction.CREATE: case ArchiveAction.TEST: case ArchiveAction.EXTRACT: - gtk_messagebox("",_("There were errors while processing the archive.") + "\n\n" + App.archiver.error_msg,this,true); + var msg = _("There were errors while processing the archive.") + "\n\n"; + msg += App.archiver.error_msg.strip(); + gtk_messagebox("Error", msg ,this,true); break; } } diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/SettingsDialog.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/SettingsDialog.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/SettingsDialog.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/SettingsDialog.vala 2016-05-16 15:31:29.000000000 +0000 @@ -36,9 +36,6 @@ public class SettingsDialog : Gtk.Dialog { private Gtk.Notebook notebook; private Gtk.TreeView tv_mime; - private Gtk.CheckButton chk_add_context_menu; - private Gtk.CheckButton chk_add_context_submenu; - private Gtk.CheckButton chk_associate_archives; private Gtk.ComboBox cmb_app; public SettingsDialog.with_parent(Window parent) { @@ -102,10 +99,11 @@ // add_context_menu var chk = new Gtk.CheckButton.with_label(_("Add right-click menu entries") + "*"); + chk.set_tooltip_text(_("Supports Gnome Files, Nautilus, Nemo and Thunar. Changes will take effect on the next login or after restarting the file manager.")); chk.active = App.add_context_menu; chk.margin_left = 6; vbox.add(chk); - chk_add_context_menu = chk; + var chk_add_context_menu = chk; chk.toggled.connect(()=>{ App.add_context_menu = chk_add_context_menu.active; @@ -113,10 +111,11 @@ // chk_add_context_submenu chk = new Gtk.CheckButton.with_label(_("Display items in a submenu (Nautilus only)")); + chk.set_tooltip_text("Items will be shown in submenu named 'Crunchy' instead of being added directly to the right-click menu"); chk.active = App.add_context_submenu; chk.margin_left = 6; vbox.add(chk); - chk_add_context_submenu = chk; + var chk_add_context_submenu = chk; chk.toggled.connect(()=>{ App.add_context_submenu = chk_add_context_submenu.active; @@ -130,7 +129,7 @@ vbox.add (label); // chk_small_icons_nav_pane - chk = new Gtk.CheckButton.with_label(_("Use small icons for navigation pane")); + chk = new Gtk.CheckButton.with_label(_("Use large icons for navigation pane")); chk.active = App.use_large_icons_nav_pane; chk.margin_left = 6; vbox.add(chk); @@ -141,7 +140,7 @@ }); // chk_small_icons_file_pane - chk = new Gtk.CheckButton.with_label(_("Use small icons for file view")); + chk = new Gtk.CheckButton.with_label(_("Use large icons for file view")); chk.active = App.use_large_icons_file_pane; chk.margin_left = 6; vbox.add(chk); @@ -161,23 +160,6 @@ chk.toggled.connect(()=>{ App.hide_nav_pane = chk_hide_nav_pane.active; }); - - // message label --------- - - label = new Label("* " + _("Supports Nautilus, Nemo and Thunar. Changes will take effect on the next login or after restarting the file manager.") + ""); - label.set_use_markup(true); - label.xalign = (float) 0.0; - label.yalign = (float) 1.0; - label.margin_bottom = 6; - label.wrap = true; - label.wrap_mode = Pango.WrapMode.WORD; - label.max_width_chars = 50; - //label.width_chars = 50; - vbox.pack_end (label); - - chk.toggled.connect(()=>{ - App.associate_archives = chk_associate_archives.active; - }); } private void init_ui_tab_mimetypes(){ diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/ViewArchiveWindow.vala crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/ViewArchiveWindow.vala --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/Gtk/ViewArchiveWindow.vala 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/Gtk/ViewArchiveWindow.vala 2016-05-16 15:31:29.000000000 +0000 @@ -96,11 +96,8 @@ private SimpleProgressWindow dlg_open; public ViewArchiveWindow() { - destroy.connect(Gtk.main_quit); - archive_list = new Gee.ArrayList(); selected_archives = new Gee.ArrayList(); - init_window(); } @@ -469,6 +466,7 @@ tv_files = new TreeView(); tv_files.get_selection().mode = SelectionMode.MULTIPLE; tv_files.headers_clickable = true; + tv_files.show_expanders = false; tv_files.rubber_banding = true; tv_files.has_tooltip = true; tv_files.set_rules_hint (true); @@ -1007,7 +1005,7 @@ // remove linkbutton padding var provider = new Gtk.CssProvider(); var css = """ - GtkLinkButton { padding-left: 1; padding-right: 1;} + GtkLinkButton { padding-left: 1px; padding-right: 1px;} """; try { provider.load_from_data(css,-1); @@ -1191,7 +1189,8 @@ current_task = (ArchiveFile) item.source_archive; current_item = item; - App.archive = (ArchiveFile) item.source_archive; + + App.archive = current_task; // check if close icon was clicked ----------- @@ -1199,7 +1198,10 @@ archive_list.remove(current_task); current_task = null; current_item = null; + + App.archive.remove_temp_files(); App.archive = null; + tv_nav_refresh(); } @@ -1300,7 +1302,7 @@ private void tv_files_refresh() { log_debug("tv_files_refresh()"); - var model = new Gtk.ListStore(2, typeof(FileItem), typeof(bool)); + var model = new Gtk.TreeStore(2, typeof(FileItem), typeof(bool)); TreeIter iter; if (current_item == null){ @@ -1408,7 +1410,7 @@ dummy.parent = current_item.parent; //add row for parent dir - model.append(out iter); + model.append(out iter, null); model.set (iter, 0, dummy); } @@ -1419,7 +1421,7 @@ odd_row = !odd_row; //add row - model.append(out iter); + model.append(out iter, null); model.set (iter, 0, item, 1, odd_row); if (!first_iter_found) { @@ -1454,9 +1456,10 @@ log_debug("tv_files_row_activated()"); TreeIter iter; - tv_files.model.get_iter_from_string(out iter, path.to_string()); + Gtk.TreeStore model = (Gtk.TreeStore) tv_files.model; + model.get_iter_from_string(out iter, path.to_string()); FileItem item; - tv_files.model.get (iter, 0, out item, -1); + model.get (iter, 0, out item, -1); change_current_item(item); } @@ -2086,7 +2089,8 @@ App.progress_count = App.archive.size; - log_msg("read: %'ld / %'ld".printf(App.archive.size,App.archive.archive_unpacked_size)); + log_debug("read: %'ld / %'ld".printf( + App.archive.size,App.archive.archive_unpacked_size)); //dlg_open.update_progressbar(); set_statusbar_summary(); diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/makefile crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/makefile --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/makefile 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/makefile 2016-05-16 15:31:29.000000000 +0000 @@ -14,7 +14,7 @@ #build binaries #crunchy-gtk - valac -X -D'GETTEXT_PACKAGE="${app_name}"' --Xcc="-lm" -X -Wl,-rpath,/usr/share/${app_name}/libs --thread Common/*.vala Gtk/*.vala -o "${app_name}-gtk" --pkg glib-2.0 --pkg gio-unix-2.0 --pkg posix --pkg gtk+-3.0 --pkg gee-0.8 --pkg libsoup-2.4 --pkg json-glib-1.0 --pkg libxml-2.0 + valac -X -D'GETTEXT_PACKAGE="${app_name}"' --Xcc="-lm" -X -Wl,-rpath,/usr/share/${app_name}/libs --thread Common/*.vala Gtk/*.vala -o "${app_name}-gtk" --target-glib 2.32 --pkg glib-2.0 --pkg gio-unix-2.0 --pkg posix --pkg gtk+-3.0 --pkg gee-0.8 --pkg libsoup-2.4 --pkg json-glib-1.0 --pkg libxml-2.0 #update translation template #xgettext --language=C --keyword=_ --copyright-holder='Tony George (teejee2008@gmail.com)' --package-name='${app_name}' --package-version='1.6' --msgid-bugs-address='teejee2008@gmail.com' --escape --sort-output --from-code=UTF-8 -o ../${app_name}.pot *.vala diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.nemo_action crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.nemo_action --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.nemo_action 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.nemo_action 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -[Nemo Action] - -Active=true - -# Standard tokens that can be used in the Name, Comment (tooltip) and Exec fields: -# -# %U - insert URI list of selection -# %F - insert path list of selection -# %P - insert path of parent (current) directory -# %f or %N (deprecated) - insert display name of first selected file -# %p - insert display name of parent directory -# %D - insert device path of file (i.e. /dev/sdb1) - - -# The name to show in the menu, locale supported with standard desktop spec. -# **** REQUIRED **** -Name=Compress... - -# Tool tip, locale supported (Appears in the status bar) -Comment=Add selected files and folders to a new archive - -# What to run. Enclose in < > to run an executable that resides in the actions folder. -# **** REQUIRED **** -#Exec=gedit %F -Exec=crunchy-gtk --compress %F - -# Icon name to use in the menu - must be a theme icon name -Icon-Name= - -# Gtk Stock ID to use for the icon. Note if both Icon-name and Stock-Id are -# defined, the Stock-Id takes precedence. -#Stock-Id=gtk-cdrom - -# What type selection: [s]ingle, [m]ultiple, any, notnone, none (background click), or -# a number representing how many files must be selected to display. -# ****** REQUIRED ******* -Selection=notnone - -# What extensions to display on - this is an array, end with a semicolon -# Single entry options, ending in a semicolon: -# "dir" for directory selection -# "none" for no extension. -# "nodirs" for any selection, but not including directories. -# "any" for any file type, including directories. -# Individual specific extensions can be a semicolon-terminated list -# Extensions are NOT case sensitive. jpg will match JPG, jPg, jpg, etc.. -# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** -Extensions=any; - -# What mime-types to display on - this is an array, end with a semicolon -# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** -#Mimetypes=text/plain; - -# Separator to use (if any) - add a string to insert between path/url entries -# in the exec line. Optional - if you leave this out, a space is inserted. -# Note you can have trailing spaces here. -#Separator=, - -# Quote type to use (if any) - enclose paths/urls with quotes. Optional - defaults -# to no quotes. -# Can be: single, double, backtick -Quote=double - -# Dependencies - program executables required for this action to work. Nemo will -# Search in the path for these program(s) and not display the action if any are missing. -# You can also supply an absolute path to a file (i.e. /usr/lib/gvfs/gvfsd-archive) to check -# instead of or in addition to an executable in the path. -# This is an array, separate entries with semi-colon, and terminate with a semicolon. -Dependencies=crunchy-gtk; - -# Conditions - semicolon-separated array of special conditions: -# "desktop" current (parent) folder is desktop -# "removable" target (first selection) is removable -# "gsettings " is true -# "gsettings <[eq|ne|gt|lt]> " -# "dbus " exists - -#Conditions=desktop; - -# Escape Spaces - set to true to escape spaces in filenames and uris ($U, $F, $P, $D) -# -# Sometimes this may be preferred to getting raw filenames that must be enclosed in -# quotes. -# -# Optional - by default this is false -#EscapeSpaces=true diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.py 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-compress.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -from gi.repository import Nautilus, GObject -import os -import subprocess -import urllib - -class CrunchyCompress(GObject.GObject, Nautilus.MenuProvider): - def __init__(self): - pass - - def url2path(self,url): - fileuri= url.get_activation_uri() - arg_uri=fileuri[7:] - path=urllib.url2pathname(arg_uri) - return path - - def compress(self,menu,files): - cmd=['crunchy-gtk','--create'] - return self.execute_for_all(menu,cmd,files) - - def execute_for_all(self,menu,cmd,files): - for file in files: - filepath=self.url2path(file) - cmd.append(filepath) - return subprocess.Popen(cmd) - - def isdir(self,files): - isdir=False - for file in files: - mime= file.get_mime_type() - if mime =='inode/directory': - isdir=True - else: - isdir=False - return isdir - - def isfile(self,files): - isfile=False - for file in files: - mime= file.get_mime_type() - if mime !='inode/directory': - isfile=True - else: - isfile=False - return isfile - - def get_file_items(self, window, files): - filecount=len(files) - if filecount <= 0: - return - - # compress - menu_item = Nautilus.MenuItem(name='CrunchyCompressMenuItem::CrunchyCompress', - label='Compress...', - tip='Compress selected files and folders', - ) - - menu_item.connect('activate',self.compress,files) - - return [menu_item] diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.nemo_action crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.nemo_action --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.nemo_action 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.nemo_action 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -[Nemo Action] - -Active=true - -# Standard tokens that can be used in the Name, Comment (tooltip) and Exec fields: -# -# %U - insert URI list of selection -# %F - insert path list of selection -# %P - insert path of parent (current) directory -# %f or %N (deprecated) - insert display name of first selected file -# %p - insert display name of parent directory -# %D - insert device path of file (i.e. /dev/sdb1) - - -# The name to show in the menu, locale supported with standard desktop spec. -# **** REQUIRED **** -Name=Extract to - -# Tool tip, locale supported (Appears in the status bar) -Comment=Extract files to subfolder - -# What to run. Enclose in < > to run an executable that resides in the actions folder. -# **** REQUIRED **** -#Exec=gedit %F -Exec=crunchy-gtk --extract-same %F - -# Icon name to use in the menu - must be a theme icon name -Icon-Name= - -# Gtk Stock ID to use for the icon. Note if both Icon-name and Stock-Id are -# defined, the Stock-Id takes precedence. -#Stock-Id=gtk-cdrom - -# What type selection: [s]ingle, [m]ultiple, any, notnone, none (background click), or -# a number representing how many files must be selected to display. -# ****** REQUIRED ******* -Selection=notnone - -# What extensions to display on - this is an array, end with a semicolon -# Single entry options, ending in a semicolon: -# "dir" for directory selection -# "none" for no extension. -# "nodirs" for any selection, but not including directories. -# "any" for any file type, including directories. -# Individual specific extensions can be a semicolon-terminated list -# Extensions are NOT case sensitive. jpg will match JPG, jPg, jpg, etc.. -# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** -Extensions=nodirs; - -# What mime-types to display on - this is an array, end with a semicolon -# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** -#Mimetypes=text/plain; - -# Separator to use (if any) - add a string to insert between path/url entries -# in the exec line. Optional - if you leave this out, a space is inserted. -# Note you can have trailing spaces here. -#Separator=, - -# Quote type to use (if any) - enclose paths/urls with quotes. Optional - defaults -# to no quotes. -# Can be: single, double, backtick -Quote=double - -# Dependencies - program executables required for this action to work. Nemo will -# Search in the path for these program(s) and not display the action if any are missing. -# You can also supply an absolute path to a file (i.e. /usr/lib/gvfs/gvfsd-archive) to check -# instead of or in addition to an executable in the path. -# This is an array, separate entries with semi-colon, and terminate with a semicolon. -Dependencies=crunchy-gtk; - -# Conditions - semicolon-separated array of special conditions: -# "desktop" current (parent) folder is desktop -# "removable" target (first selection) is removable -# "gsettings " is true -# "gsettings <[eq|ne|gt|lt]> " -# "dbus " exists - -#Conditions=desktop; - -# Escape Spaces - set to true to escape spaces in filenames and uris ($U, $F, $P, $D) -# -# Sometimes this may be preferred to getting raw filenames that must be enclosed in -# quotes. -# -# Optional - by default this is false -#EscapeSpaces=true diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.py 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-here.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -from gi.repository import Nautilus, GObject -import os -import subprocess -import urllib - -class CrunchyExtractHere(GObject.GObject, Nautilus.MenuProvider): - def __init__(self): - pass - - def url2path(self,url): - fileuri= url.get_activation_uri() - arg_uri=fileuri[7:] - path=urllib.url2pathname(arg_uri) - return path - - def extract_here(self,menu,files): - for file in files: - cmd=['crunchy-gtk','--extract-same'] - filepath=self.url2path(file) - cmd.append(filepath) - proc = subprocess.Popen(cmd) - proc.wait() - return - - def is_files(self,files): - for file in files: - mime=file.get_mime_type() - if mime == 'inode/directory': - return False - return True - - def get_file_items(self, window, files): - filecount=len(files) - if filecount <= 0: - return - - if filecount == 1: - filepath=self.url2path(files[0]) - name=os.path.basename(filepath) - label='Extract to ' + os.path.splitext(name)[0] + '/' - else: - label='Extract to ' - - if self.is_files(files) == True : - # extract to folder - menu_item = Nautilus.MenuItem(name='CrunchyExtractHereMenuItem::CrunchyExtractHere', - label=label, - tip='Extract files to subfolder ' - ) - menu_item.connect('activate',self.extract_here,files) - return [menu_item] - else: - return - diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.nemo_action crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.nemo_action --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.nemo_action 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.nemo_action 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -[Nemo Action] - -Active=true - -# Standard tokens that can be used in the Name, Comment (tooltip) and Exec fields: -# -# %U - insert URI list of selection -# %F - insert path list of selection -# %P - insert path of parent (current) directory -# %f or %N (deprecated) - insert display name of first selected file -# %p - insert display name of parent directory -# %D - insert device path of file (i.e. /dev/sdb1) - - -# The name to show in the menu, locale supported with standard desktop spec. -# **** REQUIRED **** -Name=Extract To... - -# Tool tip, locale supported (Appears in the status bar) -Comment=Extract files to specified location - -# What to run. Enclose in < > to run an executable that resides in the actions folder. -# **** REQUIRED **** -#Exec=gedit %F -Exec=crunchy-gtk --extract-ask %F - -# Icon name to use in the menu - must be a theme icon name -Icon-Name=crunchy - -# Gtk Stock ID to use for the icon. Note if both Icon-name and Stock-Id are -# defined, the Stock-Id takes precedence. -#Stock-Id=gtk-cdrom - -# What type selection: [s]ingle, [m]ultiple, any, notnone, none (background click), or -# a number representing how many files must be selected to display. -# ****** REQUIRED ******* -Selection=notnone - -# What extensions to display on - this is an array, end with a semicolon -# Single entry options, ending in a semicolon: -# "dir" for directory selection -# "none" for no extension. -# "nodirs" for any selection, but not including directories. -# "any" for any file type, including directories. -# Individual specific extensions can be a semicolon-terminated list -# Extensions are NOT case sensitive. jpg will match JPG, jPg, jpg, etc.. -# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** -Extensions=nodirs; - -# What mime-types to display on - this is an array, end with a semicolon -# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** -#Mimetypes=text/plain; - -# Separator to use (if any) - add a string to insert between path/url entries -# in the exec line. Optional - if you leave this out, a space is inserted. -# Note you can have trailing spaces here. -#Separator=, - -# Quote type to use (if any) - enclose paths/urls with quotes. Optional - defaults -# to no quotes. -# Can be: single, double, backtick -Quote=double - -# Dependencies - program executables required for this action to work. Nemo will -# Search in the path for these program(s) and not display the action if any are missing. -# You can also supply an absolute path to a file (i.e. /usr/lib/gvfs/gvfsd-archive) to check -# instead of or in addition to an executable in the path. -# This is an array, separate entries with semi-colon, and terminate with a semicolon. -Dependencies=crunchy-gtk; - -# Conditions - semicolon-separated array of special conditions: -# "desktop" current (parent) folder is desktop -# "removable" target (first selection) is removable -# "gsettings " is true -# "gsettings <[eq|ne|gt|lt]> " -# "dbus " exists - -#Conditions=desktop; - -# Escape Spaces - set to true to escape spaces in filenames and uris ($U, $F, $P, $D) -# -# Sometimes this may be preferred to getting raw filenames that must be enclosed in -# quotes. -# -# Optional - by default this is false -#EscapeSpaces=true diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.py 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch-extract-to.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -from gi.repository import Nautilus, GObject -import os -import subprocess -import urllib - -class CrunchyExtractTo(GObject.GObject, Nautilus.MenuProvider): - def __init__(self): - pass - - def url2path(self,url): - fileuri= url.get_activation_uri() - arg_uri=fileuri[7:] - path=urllib.url2pathname(arg_uri) - return path - - def extract_to(self,menu,files): - for file in files: - cmd=['crunchy-gtk'] - filepath=self.url2path(files[0]) - cmd.append("--extract-ask") - cmd.append(filepath) - subprocess.Popen(cmd) - break - return - - def is_files(self,files): - for file in files: - mime=file.get_mime_type() - if mime == 'inode/directory': - return False - return True - - def get_file_items(self, window, files): - filecount=len(files) - if filecount <= 0: - return - - if self.is_files(files) == True : - # extract to - menu_item = Nautilus.MenuItem(name='CrunchyExtractToMenuItem::CrunchyExtractTo', - label='Extract To...', - tip='Extract files to specified location' - ) - menu_item.connect('activate',self.extract_to,files) - return [menu_item] - else: - return diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunch.py 2016-05-13 16:55:22.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunch.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -from gi.repository import Nautilus, GObject -import os -import subprocess -import urllib - -class Crunchy(GObject.GObject, Nautilus.MenuProvider): - def __init__(self): - pass - - def url2path(self,url): - fileuri= url.get_activation_uri() - arg_uri=fileuri[7:] - path=urllib.url2pathname(arg_uri) - return path - - def compress(self,menu,files): - cmd=['crunchy-gtk','--create'] - return self.execute_for_all(menu,cmd,files) - - def test(self,menu,files): - cmd=['crunchy-gtk','--test'] - return self.execute_for_first(menu,cmd,files) - - def extract_here(self,menu,files): - for file in files: - cmd=['crunchy-gtk','--extract-same'] - filepath=self.url2path(file) - cmd.append(filepath) - proc = subprocess.Popen(cmd) - proc.wait() - return - - def extract_to(self,menu,files): - for file in files: - cmd=['crunchy-gtk'] - filepath=self.url2path(files[0]) - cmd.append("--extract-to") - cmd.append(filepath) - subprocess.Popen(cmd) - break - return - - def execute_for_all(self,menu,cmd,files): - for file in files: - filepath=self.url2path(file) - cmd.append(filepath) - return subprocess.Popen(cmd) - - def execute_for_first(self,menu,cmd,files): - for file in files: - filepath=self.url2path(file) - cmd.append(filepath) - break; - return subprocess.Popen(cmd) - - def execute_for_each(self,menu,cmd,files): - for file in files: - filepath=self.url2path(file) - cmd.append(filepath) - subprocess.Popen(cmd) - return subprocess.Popen(cmd) - - def is_files(self,files): - for file in files: - mime=file.get_mime_type() - if mime == 'inode/directory': - return False - return True - - def get_file_items(self, window, files): - filecount=len(files) - if filecount <= 0: - return - - top_menu = Nautilus.MenuItem(name='CrunchySubMenu::Crunchy', - label='Crunchy', - tip='', - ) - - sub_menu = Nautilus.Menu() - top_menu.set_submenu(sub_menu) - - # compress - menu_item = Nautilus.MenuItem(name='CrunchyMenuItem::CrunchyCompress', - label='Compress...', - tip='Compress selected files and folders' - ) - sub_menu.append_item(menu_item) - menu_item.connect('activate',self.compress,files) - - if filecount == 1: - filepath=self.url2path(files[0]) - name=os.path.basename(filepath) - label='Extract to ' + os.path.splitext(name)[0] + '/' - else: - label='Extract to ' - - if is_files(files) == True: - - # extract here - menu_item = Nautilus.MenuItem(name='CrunchyMenuItem::CrunchyExtractHere', - label=label, - tip='Extract files to subfolder' - ) - sub_menu.append_item(menu_item) - menu_item.connect('activate',self.extract_here,files) - - # extract to - menu_item = Nautilus.MenuItem(name='CrunchyMenuItem::CrunchyExtractTo', - label='Extract To...', - tip='Extract files in archive to specified location' - ) - sub_menu.append_item(menu_item) - menu_item.connect('activate',self.extract_to,files) - - return [top_menu] diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.nemo_action crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.nemo_action --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.nemo_action 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.nemo_action 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,86 @@ +[Nemo Action] + +Active=true + +# Standard tokens that can be used in the Name, Comment (tooltip) and Exec fields: +# +# %U - insert URI list of selection +# %F - insert path list of selection +# %P - insert path of parent (current) directory +# %f or %N (deprecated) - insert display name of first selected file +# %p - insert display name of parent directory +# %D - insert device path of file (i.e. /dev/sdb1) + + +# The name to show in the menu, locale supported with standard desktop spec. +# **** REQUIRED **** +Name=Compress... + +# Tool tip, locale supported (Appears in the status bar) +Comment=Add selected files and folders to a new archive + +# What to run. Enclose in < > to run an executable that resides in the actions folder. +# **** REQUIRED **** +#Exec=gedit %F +Exec=crunchy-gtk --compress %F + +# Icon name to use in the menu - must be a theme icon name +Icon-Name= + +# Gtk Stock ID to use for the icon. Note if both Icon-name and Stock-Id are +# defined, the Stock-Id takes precedence. +#Stock-Id=gtk-cdrom + +# What type selection: [s]ingle, [m]ultiple, any, notnone, none (background click), or +# a number representing how many files must be selected to display. +# ****** REQUIRED ******* +Selection=notnone + +# What extensions to display on - this is an array, end with a semicolon +# Single entry options, ending in a semicolon: +# "dir" for directory selection +# "none" for no extension. +# "nodirs" for any selection, but not including directories. +# "any" for any file type, including directories. +# Individual specific extensions can be a semicolon-terminated list +# Extensions are NOT case sensitive. jpg will match JPG, jPg, jpg, etc.. +# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** +Extensions=any; + +# What mime-types to display on - this is an array, end with a semicolon +# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** +#Mimetypes=text/plain; + +# Separator to use (if any) - add a string to insert between path/url entries +# in the exec line. Optional - if you leave this out, a space is inserted. +# Note you can have trailing spaces here. +#Separator=, + +# Quote type to use (if any) - enclose paths/urls with quotes. Optional - defaults +# to no quotes. +# Can be: single, double, backtick +Quote=double + +# Dependencies - program executables required for this action to work. Nemo will +# Search in the path for these program(s) and not display the action if any are missing. +# You can also supply an absolute path to a file (i.e. /usr/lib/gvfs/gvfsd-archive) to check +# instead of or in addition to an executable in the path. +# This is an array, separate entries with semi-colon, and terminate with a semicolon. +Dependencies=crunchy-gtk; + +# Conditions - semicolon-separated array of special conditions: +# "desktop" current (parent) folder is desktop +# "removable" target (first selection) is removable +# "gsettings " is true +# "gsettings <[eq|ne|gt|lt]> " +# "dbus " exists + +#Conditions=desktop; + +# Escape Spaces - set to true to escape spaces in filenames and uris ($U, $F, $P, $D) +# +# Sometimes this may be preferred to getting raw filenames that must be enclosed in +# quotes. +# +# Optional - by default this is false +#EscapeSpaces=true diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.py 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-compress.py 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,59 @@ +from gi.repository import Nautilus, GObject +import os +import subprocess +import urllib + +class CrunchyCompress(GObject.GObject, Nautilus.MenuProvider): + def __init__(self): + pass + + def url2path(self,url): + fileuri= url.get_activation_uri() + arg_uri=fileuri[7:] + path=urllib.url2pathname(arg_uri) + return path + + def compress(self,menu,files): + cmd=['crunchy-gtk','--create'] + return self.execute_for_all(menu,cmd,files) + + def execute_for_all(self,menu,cmd,files): + for file in files: + filepath=self.url2path(file) + cmd.append(filepath) + return subprocess.Popen(cmd) + + def isdir(self,files): + isdir=False + for file in files: + mime= file.get_mime_type() + if mime =='inode/directory': + isdir=True + else: + isdir=False + return isdir + + def isfile(self,files): + isfile=False + for file in files: + mime= file.get_mime_type() + if mime !='inode/directory': + isfile=True + else: + isfile=False + return isfile + + def get_file_items(self, window, files): + filecount=len(files) + if filecount <= 0: + return + + # compress + menu_item = Nautilus.MenuItem(name='CrunchyCompressMenuItem::CrunchyCompress', + label='Compress...', + tip='Compress selected files and folders', + ) + + menu_item.connect('activate',self.compress,files) + + return [menu_item] diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.nemo_action crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.nemo_action --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.nemo_action 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.nemo_action 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,86 @@ +[Nemo Action] + +Active=true + +# Standard tokens that can be used in the Name, Comment (tooltip) and Exec fields: +# +# %U - insert URI list of selection +# %F - insert path list of selection +# %P - insert path of parent (current) directory +# %f or %N (deprecated) - insert display name of first selected file +# %p - insert display name of parent directory +# %D - insert device path of file (i.e. /dev/sdb1) + + +# The name to show in the menu, locale supported with standard desktop spec. +# **** REQUIRED **** +Name=Extract Here + +# Tool tip, locale supported (Appears in the status bar) +Comment=Extract files to subfolder + +# What to run. Enclose in < > to run an executable that resides in the actions folder. +# **** REQUIRED **** +#Exec=gedit %F +Exec=crunchy-gtk --extract-same %F + +# Icon name to use in the menu - must be a theme icon name +Icon-Name= + +# Gtk Stock ID to use for the icon. Note if both Icon-name and Stock-Id are +# defined, the Stock-Id takes precedence. +#Stock-Id=gtk-cdrom + +# What type selection: [s]ingle, [m]ultiple, any, notnone, none (background click), or +# a number representing how many files must be selected to display. +# ****** REQUIRED ******* +Selection=notnone + +# What extensions to display on - this is an array, end with a semicolon +# Single entry options, ending in a semicolon: +# "dir" for directory selection +# "none" for no extension. +# "nodirs" for any selection, but not including directories. +# "any" for any file type, including directories. +# Individual specific extensions can be a semicolon-terminated list +# Extensions are NOT case sensitive. jpg will match JPG, jPg, jpg, etc.. +# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** +Extensions=nodirs; + +# What mime-types to display on - this is an array, end with a semicolon +# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** +#Mimetypes=text/plain; + +# Separator to use (if any) - add a string to insert between path/url entries +# in the exec line. Optional - if you leave this out, a space is inserted. +# Note you can have trailing spaces here. +#Separator=, + +# Quote type to use (if any) - enclose paths/urls with quotes. Optional - defaults +# to no quotes. +# Can be: single, double, backtick +Quote=double + +# Dependencies - program executables required for this action to work. Nemo will +# Search in the path for these program(s) and not display the action if any are missing. +# You can also supply an absolute path to a file (i.e. /usr/lib/gvfs/gvfsd-archive) to check +# instead of or in addition to an executable in the path. +# This is an array, separate entries with semi-colon, and terminate with a semicolon. +Dependencies=crunchy-gtk; + +# Conditions - semicolon-separated array of special conditions: +# "desktop" current (parent) folder is desktop +# "removable" target (first selection) is removable +# "gsettings " is true +# "gsettings <[eq|ne|gt|lt]> " +# "dbus " exists + +#Conditions=desktop; + +# Escape Spaces - set to true to escape spaces in filenames and uris ($U, $F, $P, $D) +# +# Sometimes this may be preferred to getting raw filenames that must be enclosed in +# quotes. +# +# Optional - by default this is false +#EscapeSpaces=true diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.py 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-here.py 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,47 @@ +from gi.repository import Nautilus, GObject +import os +import subprocess +import urllib + +class CrunchyExtractHere(GObject.GObject, Nautilus.MenuProvider): + def __init__(self): + pass + + def url2path(self,url): + fileuri= url.get_activation_uri() + arg_uri=fileuri[7:] + path=urllib.url2pathname(arg_uri) + return path + + def extract_here(self,menu,files): + for file in files: + cmd=['crunchy-gtk','--extract-same'] + filepath=self.url2path(file) + cmd.append(filepath) + proc = subprocess.Popen(cmd) + proc.wait() + return + + def is_files(self,files): + for file in files: + mime=file.get_mime_type() + if mime == 'inode/directory': + return False + return True + + def get_file_items(self, window, files): + filecount=len(files) + if filecount <= 0: + return + + if self.is_files(files) == True : + # extract to folder + menu_item = Nautilus.MenuItem(name='CrunchyExtractHereMenuItem::CrunchyExtractHere', + label='Extract Here', + tip='Extract files to subfolder' + ) + menu_item.connect('activate',self.extract_here,files) + return [menu_item] + else: + return + diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.nemo_action crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.nemo_action --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.nemo_action 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.nemo_action 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,86 @@ +[Nemo Action] + +Active=true + +# Standard tokens that can be used in the Name, Comment (tooltip) and Exec fields: +# +# %U - insert URI list of selection +# %F - insert path list of selection +# %P - insert path of parent (current) directory +# %f or %N (deprecated) - insert display name of first selected file +# %p - insert display name of parent directory +# %D - insert device path of file (i.e. /dev/sdb1) + + +# The name to show in the menu, locale supported with standard desktop spec. +# **** REQUIRED **** +Name=Extract To... + +# Tool tip, locale supported (Appears in the status bar) +Comment=Extract files to specified location + +# What to run. Enclose in < > to run an executable that resides in the actions folder. +# **** REQUIRED **** +#Exec=gedit %F +Exec=crunchy-gtk --extract-ask %F + +# Icon name to use in the menu - must be a theme icon name +Icon-Name=crunchy + +# Gtk Stock ID to use for the icon. Note if both Icon-name and Stock-Id are +# defined, the Stock-Id takes precedence. +#Stock-Id=gtk-cdrom + +# What type selection: [s]ingle, [m]ultiple, any, notnone, none (background click), or +# a number representing how many files must be selected to display. +# ****** REQUIRED ******* +Selection=notnone + +# What extensions to display on - this is an array, end with a semicolon +# Single entry options, ending in a semicolon: +# "dir" for directory selection +# "none" for no extension. +# "nodirs" for any selection, but not including directories. +# "any" for any file type, including directories. +# Individual specific extensions can be a semicolon-terminated list +# Extensions are NOT case sensitive. jpg will match JPG, jPg, jpg, etc.. +# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** +Extensions=nodirs; + +# What mime-types to display on - this is an array, end with a semicolon +# **** EITHER EXTENSIONS OR MIMETYPES IS REQUIRED ***** +#Mimetypes=text/plain; + +# Separator to use (if any) - add a string to insert between path/url entries +# in the exec line. Optional - if you leave this out, a space is inserted. +# Note you can have trailing spaces here. +#Separator=, + +# Quote type to use (if any) - enclose paths/urls with quotes. Optional - defaults +# to no quotes. +# Can be: single, double, backtick +Quote=double + +# Dependencies - program executables required for this action to work. Nemo will +# Search in the path for these program(s) and not display the action if any are missing. +# You can also supply an absolute path to a file (i.e. /usr/lib/gvfs/gvfsd-archive) to check +# instead of or in addition to an executable in the path. +# This is an array, separate entries with semi-colon, and terminate with a semicolon. +Dependencies=crunchy-gtk; + +# Conditions - semicolon-separated array of special conditions: +# "desktop" current (parent) folder is desktop +# "removable" target (first selection) is removable +# "gsettings " is true +# "gsettings <[eq|ne|gt|lt]> " +# "dbus " exists + +#Conditions=desktop; + +# Escape Spaces - set to true to escape spaces in filenames and uris ($U, $F, $P, $D) +# +# Sometimes this may be preferred to getting raw filenames that must be enclosed in +# quotes. +# +# Optional - by default this is false +#EscapeSpaces=true diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.py 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy-extract-to.py 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,47 @@ +from gi.repository import Nautilus, GObject +import os +import subprocess +import urllib + +class CrunchyExtractTo(GObject.GObject, Nautilus.MenuProvider): + def __init__(self): + pass + + def url2path(self,url): + fileuri= url.get_activation_uri() + arg_uri=fileuri[7:] + path=urllib.url2pathname(arg_uri) + return path + + def extract_to(self,menu,files): + for file in files: + cmd=['crunchy-gtk'] + filepath=self.url2path(files[0]) + cmd.append("--extract-ask") + cmd.append(filepath) + subprocess.Popen(cmd) + break + return + + def is_files(self,files): + for file in files: + mime=file.get_mime_type() + if mime == 'inode/directory': + return False + return True + + def get_file_items(self, window, files): + filecount=len(files) + if filecount <= 0: + return + + if self.is_files(files) == True : + # extract to + menu_item = Nautilus.MenuItem(name='CrunchyExtractToMenuItem::CrunchyExtractTo', + label='Extract To...', + tip='Extract files to specified location' + ) + menu_item.connect('activate',self.extract_to,files) + return [menu_item] + else: + return diff -Nru crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy.py crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy.py --- crunchy-archive-manager-16.5.1~4~ubuntu16.04.1/src/share/crunchy/actions/crunchy.py 1970-01-01 00:00:00.000000000 +0000 +++ crunchy-archive-manager-16.5.2~18~ubuntu16.04.1/src/share/crunchy/actions/crunchy.py 2016-05-16 15:31:29.000000000 +0000 @@ -0,0 +1,109 @@ +from gi.repository import Nautilus, GObject +import os +import subprocess +import urllib + +class Crunchy(GObject.GObject, Nautilus.MenuProvider): + def __init__(self): + pass + + def url2path(self,url): + fileuri= url.get_activation_uri() + arg_uri=fileuri[7:] + path=urllib.url2pathname(arg_uri) + return path + + def compress(self,menu,files): + cmd=['crunchy-gtk','--create'] + return self.execute_for_all(menu,cmd,files) + + def test(self,menu,files): + cmd=['crunchy-gtk','--test'] + return self.execute_for_first(menu,cmd,files) + + def extract_here(self,menu,files): + for file in files: + cmd=['crunchy-gtk','--extract-same'] + filepath=self.url2path(file) + cmd.append(filepath) + proc = subprocess.Popen(cmd) + proc.wait() + return + + def extract_to(self,menu,files): + for file in files: + cmd=['crunchy-gtk'] + filepath=self.url2path(files[0]) + cmd.append("--extract-to") + cmd.append(filepath) + subprocess.Popen(cmd) + break + return + + def execute_for_all(self,menu,cmd,files): + for file in files: + filepath=self.url2path(file) + cmd.append(filepath) + return subprocess.Popen(cmd) + + def execute_for_first(self,menu,cmd,files): + for file in files: + filepath=self.url2path(file) + cmd.append(filepath) + break; + return subprocess.Popen(cmd) + + def execute_for_each(self,menu,cmd,files): + for file in files: + filepath=self.url2path(file) + cmd.append(filepath) + subprocess.Popen(cmd) + return subprocess.Popen(cmd) + + def is_files(self,files): + for file in files: + mime=file.get_mime_type() + if mime == 'inode/directory': + return False + return True + + def get_file_items(self, window, files): + filecount=len(files) + if filecount <= 0: + return + + top_menu = Nautilus.MenuItem(name='CrunchySubMenu::Crunchy', + label='Crunchy', + tip='', + ) + + sub_menu = Nautilus.Menu() + top_menu.set_submenu(sub_menu) + + # compress + menu_item = Nautilus.MenuItem(name='CrunchyMenuItem::CrunchyCompress', + label='Compress...', + tip='Compress selected files and folders' + ) + sub_menu.append_item(menu_item) + menu_item.connect('activate',self.compress,files) + + if is_files(files) == True: + + # extract here + menu_item = Nautilus.MenuItem(name='CrunchyMenuItem::CrunchyExtractHere', + label='Extract Here', + tip='Extract files to subfolder' + ) + sub_menu.append_item(menu_item) + menu_item.connect('activate',self.extract_here,files) + + # extract to + menu_item = Nautilus.MenuItem(name='CrunchyMenuItem::CrunchyExtractTo', + label='Extract To...', + tip='Extract files in archive to specified location' + ) + sub_menu.append_item(menu_item) + menu_item.connect('activate',self.extract_to,files) + + return [top_menu]