How do I export PSDs as PNGs with py-appscript? - photoshop

I wrote a script to export PSDs as PNGs with rb-appscript. That's fine and dandy, but I can't seem to pull it off in py-appscript.
Here's the ruby code:
#!/usr/bin/env ruby
require 'rubygems'
require 'optparse'
require 'appscript'
ps = Appscript.app('Adobe Photoshop CS5.app')
finder = Appscript.app("Finder.app")
path = "/Users/nbaker/Desktop/"
ps.activate
ps.open(MacTypes::Alias.path("#{path}guy.psd"))
layerSets = ps.current_document.layer_sets.get
# iterate through all layers and hide them
ps.current_document.layers.get.each do |layer|
layer.visible.set false
end
layerSets.each do |layerSet|
layerSet.visible.set false
end
# iterate through all layerSets, make them visible, and create a PNG for them
layerSets.each do |layerSet|
name = layerSet.name.get
layerSet.visible.set true
ps.current_document.get.export(:in => "#{path}#{name}.png", :as => :save_for_web,
:with_options => {:web_format => :PNG, :png_eight => false})
layerSet.visible.set false
end
And here's the apparently nonequivalent python code:
from appscript import *
from mactypes import *
# fire up photoshop
ps = app("Adobe Photoshop CS5.app")
ps.activate()
# open the file for editing
path = "/Users/nbaker/Desktop/"
f = Alias(path + "guy.psd")
ps.open(f)
layerSets = ps.current_document.layer_sets()
# iterate through all layers and hide them
for layer in ps.current_document.layers():
layer.visible.set(False)
#... and layerSets
for layerSet in layerSets:
layerSet.visible.set(False)
# iterate through all layerSets, make them visible, and create a PNG for them
for layerSet in layerSets:
name = layerSet.name()
layerSet.Visible = True
ps.current_document.get().export(in_=Alias(path + name + ".png"), as_=k.save_for_web,
with_options={"web_format":k.PNG, "png_eight":False})
The only part of the python script that doesn't work is the saving. I've gotten all sorts of errors trying different export options and stuff:
Connection is invalid... General Photoshop error occurred. This functionality may not be available in this version of Photoshop... Can't make some data into the expected type...
I can live with just the ruby script, but all of our other scripts are in python, so it would be nice to be able to pull this off in python. Thanks in advance internet.

Bert,
I think I have a solution for you – albeit several months later. Note that I'm a Python noob, so this is by no means elegant.
When I tried out your script, it kept crashing for me too. However by removing the "Alias" in the export call, it seems to be OK:
from appscript import *
from mactypes import *
# fire up photoshop
ps = app("Adobe Photoshop CS5.1.app")
ps.activate()
# open the file for editing
path = "/Users/ian/Desktop/"
f = Alias(path + "Screen Shot 2011-10-13 at 11.48.51 AM.psd")
ps.open(f)
layerSets = ps.current_document.layer_sets()
# no need to iterate
ps.current_document.layers.visible.set(False)
ps.current_document.layer_sets.visible.set(False)
# iterate through all layerSets, make them visible, and create a PNG for them
for l in layerSets:
name = l.name()
# print l.name()
l.visible.set(True)
# make its layers visible too
l.layers.visible.set(True)
# f = open(path + name + ".png", "w").close()
ps.current_document.get().export(in_=(path + name + ".png"), as_=k.save_for_web,
with_options={"web_format":k.PNG, "png_eight":False})
I noticed, too, that you iterate through all the layers to toggle their visibility. You can actually just issue them all a command at once – my understanding is that it's faster, since it doesn't have to keep issuing Apple Events.
The logic of my script isn't correct (with regards to turning layers on and off), but you get the idea.
Ian

Related

Spacevim: neosnippet <Plug> mappings dont work

