diff --git a/AppImage/src/densify b/AppImage/src/densify index 7bb83ba..29ea7b4 100755 --- a/AppImage/src/densify +++ b/AppImage/src/densify @@ -23,11 +23,18 @@ import queue import os import re import gi +import gettext gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject from gi.overrides import GLib import pathlib +# Set user language +gettext.bindtextdomain("densify", "/usr/share/locale/") +gettext.textdomain("densify") +gettext.translation("densify") +_ = gettext.gettext + class MyWindow(Gtk.Window, threading.Thread): def __init__(self): @@ -57,7 +64,7 @@ class MyWindow(Gtk.Window, threading.Thread): window_height = 450 # Set Window Specification - Gtk.Window.__init__(self, title="Densify - PDF Compression") + Gtk.Window.__init__(self, title=_("Densify - PDF Compression")) self.set_position(Gtk.WindowPosition.CENTER) self.set_default_size(window_height, 300) self.set_resizable(True) @@ -71,8 +78,8 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(self.image, True, True, padding=1) # App About - aLabel = Gtk.Label(label="An Open Source Initiative Sponsored by 3DF") - aLabel.set_markup("An OSI application sponsored by 3DF") + aLabel = Gtk.Label(label=_("An Open Source Initiative Sponsored by 3DF")) + aLabel.set_markup(_("An OSI application sponsored by 3DF")) self.box.pack_start(aLabel, True, True, 0) # App Version @@ -89,16 +96,18 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(iLabel, True, True, 0) self.iChooser = Gtk.FileChooserButton() self.box.pack_start(self.iChooser, True, True, 0) + self.iChooser.connect("file-set", self.on_filechooserbutton_changed) +# print (self.iChooser) # Separator bar1 = Gtk.HSeparator() self.box.pack_start(bar1, True, True, 0) # Specify Compression Type - tLabel = Gtk.Label(label="Type:", xalign=0) + tLabel = Gtk.Label(label=_("Type:"), xalign=0) self.box.pack_start(tLabel, True, True, 0) store = Gtk.ListStore(str) - for item in ["ebook", "screen", "printer", "prepress", "default"]: + for item in ["ebook", _("screen"), _("printer"), _("prepress"), _("default")]: store.append([item]) self.cType = Gtk.ComboBox() self.cType.set_model(store) @@ -119,10 +128,11 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(bar2, True, True, 0) # Specify Output File - oLabel = Gtk.Label(label="Output:", xalign=0) + oLabel = Gtk.Label(label=_("Output:"), xalign=0) self.box.pack_start(oLabel, True, True, 0) self.oFile = Gtk.Entry() - self.oFile.set_placeholder_text("compressed.pdf") + self.insert = _("_compressed.pdf") + self.oFile.set_placeholder_text(self.insert) self.box.pack_start(self.oFile, True, True, 0) # Help Button - Output File @@ -135,12 +145,12 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(bar3, True, True, 0) # Progress Bar - pLabel = Gtk.Label(label="Status:", xalign=0) + pLabel = Gtk.Label(label=_("Status:"), xalign=0) self.box.pack_start(pLabel, True, True, 0) self.progressbar = Gtk.ProgressBar() self.box.pack_start(self.progressbar, True, True, 1) show_text = True - text = "Ready" + text = _("Ready") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.timeout_id = GLib.timeout_add(50, self.on_timeout, None) @@ -151,7 +161,7 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(bar4, True, True, 0) # Toggle Compress - self.button = Gtk.Button(label="Compress Now!") + self.button = Gtk.Button(label=_("Compress Now!")) self.button.set_sensitive(True) self.button.connect("clicked", self.on_button_clicked) self.box.pack_start(self.button, True, True, 0) @@ -161,17 +171,28 @@ class MyWindow(Gtk.Window, threading.Thread): treeiter = combobox.get_active_iter() model = combobox.get_model() + def on_filechooserbutton_changed(self, widget): + iName = widget.get_filename() + self.nPathIn = os.path.dirname(iName) + nNameIn = os.path.basename(iName) + nFileIn = os.path.splitext(nNameIn)[0] + self.oFile.set_text(nFileIn+self.insert) + smesg = _("File chooosen: ") +# print (smesg, nNameIn, " - ", self.nPathIn) + # Help Button Handler def on_help_clicked(self, widget): # Show Compression Type Descriptions Help Dialog - verbiage = "\n\n\nscreen:\n\nselects low-resolution output similar to the Acrobat Distiller \"Screen Optimized\" setting.\n\n\nebook:\n\nselects medium-resolution output similar to the Acrobat Distiller \"eBook\" setting.\n\n\nprinter:\n\nselects output similar to the Acrobat Distiller \"Print Optimized\" setting.\n\n\nprepress:\n\nselects output similar to Acrobat Distiller \"Prepress Optimized\" setting.\n\n\ndefault:\n\nselects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file." - self.info("Types of Compression", verbiage) + verbiage = _("\n\n\nscreen:\n\nselects low-resolution output similar to the Acrobat Distiller \"Screen Optimized\" setting.\n\n\nebook:\n\nselects medium-resolution output similar to the Acrobat Distiller \"eBook\" setting.\n\n\nprinter:\n\nselects output similar to the Acrobat Distiller \"Print Optimized\" setting.\n\n\nprepress:\n\nselects output similar to Acrobat Distiller \"Prepress Optimized\" setting.\n\n\ndefault:\n\nselects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file.") + title = _("Types of Compression") + self.info(title, verbiage) # oHelp Button Handler def on_oHelp_clicked(self, widget): # Show Output File Help Dialog - verbiage = "The output filename must not be the same as the input file name. The compressed PDF file will be placed in the same folder as your input file folder." - self.info("Output File Name", verbiage) + verbiage = _("The output filename must not be the same as the input file name. The compressed PDF file will be placed in the same folder as your input file folder.") + title = _("Output File Name") + self.info(title, verbiage) # Compression Button Handler - Where all the magic happens def on_button_clicked(self, widget): @@ -183,16 +204,17 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Command Compression Type Variable iFile = self.iChooser.get_filename() slash = "/" - oName = self.oFile.get_text() +# oName = self.oFile.get_text() + oFile = self.nPathIn+slash+self.oFile.get_text() # If Output file name was not specified, use "compressed.pdf" - if oName == None or oName == "": - oName = "compressed.pdf" +# if oName == None or oName == "": +# oName = _("compressed.pdf") # If Input file is not specified, show an error dialog box if iFile == None: # Show Error Dialog - verbiage = "The input file field is empty. Please specify an input file to compress..." + verbiage = _("The input file field is empty. Please specify an input file to compress...") self.warning("ERROR!", verbiage) # Set Progress Bar Text to "Ready" self.ready() @@ -204,8 +226,8 @@ class MyWindow(Gtk.Window, threading.Thread): # If Input file does not end with .pdf, show an error dialog box if not iFile.endswith(".pdf"): # Show Error Dialog - verbiage = "Only PDF files can be compressed with this application. Please specify a pdf file" - self.warning("ERROR!", verbiage) + verbiage = _("Only PDF files can be compressed with this application. Please specify a pdf file") + self.warning(_("ERROR!"), verbiage) # Set Progress Bar Text to "Ready" self.ready() # Enable Compress Button @@ -214,14 +236,15 @@ class MyWindow(Gtk.Window, threading.Thread): return 1 # Prep Type of Compression - Must happen before comparing iFile and oFile - if iFile != None: - iPath = str(self.iChooser.get_current_folder()) - oFile = iPath + slash + oName +# if iFile != None: +# iPath = str(self.iChooser.get_current_folder()) +# oFile = oName +# print ("In = ",iFile,"\nOut = ",oFile) # If the Input File and Output File are the same, show an error dialog box if iFile == oFile: # Show Error Dialog - verbiage = "The output file name cannot be the same as the input file name." + verbiage = _("The output file name cannot be the same as the input file name.") self.warning("ERROR!", verbiage) # Set Progress Bar Text to "Ready" self.ready() @@ -232,8 +255,8 @@ class MyWindow(Gtk.Window, threading.Thread): # If Output File does not end with .pdf, verify with user that's really what they want if not oFile.endswith(".pdf"): - verbiage = "The output file name you specified does not end with \".pdf\". Are you sure that's what you want?" - response = self.verify("Output file name does not end with \".pdf\"!", verbiage) + verbiage = _("The output file name you specified does not end with \".pdf\". Are you sure that's what you want?") + response = self.verify(_("Output file name does not end with \".pdf\"!"), verbiage) # If OK, then continue to overwrite existing file. If cancel, then stop and go back to main window if response == Gtk.ResponseType.CANCEL: @@ -249,17 +272,18 @@ class MyWindow(Gtk.Window, threading.Thread): # If Specified Input File Name Contains Unsupported Characters, Show Dialog Error Dialog Box and Return to Main Window # Security Procaution if re.search('[\\\\\|:;\`]', iName): - verbiage = "The input file name contains unsupported characters. Please ensure your input file name does not contain special characters / \\ : ; \`" - self.warning("Unsupported File Name Convention!", verbiage) + verbiage = _("The input file name contains unsupported characters. Please ensure your input file name does not contain special characters / \\ : ; \`") + self.warning(_("Unsupported File Name Convention!"), verbiage) self.button.set_sensitive(True) return 1 # If Specified Output File Name Contains Unsupported Characters, Show Dialog Error Dialog Box and Return to Main Window # Security Procaution - if re.search('[\\\\\|:;\`]', oName): - verbiage = "The output file name contains unsupported characters. Please ensure your output file name does not contain special characters / \\ : ; \`" - self.warning("Unsupported File Name Convention!", verbiage) +# if re.search('[\\\\\|:;\`]',oName): + if re.search('[\\\\\|:;\`]',oFile): + verbiage = _("The output file name contains unsupported characters. Please ensure your output file name does not contain special characters / \\ : ; \`") + self.warning(_("Unsupported File Name Convention!"), verbiage) self.button.set_sensitive(True) return 1 @@ -267,8 +291,8 @@ class MyWindow(Gtk.Window, threading.Thread): # If Specified Output File Name Matches a File in the Output Directory if os.path.isfile(oFile): # Show Error Dialog - verbiage = "There's a file with the same name, \"" + oFile + "\" already in the directory. Are you sure you want to overwrite?" - response = self.verify("WARNING!", verbiage) + verbiage = _("There's a file with the same name, \"") + oFile + _("\" already in the directory. Are you sure you want to overwrite?") + response = self.verify(_("WARNING!"), verbiage) # If OK, then continue to overwrite existing file. If cancel, then stop and go back to main window if response == Gtk.ResponseType.CANCEL: @@ -285,7 +309,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Build gs Command self.cmmd = 'gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 -dPDFSETTINGS=/' + cType + ' -dNOPAUSE -dQUIET -dBATCH -sOutputFile=' + "\"" + oFile + "\"" + ' ' + "\"" +iFile + "\"" - + # Start Compressing q = queue.Queue() cnow = threading.Thread(target=self.compress, args=[q]) @@ -302,7 +326,7 @@ class MyWindow(Gtk.Window, threading.Thread): # If try succeeds, tell user it succeeded, else, show an error dialog if success == True: # Notify User - subprocess.run(["notify-send", "PDF Compressed!"]) + subprocess.run(["notify-send", _("PDF Compressed!")]) # Get File Size iFileSizeRaw = os.path.getsize(iFile) @@ -327,15 +351,15 @@ class MyWindow(Gtk.Window, threading.Thread): self.completed() # Show Completion Dialog - Try Completed - verbiage = "Your PDF File has been successfully compressed from " + str(iFileSize) + iUnit + " to " + str(oFileSize) + oUnit + "! Enjoy!" - self.info("PDF Compressed!", verbiage) + verbiage = _("Your PDF File has been successfully compressed from ") + str(iFileSize) + iUnit + _(" to ") + str(oFileSize) + oUnit + _("! Enjoy!") + self.info(_("PDF Compressed!"), verbiage) else: # Notify User - subprocess.run(["notify-send", "ERROR!"]) + subprocess.run(["notify-send", _("ERROR!")]) # Show Error Dialog - Exception - verbiage = "Something went wrong! Maybe your PDF file is corrupted?" - self.info("ERROR!", verbiage) + verbiage = _("Something went wrong! Maybe your PDF file is corrupted?") + self.info(_("ERROR!"), verbiage) # Set Progress Bar to Ready and Stop Pulsing self.ready() @@ -381,16 +405,16 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Compressing..." and Progress Bar to Pulse def progress(self): show_text = True - text = "Compressing..." + text = _("Compressing...") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = True self.progressbar.pulse() # Set Progress Bar Text to "Ready" and Progress Bar to Stop - def ready(self): + def ready(self, *_): show_text = True - text = "Ready" + text = _("Ready") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = False @@ -401,7 +425,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Puased" and Progress Bar to Stop def pause(self): show_text = True - text = "Paused" + text = _("Paused") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = False @@ -410,7 +434,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Compressing..." and Progress Bar to Resume def resume(self): show_text = True - text = "Compressing..." + text = _("Compressing...") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = True @@ -419,7 +443,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Completed" and Progress Bar to Stop def completed(self): show_text = True - text = "Completed" + text = _("Completed") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = False @@ -435,7 +459,7 @@ class MyWindow(Gtk.Window, threading.Thread): out_queue.put(True) except: if err == None: - print("There's an error with no trace data...") + print(_("There's an error with no trace data...")) else: print(err) out_queue.put(False) diff --git a/README.md b/README.md index 8b9d87d..7e168c6 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,23 @@ -# Densify v0.3.1 -**maintained by:** hkdb \<\>
+# Squeeze v0.1.1 +**maintained by:** marianomarini \<\>
+A fork from Densify created by hkdb \<\>
## Description A GTK+ GUI Application written in Python that simplifies compressing PDF files with Ghostscript +With version v0.1.1 a watermark can be inserted in every page. ## Change Log -#### May 17th, 2020 - v0.3.1 Released +#### MAY 2th, 2023 - v0.1.0 Released -Hotfix: -- Increased "do not show logo" condition to "any display under 800 (h)" - -#### May 17th, 2020 - v0.3.0 Released - -Features: -- Added Error Handling Unsafe Character \` -- Switched to Python3 - also fixes #4 -- Allow User Resize of Window -- Desktop Notification -- Handling Lower Screen Resolutions - #5 -- Refined installation script (v0.2) - -Bug Fixes: -- Display Icon - #3 - -Notes: - -- Changed installation Procedure in README - - -### MAY 13th, 2018 - v0.2.0 Released - -Features: -- Improved error handling of filenames - [issue #2](https://github.com/hkdb/Densify/issues/2) -- Support for Chinese & other unicode file names - -Bug Fixes: -- Support whitespaces in filenames - [issue #1](https://github.com/hkdb/Densify/issues/1) - -#### MAY 13th, 2018 - v0.1.0 Released - -- Birth of Densify +- Birth of Squeeze ## Screenshots -![Screenshots](https://osi.3df.io/wp-content/uploads/2018/05/Densify-Screens.png "Screenshots") +![Screenshots](Screenshots/Squeezer-Screen.png "Screenshots") -Notice that compressed.pdf is 4M; the results from compressing a 28M pdf? I then opened up compressed.pdf and it still looked great! +Notice that compressed.pdf is 1.5M; the results from compressing a 3.8M pdf? I then opened up compressed.pdf and it still looked great! ## Under the Hood @@ -58,6 +28,7 @@ gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=[compressed.pdf] "[input.pdf]" ``` +If watermark is selected a text watermark will be included in all pages. ## Error Handling @@ -84,11 +55,11 @@ Questionable Conditions that the application will verify with User via A Dialog Step 1: -Download or Clone Densify +Download or Clone Squeezer Step 2: -Execute the install.sh script from within the downloaded Densify directory to install this application: +Execute the install.sh script from within the downloaded Squeezer directory to install this application: ``` sudo chmod a+x install.sh @@ -99,19 +70,16 @@ Enter your sudo password when the dialog pops up. You should then see this: ``` -hkdb@machine:/opt/Densify$ sudo ./install.sh +marmar@machine:/opt/Squeezer$ sudo ./install.sh Installation Complete. If you don't see any errors above, you are good to go! :) -hkdb@machine:/opt/Densify$ +marmar@machine:/opt/Squeezer$ ``` -Now, you can search for "densify" in Gnome Shell Search and you will see that Densify is available to launch. Enjoy! +Now, you can search for "squeezer" in Gnome Shell Search and you will see that Squeezer is available to launch. Enjoy! ## Future Plans -- Compile to binaries to support Linux with Nuitka -- Build Debian Packages -- Build RPM Packages -- Compile to binaries to support OS X and Windows 10 +- None ## Disclaimer @@ -119,17 +87,7 @@ This application is maintained by volunteers and in no way do the maintainers ma ## Recognition -Many thanks to Anthony Wong and Koala Yeung for talking me through this and Dr. Haggen So for sharing the following link that inspired me to write this application: - -https://www.tjansson.dk/2012/04/compressing-pdfs-using-ghostscript-under-linux/ - -This is an application utility sponsored by 3DF Limited's Open Source Initiative. - -To Learn more please visit: - -https://osi.3df.io - -https://www.3df.com.hk +Many thanks to hkdb who create Densify ## Want a CLI alternative instead? diff --git a/Screenshots/Squeezer-Screen.png b/Screenshots/Squeezer-Screen.png new file mode 100644 index 0000000..d764517 Binary files /dev/null and b/Screenshots/Squeezer-Screen.png differ diff --git a/densify.desktop b/densify.desktop deleted file mode 100755 index 9c63048..0000000 --- a/densify.desktop +++ /dev/null @@ -1,12 +0,0 @@ -[Desktop Entry] -Version=0.3.1 -Name=Densify -Comment=PDF Compressor -GenericName=Densify -Exec=/opt/Densify/densify -Path=/opt/Densify/ -Terminal=false -Type=Application -Icon=/opt/Densify/desktop-icon.png -StartupNotify=true -Categories=Utility;Application; diff --git a/desktop-icon.png b/desktop-icon.png index 3f4105c..c8789ff 100644 Binary files a/desktop-icon.png and b/desktop-icon.png differ diff --git a/header.png b/header.png index 8b09bc9..fb0f770 100644 Binary files a/header.png and b/header.png differ diff --git a/icon.png b/icon.png index 201247f..f577741 100644 Binary files a/icon.png and b/icon.png differ diff --git a/icon.xcf b/icon.xcf index 51cbe53..6d64d3f 100644 Binary files a/icon.xcf and b/icon.xcf differ diff --git a/install.sh b/install.sh index eb7d2a7..369743f 100755 --- a/install.sh +++ b/install.sh @@ -2,24 +2,27 @@ ################################################################# ### PROJECT: -### Densify +### Squeezer ### VERSION: -### v0.2.0 +### v0.1.0 ### SCRIPT: ### install.sh ### DESCRIPTION: -### Install Script for Densify +### Install Script for Squeezer ### MAINTAINED BY: -### hkdb +### Mariano Marini ### Disclaimer: ### This application is maintained by volunteers and in no way ### do the maintainers make any guarantees. Use at your own risk. ### ############################################################## -chmod a+x densify -chmod a+x densify.desktop -mkdir -p /opt/Densify -cp densify /opt/Densify -cp *.png /opt/Densify -cp densify.desktop /usr/share/applications/ +chmod a+x squeezer +chmod a+x squeezer.desktop +mkdir -p /opt/Squeezer +cp squeezer /opt/Squeezer +cp *.png /opt/Squeezer +cp *.ps /opt/Squeezer +cp squeezer.desktop /usr/share/applications/ +cp icon.png /usr/share/icons/squeezer.png +cp squeezer.mo /usr/share/locale/it/LC_MESSAGES/ echo "Installation Complete. If you don't see any errors above, you are good to go! :)" diff --git a/densify b/squeezer old mode 100755 new mode 100644 similarity index 66% rename from densify rename to squeezer index 7bb83ba..ac7bb3b --- a/densify +++ b/squeezer @@ -2,15 +2,15 @@ ################################################################# ### PROJECT: -### Densify +### Squeezer ### VERSION: -### v0.3.1 +### v0.1.0 ### SCRIPT: -### Densify +### Squeezer ### DESCRIPTION: ### GTK+ application to easily compress pdf files w/ Ghostscript ### MAINTAINED BY: -### hkdb +### Mariano Marini ### Disclaimer: ### This application is maintained by volunteers and in no way ### do the maintainers make any guarantees. Use at your own risk. @@ -23,16 +23,25 @@ import queue import os import re import gi +import gettext +import sys gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject from gi.overrides import GLib import pathlib +# Set user language +gettext.bindtextdomain("squeezer", "/usr/share/locale/") +gettext.textdomain("squeezer") +gettext.translation("squeezer") +_ = gettext.gettext + class MyWindow(Gtk.Window, threading.Thread): - def __init__(self): + def __init__(self, nomeFile): threading.Thread.__init__(self) + self.nomeFile = nomeFile # Detect Path that the script is running from: run_path = pathlib.Path(__file__).parent.absolute() header = str(run_path) + "/header.png" @@ -57,7 +66,7 @@ class MyWindow(Gtk.Window, threading.Thread): window_height = 450 # Set Window Specification - Gtk.Window.__init__(self, title="Densify - PDF Compression") + Gtk.Window.__init__(self, title=_("Squeezer - PDF Compression")) self.set_position(Gtk.WindowPosition.CENTER) self.set_default_size(window_height, 300) self.set_resizable(True) @@ -71,12 +80,12 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(self.image, True, True, padding=1) # App About - aLabel = Gtk.Label(label="An Open Source Initiative Sponsored by 3DF") - aLabel.set_markup("An OSI application sponsored by 3DF") + aLabel = Gtk.Label(label=_("A Personal Open Source Initiative by Mariano Marini")) +# aLabel.set_markup(_("An OSI application sponsored by 3DF")) self.box.pack_start(aLabel, True, True, 0) # App Version - vLabel = Gtk.Label(label="v0.3.1") + vLabel = Gtk.Label(label="v0.1.0") vLabel.set_justify(Gtk.Justification.CENTER) self.box.pack_start(vLabel, True, True, 0) @@ -88,6 +97,8 @@ class MyWindow(Gtk.Window, threading.Thread): iLabel = Gtk.Label(label="PDF:", xalign=0) self.box.pack_start(iLabel, True, True, 0) self.iChooser = Gtk.FileChooserButton() + self.iChooser.set_filename(self.nomeFile) + self.iChooser.connect("file-set", self.on_filechooserbutton_changed) self.box.pack_start(self.iChooser, True, True, 0) # Separator @@ -95,10 +106,10 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(bar1, True, True, 0) # Specify Compression Type - tLabel = Gtk.Label(label="Type:", xalign=0) + tLabel = Gtk.Label(label=_("Type:"), xalign=0) self.box.pack_start(tLabel, True, True, 0) store = Gtk.ListStore(str) - for item in ["ebook", "screen", "printer", "prepress", "default"]: + for item in ["ebook", _("screen"), _("printer"), _("prepress"), _("default")]: store.append([item]) self.cType = Gtk.ComboBox() self.cType.set_model(store) @@ -119,10 +130,15 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(bar2, True, True, 0) # Specify Output File - oLabel = Gtk.Label(label="Output:", xalign=0) + oLabel = Gtk.Label(label=_("Output:"), xalign=0) self.box.pack_start(oLabel, True, True, 0) self.oFile = Gtk.Entry() - self.oFile.set_placeholder_text("compressed.pdf") + self.insert = _("_compressed.pdf") + if self.nomeFile != _("None"): + fileOut = self.nomeFile[:-4]+self.insert + else: + fileOut = self.insert + self.oFile.set_placeholder_text(fileOut) self.box.pack_start(self.oFile, True, True, 0) # Help Button - Output File @@ -134,13 +150,25 @@ class MyWindow(Gtk.Window, threading.Thread): bar3 = Gtk.HSeparator() self.box.pack_start(bar3, True, True, 0) + # Watermarker + wLabel = Gtk.Label(label=_("Watermark"), xalign=0) + self.box.pack_start(wLabel, True, True, 0) + + self.Wbutton = Gtk.ToggleButton(label="OFF") + self.Wbutton.connect("toggled", self.on_wbutton_toggled, "1") + self.box.pack_start(self.Wbutton, True, True, 0) + + self.wFile = Gtk.Entry() + self.wFile.set_text(_("Reserved")) + self.box.pack_start(self.wFile, True, True, 0) + # Progress Bar - pLabel = Gtk.Label(label="Status:", xalign=0) + pLabel = Gtk.Label(label=_("Status:"), xalign=0) self.box.pack_start(pLabel, True, True, 0) self.progressbar = Gtk.ProgressBar() self.box.pack_start(self.progressbar, True, True, 1) show_text = True - text = "Ready" + text = _("Ready") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.timeout_id = GLib.timeout_add(50, self.on_timeout, None) @@ -151,28 +179,49 @@ class MyWindow(Gtk.Window, threading.Thread): self.box.pack_start(bar4, True, True, 0) # Toggle Compress - self.button = Gtk.Button(label="Compress Now!") + self.button = Gtk.Button(label=_("Compress Now!")) self.button.set_sensitive(True) self.button.connect("clicked", self.on_button_clicked) self.box.pack_start(self.button, True, True, 0) + if (self.nomeFile != _("None")): + self.iChooser.set_filename(self.nomeFile) + self.on_filechooserbutton_changed(self.iChooser) # ComboBox Handler def on_combobox_changed(self, combobox): treeiter = combobox.get_active_iter() model = combobox.get_model() + def on_filechooserbutton_changed(self, widget): + iName = widget.get_filename() + self.nPathIn = os.path.dirname(iName) + nNameIn = os.path.basename(iName) + nFileIn = os.path.splitext(nNameIn)[0] + self.oFile.set_text(nFileIn+self.insert) + smesg = _("File chooosen: ") + print (smesg, nNameIn, " - ", self.nPathIn) + # Help Button Handler def on_help_clicked(self, widget): # Show Compression Type Descriptions Help Dialog - verbiage = "\n\n\nscreen:\n\nselects low-resolution output similar to the Acrobat Distiller \"Screen Optimized\" setting.\n\n\nebook:\n\nselects medium-resolution output similar to the Acrobat Distiller \"eBook\" setting.\n\n\nprinter:\n\nselects output similar to the Acrobat Distiller \"Print Optimized\" setting.\n\n\nprepress:\n\nselects output similar to Acrobat Distiller \"Prepress Optimized\" setting.\n\n\ndefault:\n\nselects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file." - self.info("Types of Compression", verbiage) + verbiage = _("\n\n\nscreen:\n\nselects low-resolution output similar to the Acrobat Distiller \"Screen Optimized\" setting.\n\n\nebook:\n\nselects medium-resolution output similar to the Acrobat Distiller \"eBook\" setting.\n\n\nprinter:\n\nselects output similar to the Acrobat Distiller \"Print Optimized\" setting.\n\n\nprepress:\n\nselects output similar to Acrobat Distiller \"Prepress Optimized\" setting.\n\n\ndefault:\n\nselects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file.") + title = _("Types of Compression") + self.info(title, verbiage) # oHelp Button Handler def on_oHelp_clicked(self, widget): # Show Output File Help Dialog - verbiage = "The output filename must not be the same as the input file name. The compressed PDF file will be placed in the same folder as your input file folder." - self.info("Output File Name", verbiage) - + verbiage = _("The output filename must not be the same as the input file name. The compressed PDF file will be placed in the same folder as your input file folder.") + title = _("Output File Name") + self.info(title, verbiage) + + # verifica Watermark Button + def on_wbutton_toggled(self, button, name): + if self.Wbutton.get_active(): + self.Wbutton.set_label("ON") + else: + self.Wbutton.set_label("OFF") + # Compression Button Handler - Where all the magic happens def on_button_clicked(self, widget): # Disable Compress Button @@ -180,19 +229,21 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Completed" and Progress Bar to Pulse self.progress() - # Set Command Compression Type Variable - iFile = self.iChooser.get_filename() slash = "/" - oName = self.oFile.get_text() + iFile = self.iChooser.get_filename() +# oName = self.oFile.get_text() + oFile = self.nPathIn+slash+self.oFile.get_text() +# oFile = self.oFile.get_text() # If Output file name was not specified, use "compressed.pdf" - if oName == None or oName == "": - oName = "compressed.pdf" +# if oName == None or oName == "": +# oName = _("compressed.pdf") +# print (iFile, " -> ", oFile) # If Input file is not specified, show an error dialog box if iFile == None: # Show Error Dialog - verbiage = "The input file field is empty. Please specify an input file to compress..." + verbiage = _("The input file field is empty. Please specify an input file to compress...") self.warning("ERROR!", verbiage) # Set Progress Bar Text to "Ready" self.ready() @@ -204,8 +255,8 @@ class MyWindow(Gtk.Window, threading.Thread): # If Input file does not end with .pdf, show an error dialog box if not iFile.endswith(".pdf"): # Show Error Dialog - verbiage = "Only PDF files can be compressed with this application. Please specify a pdf file" - self.warning("ERROR!", verbiage) + verbiage = _("Only PDF files can be compressed with this application. Please specify a pdf file") + self.warning(_("ERROR!"), verbiage) # Set Progress Bar Text to "Ready" self.ready() # Enable Compress Button @@ -214,14 +265,15 @@ class MyWindow(Gtk.Window, threading.Thread): return 1 # Prep Type of Compression - Must happen before comparing iFile and oFile - if iFile != None: - iPath = str(self.iChooser.get_current_folder()) - oFile = iPath + slash + oName +# if iFile != None: +# iPath = str(self.iChooser.get_current_folder()) +# oFile = oName +# print ("In = ",iFile,"\nOut = ",oFile) # If the Input File and Output File are the same, show an error dialog box if iFile == oFile: # Show Error Dialog - verbiage = "The output file name cannot be the same as the input file name." + verbiage = _("The output file name cannot be the same as the input file name.") self.warning("ERROR!", verbiage) # Set Progress Bar Text to "Ready" self.ready() @@ -232,8 +284,8 @@ class MyWindow(Gtk.Window, threading.Thread): # If Output File does not end with .pdf, verify with user that's really what they want if not oFile.endswith(".pdf"): - verbiage = "The output file name you specified does not end with \".pdf\". Are you sure that's what you want?" - response = self.verify("Output file name does not end with \".pdf\"!", verbiage) + verbiage = _("The output file name you specified does not end with \".pdf\". Are you sure that's what you want?") + response = self.verify(_("Output file name does not end with \".pdf\"!"), verbiage) # If OK, then continue to overwrite existing file. If cancel, then stop and go back to main window if response == Gtk.ResponseType.CANCEL: @@ -249,17 +301,18 @@ class MyWindow(Gtk.Window, threading.Thread): # If Specified Input File Name Contains Unsupported Characters, Show Dialog Error Dialog Box and Return to Main Window # Security Procaution if re.search('[\\\\\|:;\`]', iName): - verbiage = "The input file name contains unsupported characters. Please ensure your input file name does not contain special characters / \\ : ; \`" - self.warning("Unsupported File Name Convention!", verbiage) + verbiage = _("The input file name contains unsupported characters. Please ensure your input file name does not contain special characters / \\ : ; \`") + self.warning(_("Unsupported File Name Convention!"), verbiage) self.button.set_sensitive(True) return 1 # If Specified Output File Name Contains Unsupported Characters, Show Dialog Error Dialog Box and Return to Main Window # Security Procaution - if re.search('[\\\\\|:;\`]', oName): - verbiage = "The output file name contains unsupported characters. Please ensure your output file name does not contain special characters / \\ : ; \`" - self.warning("Unsupported File Name Convention!", verbiage) +# if re.search('[\\\\\|:;\`]',oName): + if re.search('[\\\\\|:;\`]',oFile): + verbiage = _("The output file name contains unsupported characters. Please ensure your output file name does not contain special characters / \\ : ; \`") + self.warning(_("Unsupported File Name Convention!"), verbiage) self.button.set_sensitive(True) return 1 @@ -267,8 +320,8 @@ class MyWindow(Gtk.Window, threading.Thread): # If Specified Output File Name Matches a File in the Output Directory if os.path.isfile(oFile): # Show Error Dialog - verbiage = "There's a file with the same name, \"" + oFile + "\" already in the directory. Are you sure you want to overwrite?" - response = self.verify("WARNING!", verbiage) + verbiage = _("There's a file with the same name, \"") + oFile + _("\" already in the directory. Are you sure you want to overwrite?") + response = self.verify(_("WARNING!"), verbiage) # If OK, then continue to overwrite existing file. If cancel, then stop and go back to main window if response == Gtk.ResponseType.CANCEL: @@ -283,9 +336,17 @@ class MyWindow(Gtk.Window, threading.Thread): cTypeModel = self.cType.get_model() cType = cTypeModel[cTypeIter][0] - # Build gs Command - self.cmmd = 'gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 -dPDFSETTINGS=/' + cType + ' -dNOPAUSE -dQUIET -dBATCH -sOutputFile=' + "\"" + oFile + "\"" + ' ' + "\"" +iFile + "\"" + # Copy watermark label + filigrana = self.wFile.get_text() + bashCommand = "sed 's/Reserved/"+filigrana+"/'"+" watermark.ps > ~/twatermark.ps" + os.system(bashCommand) + # Build gs Command + if self.Wbutton.get_active(): + self.cmmd = 'gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 -dPDFSETTINGS=/' + cType + ' -dNOPAUSE -dQUIET -dBATCH -sOutputFile=' + "\"" + oFile + "\"" + " -dALLOWPSTRANSPARENCY ~/twatermark.ps" + " \"" + iFile + "\"" + else: + self.cmmd = 'gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 -dPDFSETTINGS=/' + cType + ' -dNOPAUSE -dQUIET -dBATCH -sOutputFile=' + "\"" + oFile + "\"" + ' ' + "\"" +iFile + "\"" + # Start Compressing q = queue.Queue() cnow = threading.Thread(target=self.compress, args=[q]) @@ -299,10 +360,14 @@ class MyWindow(Gtk.Window, threading.Thread): # Setup Queue to get try catch results success = q.get() + # Delete tmp file (twatwermark.ps) + bashCommand = "rm ~/twatermark.ps" + os.system(bashCommand) + # If try succeeds, tell user it succeeded, else, show an error dialog if success == True: # Notify User - subprocess.run(["notify-send", "PDF Compressed!"]) + subprocess.run(["notify-send", _("PDF Compressed!")]) # Get File Size iFileSizeRaw = os.path.getsize(iFile) @@ -327,15 +392,15 @@ class MyWindow(Gtk.Window, threading.Thread): self.completed() # Show Completion Dialog - Try Completed - verbiage = "Your PDF File has been successfully compressed from " + str(iFileSize) + iUnit + " to " + str(oFileSize) + oUnit + "! Enjoy!" - self.info("PDF Compressed!", verbiage) + verbiage = _("Your PDF File has been successfully compressed from (") + str(iFileSize) + iUnit + _(") to (") + str(oFileSize) + oUnit + _(")! Enjoy!") + self.info(_("PDF Compressed!"), verbiage) else: # Notify User - subprocess.run(["notify-send", "ERROR!"]) + subprocess.run(["notify-send", _("ERROR!")]) # Show Error Dialog - Exception - verbiage = "Something went wrong! Maybe your PDF file is corrupted?" - self.info("ERROR!", verbiage) + verbiage = _("Something went wrong! Maybe your PDF file is corrupted?") + self.info(_("ERROR!"), verbiage) # Set Progress Bar to Ready and Stop Pulsing self.ready() @@ -381,16 +446,16 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Compressing..." and Progress Bar to Pulse def progress(self): show_text = True - text = "Compressing..." + text = _("Compressing...") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = True self.progressbar.pulse() # Set Progress Bar Text to "Ready" and Progress Bar to Stop - def ready(self): + def ready(self, *_): show_text = True - text = "Ready" + text = _("Ready") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = False @@ -401,7 +466,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Puased" and Progress Bar to Stop def pause(self): show_text = True - text = "Paused" + text = _("Paused") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = False @@ -410,7 +475,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Compressing..." and Progress Bar to Resume def resume(self): show_text = True - text = "Compressing..." + text = _("Compressing...") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = True @@ -419,7 +484,7 @@ class MyWindow(Gtk.Window, threading.Thread): # Set Progress Bar Text to "Completed" and Progress Bar to Stop def completed(self): show_text = True - text = "Completed" + text = _("Completed") self.progressbar.set_text(text) self.progressbar.set_show_text(show_text) self.activity_mode = False @@ -435,7 +500,7 @@ class MyWindow(Gtk.Window, threading.Thread): out_queue.put(True) except: if err == None: - print("There's an error with no trace data...") + print(_("There's an error with no trace data...")) else: print(err) out_queue.put(False) @@ -459,7 +524,16 @@ class MyWindow(Gtk.Window, threading.Thread): return True # Initiate Window -win = MyWindow() +if len(sys.argv) > 1: + nomeFile = os.path.basename(sys.argv[1]) + cartella = os.path.dirname(sys.argv[1]) + if (len(cartella) == 0): + cartella = "." + print("Cartella = ", cartella) + os.chdir(cartella) +else: + nomeFile = _("None") +win = MyWindow(nomeFile) win.start() win.set_icon_from_file(str(pathlib.Path(__file__).parent.absolute()) + "/icon.png") # Set App Icon win.connect("destroy", Gtk.main_quit) diff --git a/squeezer.desktop b/squeezer.desktop new file mode 100644 index 0000000..b20138d --- /dev/null +++ b/squeezer.desktop @@ -0,0 +1,14 @@ +[Desktop Entry] +Version=0.1.0 +Name=Squeezer +Comment=PDF Compressor +GenericName=Squeezer +Exec=/opt/Squeezer/squeezer +Path=/opt/Squeezer/ +Terminal=false +Type=Application +Icon=/opt/Squeezer/desktop-icon.png +StartupNotify=true +Categories=Utility;Application; +Name[it]=schiacciatore +Name[en]=squeezer diff --git a/squeezer.mo b/squeezer.mo new file mode 100644 index 0000000..b00eb6e Binary files /dev/null and b/squeezer.mo differ diff --git a/squeezer.po b/squeezer.po new file mode 100644 index 0000000..d5e7aeb --- /dev/null +++ b/squeezer.po @@ -0,0 +1,250 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-03 15:57+0200\n" +"PO-Revision-Date: 2023-05-03 18:00+0200\n" +"Last-Translator: Mariano Marini \n" +"Language-Team: LANGUAGE \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: squeezer:67 +msgid "Squeezer - PDF Compression" +msgstr "Squeezer - Compressione PDF" + +#: squeezer:81 +msgid "A Personal Open Source Initiative by Mariano Marini" +msgstr "Una iniziativa Open Source di Mariano Marini" + +#: squeezer:107 +msgid "Type:" +msgstr "Tipo" + +#: squeezer:110 +msgid "screen" +msgstr "schermo" + +#: squeezer:110 +msgid "printer" +msgstr "stampa" + +#: squeezer:110 +msgid "prepress" +msgstr "prestampa" + +#: squeezer:110 +msgid "default" +msgstr "Preimpostato" + +#: squeezer:131 +msgid "Output:" +msgstr "Destinazione" + +#: squeezer:134 +msgid "_compressed.pdf" +msgstr "_compresso.pdf" + +#: squeezer:148 +msgid "Status:" +msgstr "Stato" + +#: squeezer:153 squeezer:417 +msgid "Ready" +msgstr "Pronto" + +#: squeezer:164 +msgid "Compress Now!" +msgstr "Adesso comprimi!" + +#: squeezer:180 +msgid "File chooosen: " +msgstr "" + +#: squeezer:186 +msgid "" +"\n" +"\n" +"\n" +"screen:\n" +"\n" +"selects low-resolution output similar to the Acrobat Distiller \"Screen " +"Optimized\" setting.\n" +"\n" +"\n" +"ebook:\n" +"\n" +"selects medium-resolution output similar to the Acrobat Distiller \"eBook\" " +"setting.\n" +"\n" +"\n" +"printer:\n" +"\n" +"selects output similar to the Acrobat Distiller \"Print Optimized\" " +"setting.\n" +"\n" +"\n" +"prepress:\n" +"\n" +"selects output similar to Acrobat Distiller \"Prepress Optimized\" setting.\n" +"\n" +"\n" +"default:\n" +"\n" +"selects output intended to be useful across a wide variety of uses, possibly " +"at the expense of a larger output file." +msgstr "" +"\n" +"\n" +"\n" +"schermo:\n" +"\n" +"seleziona una bassa risoluzione simile ad Acrobat Distiller \"Screen Optimized\" setting.\n" +"\n" +"\n" +"ebook:\n" +"\n" +"seleziona una risoluzione media simile ad the Acrobat Distiller \"eBook\" setting.\n" +"\n" +"\n" +"stampante:\n" +"\n" +"seleziona una risoluzione ottimizzata simile ad Acrobat Distiller \"Print Optimized\" setting.\n" +"\n" +"\n" +"prestampa:\n" +"\n" +"seleziona una isoluzione ottimizzata simile ad Acrobat Distiller \"Prepress Optimized\" setting.\n" +"\n" +"\n" +"dpredefinita:\n" +"\n" +"seleziona la risoluzikone ritenuta utile tra quelle in uso, a scapito di un eventuale file di destinazione più grande.." + +#: squeezer:187 +msgid "Types of Compression" +msgstr "Tipo di compressione" + +#: squeezer:193 +msgid "" +"The output filename must not be the same as the input file name. The " +"compressed PDF file will be placed in the same folder as your input file " +"folder." +msgstr "" +"Il nome del file di destinazione non può essere uguale a quello di origine." +" Il file PDF compresso sarà salvato nella stessa cartella del file di " +"origine" + +#: squeezer:194 +msgid "Output File Name" +msgstr "compresso.pdf" + +#: squeezer:217 +msgid "" +"The input file field is empty. Please specify an input file to compress..." +msgstr "" +"Il campo file origine è vuoto. Specifica un file origine da comprimere per favore..." + +#: squeezer:229 +msgid "" +"Only PDF files can be compressed with this application. Please specify a pdf " +"file" +msgstr "" +"Con questo programma si possono comprimere solo file PDF. Scegli un file pdf per " +"favore." + +#: squeezer:230 squeezer:359 squeezer:362 +msgid "ERROR!" +msgstr "ERRORE!" + +#: squeezer:247 +msgid "The output file name cannot be the same as the input file name." +msgstr "Il nome del file di destinazione non può essere lo stesso di quello di origine." + +#: squeezer:258 +msgid "" +"The output file name you specified does not end with \".pdf\". Are you sure " +"that's what you want?" +msgstr "" +"Il nome del file di destinazine scelto non termina con \".pdf\". Sei sicuro " +"di volerlo?" + +#: squeezer:259 +msgid "Output file name does not end with \".pdf\"!" +msgstr "Il nome del file non termina con \".pdf\"!" + +#: squeezer:275 +msgid "" +"The input file name contains unsupported characters. Please ensure your " +"input file name does not contain special characters / \\ : ; \\`" +msgstr "" +"Il nome del file di origine contiene dei caratteri non accettati. Per favore " +"assicurati che non contenga / \\ : ; \\'" + +#: squeezer:276 squeezer:286 +msgid "Unsupported File Name Convention!" +msgstr "Convenzione del Nome del File non supportata!" + +#: squeezer:285 +msgid "" +"The output file name contains unsupported characters. Please ensure your " +"output file name does not contain special characters / \\ : ; \\`" +msgstr "" +"Il nome del file di destinazione contiene dei caratteri non accettati. Per favore assicurati " +"che non contenga caratteri speciali/ \\ : ; \\'" + +#: squeezer:294 +msgid "There's a file with the same name, \"" +msgstr "C'è un file con lo stesso nome, \"" + +#: squeezer:294 +msgid "\" already in the directory. Are you sure you want to overwrite?" +msgstr "\"nella cartella. Sei sicuro di volerlo sovrascrivere?" + +#: squeezer:295 +msgid "WARNING!" +msgstr "ATTENZIONE!" + +#: squeezer:329 squeezer:355 +msgid "PDF Compressed!" +msgstr "PDF Compresso!" + +#: squeezer:354 +msgid "Your PDF File has been successfully compressed from (" +msgstr "Il tuo file è stato compresso con successo da (" + +#: squeezer:354 +msgid ") to (" +msgstr ") a (" + +#: squeezer:354 +msgid ")! Enjoy!" +msgstr ")! Esulta!" + +#: squeezer:361 +msgid "Something went wrong! Maybe your PDF file is corrupted?" +msgstr "Qualcosa è andato storto! Forse il tuo file PDF è rovinato?" + +#: squeezer:408 squeezer:437 +msgid "Compressing..." +msgstr "Comprimendo..." + +#: squeezer:428 +msgid "Paused" +msgstr "In pausa" + +#: squeezer:446 +msgid "Completed" +msgstr "Completato" + +#: squeezer:462 +msgid "There's an error with no trace data..." +msgstr "C'è un errore non tracciabile..." diff --git a/watermark.ps b/watermark.ps new file mode 100644 index 0000000..712a215 Binary files /dev/null and b/watermark.ps differ