Problem
I set up my spacevim with builtin autocompletion which provides neosnippet in-box, but when I use my Enter button to perform expansion of a snippet I get just raw output of <Plug>(neosnippet_expand). Also, I've tried to use deoppet snippets, but faced with the same problem. Besides, i tried to remap my how in this post How to autoexpand neosnippet with deoplete dropdown menu? but when I try to expand main I got main<Plug>(neosnippet_expand_or_jump) Here are my configs:
Init.toml:
[options]
# set spacevim theme. by default colorscheme layer is not loaded,
# if you want to use more colorscheme, please load the colorscheme
# layer
colorscheme = "nord"
colorscheme_bg = "dark"
default_indent = 4
expand_tab = false
# snippet_engine = "neosnippet"
# Disable guicolors in basic mode, many terminal do not support 24bit
# true colors
enable_guicolors = true
# Disable statusline separator, if you want to use other value, please
# install nerd fonts
statusline_separator = "arrow"
statusline_iseparator = "arrow"
buffer_index_type = 4
enable_tabline_filetype_icon = true
enable_statusline_mode = false
autocomplete_parens = false
automatic_update = true
# Enable autocomplete layer
[[layers]]
name = 'autocomplete'
# autocomplete_method = 'coc'
auto_completion_tab_key_behavior = "smart"
auto_completion_return_key_behavior = "smart"
Init.vim:
map <F5> :ImportName<CR>
execute 'source' fnamemodify(expand('<sfile>'), ':h').'/main.vim'
let g:deoplete#enable_at_startup = 1
call deoplete#custom#option("num_processes", 4)
let g:spacevim_enable_ycm = 1
let g:ansible_extra_keywords_highlight = 1
let g:coc_filetype_map = {
\ 'yaml.ansibe': 'ansible',
\ }
let g:jedi#completions_enabled = 0
au BufRead,BufNewFile */playbooks/*.yml set filetype=yaml.ansible
autocmd FileType yaml\|yaml.ansible setlocal ts=2 sts=2 sw=2 expandtab
inoremap <silent><expr><CR> pumvisible() ? deoplete#close_popup()."\<Plug>(neosnippet_expand_or_jump)" : "\<CR>"
Snippets dir list:
╰─$ ls ~/.SpaceVim.d/snippets/
actionscript.snip blade.snip d.snip go.snip liquid.snip objc.snip rust.snip systemverilog.snip vim.snip
ada.snip clojure.snip elixir.snip go.vim lua.snip ocaml.snip scala.snip tex.snip vimspec.snip
apache.snip cmake.snip elm.snip groovy.snip make.snip perl.snip scheme.snip toml.snip vimwiki.snip
applescript.snip coffee.snip erlang.snip haskell.snip markdown.snip php.snip scss.snip twig.snip vue.snip
asciidoc.snip cpp.snip eruby.snip html.snip mediawiki.snip prolog.snip sh.snip typescriptreact.snip xhtml.snip
asciidoctor.snip c.snip fortran.snip javascript.snip mkd.snip python.snip _.snip typescript.snip zsh.snip
asm.snip cs.snip fsharp.snip java.snip moon.snip rails.snip sql.snip verilog.snip
beancount.snip css.snip Gemfile.snip julia.snip neosnippet.snip rst.snip sshconfig.snip vim
bib.snip cuda.snip gnuplot.snip kp19pp.snip nim.snip ruby.snip swift.snip vimshell.snip
Completion sight (if needed):
I want to expand neosnippet snippets, but fail

Perl : Scrape website and how to download PDF files from the website using Perl Selenium:Chrome

So I'm studying Scraping website using Selenium:Chrome on Perl, I just wondering how can I download all pdf files from year 2017 to 2021 and store it into a folder from this website https://www.fda.gov/drugs/warning-letters-and-notice-violation-letters-pharmaceutical-companies/untitled-letters-2021 . So far this is what I've done
use strict;
use warnings;
use Time::Piece;
use POSIX qw(strftime);
use Selenium::Chrome;
use File::Slurp;
use File::Copy qw(copy);
use File::Path;
use File::Path qw(make_path remove_tree);
use LWP::Simple;
my $collection_name = "mre_zen_test3";
make_path("$collection_name");
#DECLARE SELENIUM DRIVER
my $driver = Selenium::Chrome->new;
#NAVIGATE TO SITE
print "trying to get toc_url\n";
$driver->navigate('https://www.fda.gov/drugs/warning-letters-and-notice-violation-letters-pharmaceutical-companies/untitled-letters-2021');
sleep(8);
#GET PAGE SOURCE
my $toc_content = $driver->get_page_source();
$toc_content =~ s/[^\x00-\x7f]//g;
write_file("toc.html", $toc_content);
print "writing toc.html\n";
sleep(5);
$toc_content = read_file("toc.html");
This script only download the entire content of the website. Hope someone here can help me and teach me. Thank you very much.
Here is some working code, to help you get going hopefully
use warnings;
use strict;
use feature 'say';
use Path::Tiny; # only convenience
use Selenium::Chrome;
my $base_url = q(https://www.fda.gov/drugs/)
. q(warning-letters-and-notice-violation-letters-pharmaceutical-companies/);
my $show = 1; # to see navigation. set to false for headless operation
# A little demo of how to set some browser options
my %chrome_capab = do {
my #cfg = ($show)
? ('window-position=960,10', 'window-size=950,1180')
: 'headless';
'extra_capabilities' => { 'goog:chromeOptions' => { args => [ #cfg ] } }
};
my $drv = Selenium::Chrome->new( %chrome_capab );
my #years = 2017..2021;
foreach my $year (#years) {
my $url = $base_url . "untitled-letters-$year";
$drv->get($url);
say "\nPage title: ", $drv->get_title;
sleep 1 if $show;
my $elem = $drv->find_element(
q{//li[contains(text(), 'PDF')]/a[contains(text(), 'Untitled Letter')]}
);
sleep 1 if $show;
# Downloading the file is surprisingly not simple with Selenium (see text)
# But as we found the link we can get its url and then use Selenium-provided
# user-agent (it's LWP::UserAgent)
my $href = $elem->get_attribute('href');
say "pdf's url: $href";
my $response = $drv->ua->get($href);
die $response->status_line if not $response->is_success;
say "Downloading 'Content-Type': ", $response->header('Content-Type');
my $filename = "download_$year.pdf";
say "Save as $filename";
path($filename)->spew( $response->decoded_content );
}
This takes shortcuts, switches approaches, and sidesteps some issues (which one need resolve for a fuller utility of this useful tool). It downloads one pdf from each page; to download all we need to change the XPath expression used to locate them
my #hrefs =
map { $_->get_attribute('href') }
$drv->find_elements(
# There's no ends-with(...) in XPath 1.0 (nor matches() with regex)
q{//li[contains(text(), '(PDF)')]}
. q{/a[starts-with(#href, '/media/') and contains(#href, '/download')]}
);
Now loop over the links, forming filenames more carefully, and download each like in the program above. I can fill the gaps further if there's need for that.
The code puts the pdf files on disk, in its working directory. Please review that before running this so to make sure that nothing gets overwritten!
See Selenium::Remove::Driver for starters.
Note: there is no need for Selenium for this particular task; it's all straight-up HTTP requests, no JavaScript. So LWP::UserAgent or Mojo would do it just fine. But I take it that you want to learn how to use Selenium, since it often is needed and is useful.

Julia using package located in .julia/dev

I am beginner to Julia though I have experience with Python and some other languages. I get that this is probably a very simple/beginner issue, but I fail to understand how it should work in Julia.
I want to create a Julia module. I saw recommendations to create it with PkgTemplates, so that is exactly what I have done. My directory structure is thus:
It is located at the default path proposed by PkgTemplates: /home/username/.julia/dev/Keras2Flux.
I want to develop it with Revise package due to the slow start-up time of the Julia REPL. However, I fail to import my module to the Julia REPL in the terminal.
So, I cd to the directory mentioned above, use julia command and try using Keras2Flux. I get the error:
ERROR: ArgumentError: Package Keras2Flux not found in current path:
I tried both using Keras2Flux and using Keras2Flux.jl, and I also tried to call it from one level above in my directory structure (i.e. /home/username/.julia/dev). All has the same problem.
What is wrong (more importantly, why?) and how to fix it?
Current contents of the module (not really relevant to the question but still):
module Keras2Flux
import JSON
using Flux
export convert
function create_dense(config)
in = config["input_dim"]
out = config["output_dim"]
dense = Dense(in, outо)
return dense
end
function create_dropout(config)
p = config["p"]
dropout = Dropout(p)
return dropout
end
function create_model(model_config)
layers = []
for layer_config in model_config
if layer_config["class_name"] == "Dense"
layer = create_dense(layer_config["config"])
elseif layer_config["class_name"] == "Dropout"
layer = create_dropout(layer_config["config"])
else
println(layer_config["class_name"])
throw("unimplemented")
end
push!(layers, layer)
end
model = Chain(layers)
end
function convert(filename)
jsontxt = ""
open(filename, "r") do f
jsontxt = read(f, String)
end
model_params = JSON.parse(jsontxt)
if model_params["keras_version"] == "1.1.0"
create_model(model_params["config"])
else
throw("unimplemented")
end
end
end
Here is a full recipe to get you going:
cd("/home/username/.julia/dev")
using Pkg
pkg"generate Keras2Flux"
cd("Keras2Flux")
pkg"activate ."
pkg"add JSON Flux"
# now copy-paste whatever you need to Keras2Flux\src\Keras2Flux.jl
using Revise
using Keras2Flux
# happy development!

How do I optionally set a platform/model attribute from my run script?

I'm using the VLAB MPC5xxx Toolbox.
I have a run script that is controlling my simulation, which loads the platform in the usual way, then runs it:
import vlab
import os
import sysc
image_path = os.path.join('o5e',
'firmware.open5xxxecu-e6009bbcfcd1',
'bin', 'o5e_dbg.elf')
vlab.load('mpc.mpc5674f.sim', args=['--testbench=o5e_testbench',
"--image=%s" % image_path,
"--debugger-config=GHS_MULTI",
"--trace=+src:sc_report",
])
vcd_sink = vlab.trace.sink.vcd("mpc.mpc5674f.sim.vcd")
vlab.add_trace("mpc5674f.PBRIDGE.EDMA_B", sink=vcd_sink)
for i in range(32):
vlab.add_trace("mpc5674f.PBRIDGE.ETPU.CH_OUT_A[%d]" % i, sink=vlab.trace.sink.console)
vlab.run(11, "ms", blocking=True)
vlab.exit()
I want to give this run script an argument to turn on tracing in the core, which I know you do by setting the tracing attribute on the core. And I know I can read the options of the script using python's optparse.
The problem I have is that you have to set the attribute before the end of elaboration, but the only place I can access the simulation before elaboration is in the testbench... but there seems to be no way to pass parameters (for example script arguments) to the testbench.
How should I pass the argument from my script into the testbench, so it conditionally turns on or not the core tracing?
So, I think the answer is:
1) Don't use try to use the testbench for things that aren't to do with ... a testbench
2) Use "phase breakpoints" to do things that need to happen at... specific phases in the simulation
eg:
from optparse import OptionParser
parser = OptionParser()
parser.add_option("--core-instrumentation", dest="core_instrumentation",
action = "store_true",
help="turn on core instrumentation")
(options, args) = parser.parse_args()
if options.core_instrumentation:
vlab.add_phase_breakpoint("before_end_of_elaboration",
action = lambda bp: vlab.write_attribute("mpc5467f.Core0.log_filter","+instr"))
image_path = os.path.join('o5e',
'firmware.open5xxxecu-e6009bbcfcd1',
'bin', 'o5e_dbg.elf')
vlab.load('mpc.mpc5674f.sim', args=['--testbench=o5e_testbench',
"--image=%s" % image_path,
"--debugger-config=GHS_MULTI",
])
vcd_sink = vlab.trace.sink.vcd("mpc.mpc5674f.sim.vcd")
vlab.add_trace("mpc5674f.PBRIDGE.EDMA_B", sink=vcd_sink)
for i in range(32):
vlab.add_trace("mpc5674f.PBRIDGE.ETPU.CH_OUT_A[%d]" % i, sink=vlab.trace.sink.console)
vlab.run(11, "ms", blocking=True)
vlab.exit()

Getting Origami-pdf to work with Amazon S3 files

I've implemented a local script to insert digital signatures into local pdf files recurring to Origami, but don't quite know what would be the best approach to do this within a rails server, and with amazon s3 stored files.
I am guessing i would need to download the file from s3 to my server (or capture it before uploading to amazon, which is what i am doing with paperclip) insert the signature, and sent it back to s3 again.
Here is the PDF.read method in pdf.rb file of origami solution:
class << self
#
# Reads and parses a PDF file from disk.
#
def read(filename, options = {})
filename = File.expand_path(filename) if filename.is_a?(::String)
PDF::LinearParser.new(options).parse(filename)
end
How could i adapt this so that i treat an in-memory binary file?
Do you have any suggestions?
You can find more about origami here
And my code below
require 'openssl'
begin
require 'origami'
rescue LoadError
ORIGAMIDIR = "C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib"
$: << ORIGAMIDIR
require 'origami'
end
include Origami
INPUTFILE = "Sample.pdf"
#inputfile = String.new(INPUTFILE)
OUTPUTFILE = #inputfile.insert(INPUTFILE.rindex("."),"_signed")
CERTFILE = "certificate.pem"
RSAKEYFILE = "private_key.pem"
passphrase = "your passphrase"
key4pem=File.read RSAKEYFILE
key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read CERTFILE)
pdf = PDF.read(INPUTFILE)
page = pdf.get_page(1)
# Add signature annotation (so it becomes visibles in pdf document)
sigannot = Annotation::Widget::Signature.new
sigannot.Rect = Rectangle[:llx => 89.0, :lly => 386.0, :urx => 190.0, :ury => 353.0]
page.add_annot(sigannot)
# Sign the PDF with the specified keys
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:annotation => sigannot,
:location => "Portugal",
:contact => "myemail#email.tt",
:reason => "Proof of Concept"
)
# Save the resulting file
pdf.save(OUTPUTFILE)
PDF.read and PDF.save methods both accept either a file path or a Ruby IO object.
One method to create a PDF instance from a string (which, I suppose, is what you mean when you say "in-memory") is to use a StringIO object.
For example, the following session in the Origami shell will create a PDF instance, save it to a StringIO object and reload it using its own output string.
>>> PDF.new.save(strio = StringIO.new)
...
>>> strio.string
"%PDF-1.0\r\n1 0 obj\r\n<<\r\n\t/Pages 2 0 R ..."
>>> strio.reopen(strio.string, 'r')
#<StringIO:0xffbea6cc>
>>> pdf = PDF.read(strio)
...
>>> pdf.class
Origami::PDF
After a deep further analysis into the origami code, i noticed that PDF.Read accepts a binary file, and so instead of sending the local file path, we can send the file instance as a whole.
As #MrWater wrote, Origami::PDF.read accepts a stream (more precisely, the Origami::PDF::LinearParser does, look at the source here).
Here's my simple solution:
require 'open-uri'
# pdf_url = 'http://someurl.com/somepdf.pdf'
pdf = Origami::PDF.read(URI.parse(pdf_url))
References
open-uri URI
Origami::PDF::LinearParser