Veritas3241 Posted February 3, 2014 Posted February 3, 2014 I'm building a workflow that will accept a string input and output the same string with some characters escaped using '\'. This is so the string can be accepted into a function which accepts regular expressions. I have a python script that does this perfectly and Alfred will do it perfectly as well up to about 60-70 characters. After that it just defaults to the "Search Google for {my string}". My question is a) is there a character limit on arguments passed into Alfred and is there a way to bypass it? Thank you!
Tyler Eich Posted February 3, 2014 Posted February 3, 2014 Have you tried running your Python script from the Terminal? Does it throw errors when you input this 60-70 character query? For what it's worth, I just ran a workflow with a 1003 character input. Clearly, Alfred isn't throttling the query's length
Veritas3241 Posted February 3, 2014 Author Posted February 3, 2014 It does work fine on the command line. I have to wrap my string in quotes to get it to work but the one I'm testing (and works on the command line) is 1192 characters. I wonder if it's an issue with encoding? I'm going from utf-8 to ascii within the script. Might it also be an issue with copying into the alfred argument field? The workflow right now is type 'reg', and copy my string in. I don't type it in.
Tyler Eich Posted February 3, 2014 Posted February 3, 2014 It may be easier to debug your code if you post the workflow. Could you do that?
Veritas3241 Posted February 3, 2014 Author Posted February 3, 2014 Now that I play with the code some more, it seems that certain characters are not liked by Alfred. My string has pipes |, apostrophes, and other fun characters in it. Is there a way to have alfred ignore those?
Tyler Eich Posted February 3, 2014 Posted February 3, 2014 If you look in Console.app, do you seen any errors from Alfred? For example, something about 'Invalid XML'? Without actually seeing and running your code on my machine, it's difficult to isolate your issue
Veritas3241 Posted February 3, 2014 Author Posted February 3, 2014 (edited) Sorry, I replied before I saw your reply. Here's the script I'm running. When I run a string like 'This-is a string with some stuff-in it' it correctly outputs: This\-is a string with some stuff\-in it. But if I run the string 'But now my string|has pipes and 'quotes' nothing happens. it does work on the command line and correctly outputs the xml <items><item arg="But not my string|has pipes and \'quotes" uid="regexified" valid="yes"><title>But now my string|has pipes and \'quotes</title><subtitle>Copy to Clipboard</subtitle><icon /></item></items> I want to keep pipes in there and un-escaped. And no, I don't see any errors on the console. # -*- coding: utf-8 -*- import sys from xml.etree.ElementTree import Element, SubElement, Comment, tostring args = sys.argv string_to_regex = str(args[1]).decode('utf-8') regexified = [] # Builds each part of the XML tree def build_xmltree(items): item = SubElement(items, 'item') title = SubElement(item, 'title') subtitle = SubElement(item, 'subtitle') icon = SubElement(item, 'icon') return (item, title, subtitle, icon) for i in string_to_regex: if i in ["-","\\","(",")",",","'",">","<"]: regexified.append("\\"+ i) else: regexified.append(i) alfred = ''.join(regexified) alfred_two = alfred.encode('ascii', 'ignore') items = Element('items') item, title, subtitle, icon = build_xmltree(items) item.set('uid', 'regexified') item.set('arg', alfred_two) item.set('valid', 'yes') title.text = alfred subtitle.text = 'Copy to Clipboard' print tostring(items) Edited February 3, 2014 by Veritas3241
rice.shawn Posted February 4, 2014 Posted February 4, 2014 Did you uncheck the correct 'escape' characters in the 'run script' action? Veritas3241 1
Tyler Eich Posted February 4, 2014 Posted February 4, 2014 Sorry, I replied before I saw your reply. Here's the script I'm running. When I run a string like 'This-is a string with some stuff-in it' it correctly outputs: This\-is a string with some stuff\-in it. But if I run the string 'But now my string|has pipes and 'quotes' nothing happens. it does work on the command line and correctly outputs the xml <items><item arg="But not my string|has pipes and \'quotes" uid="regexified" valid="yes"><title>But now my string|has pipes and \'quotes</title><subtitle>Copy to Clipboard</subtitle><icon /></item></items> I want to keep pipes in there and un-escaped. And no, I don't see any errors on the console. # -*- coding: utf-8 -*- import sys from xml.etree.ElementTree import Element, SubElement, Comment, tostring args = sys.argv string_to_regex = str(args[1]).decode('utf-8') regexified = [] # Builds each part of the XML tree def build_xmltree(items): item = SubElement(items, 'item') title = SubElement(item, 'title') subtitle = SubElement(item, 'subtitle') icon = SubElement(item, 'icon') return (item, title, subtitle, icon) for i in string_to_regex: if i in ["-","\\","(",")",",","'",">","<"]: regexified.append("\\"+ i) else: regexified.append(i) alfred = ''.join(regexified) alfred_two = alfred.encode('ascii', 'ignore') items = Element('items') item, title, subtitle, icon = build_xmltree(items) item.set('uid', 'regexified') item.set('arg', alfred_two) item.set('valid', 'yes') title.text = alfred subtitle.text = 'Copy to Clipboard' print tostring(items) I replaced your \' with ' and everything works. Your XML was invalid because of the improperly escaped apostrophes. I recommend using a workflow library in your code. It will abstract all this escaping business and make it easier to interact with Alfred
Veritas3241 Posted February 4, 2014 Author Posted February 4, 2014 Shawn, good call. That was part of the problem. Tyler, thanks for pointing that out. I think I'll work on this and incorporate the alp library. I hadn't seen that before and it might solve some of my other problems. Thank you both very much! You've been very helpful!
deanishe Posted February 4, 2014 Posted February 4, 2014 (edited) The output escaping isn't the problem—he's letting the XML library do that, as would any Alfred library. The big problem is the text encoding is all over the place. Veritas, you're mixing unicode strings (string_to_regex) and UTF-8-encoded strings (everything else). You must encode the output to UTF-8 before printing it to Alfred. Try this instead: # -*- coding: utf-8 -*- import sys from xml.etree.ElementTree import Element, SubElement, Comment, tostring string_to_regex = sys.argv[1].decode(u'utf-8') regexified = [] # Builds each part of the XML tree def build_xmltree(items): item = SubElement(items, u'item') title = SubElement(item, u'title') subtitle = SubElement(item, u'subtitle') icon = SubElement(item, u'icon') return (item, title, subtitle, icon) for i in string_to_regex: if i in u"\\[]().*+-^$|": regexified.append(u"\\" + i) else: regexified.append(i) alfred = u''.join(regexified) items = Element(u'items') item, title, subtitle, icon = build_xmltree(items) item.set(u'uid', u'regexified') item.set(u'arg', alfred) item.set(u'valid', u'yes') title.text = alfred subtitle.text = u'Copy to Clipboard' print tostring(items, encoding=u'utf-8') And set up the script escaping so: It should do what you want (if I've understood it correctly). A lot of the strings I've changed to unicode literals are unnecessary (tag names, 'utf-8' etc.), but it's a good habit to get into with Python 2, otherwise at some point you'll combine unicode and non-unicode and bad things will happen. Be sure to decode all external input (sys.argv, os.environ, sys.stdin etc.) to unicode immediately, and encode all output (usually to UTF-8) before you print/write it. If you don't do that, any non-ASCII character will likely break your script. If you're working with filepaths, you also have to call unicodedata.normalize(u'NFD', u'your unicode path here') or weird things will happen (on OS X). Edited February 4, 2014 by deanishe Veritas3241 1
Veritas3241 Posted February 4, 2014 Author Posted February 4, 2014 This script worked exactly like I need it to. I'm a complete noob at dealing with all of the encoding issues. I'm still trying to wrap my head around it all. For now, I'm going to use the script like you wrote it, but I still might try my hand incorporating one of the libraries. Thank you very much for your help!
deanishe Posted February 4, 2014 Posted February 4, 2014 You're welcome. Here's the Python Unicode tutorial, but the golden rule is decode on input, encode on output. You should always test your scripts with non-ASCII input to flush out any errors. Most of the Alfred libraries are overkill for a simple script like this one, but you might give nikipore's one a try. It's nice and lightweight (just one file), and does a good job with encoding. Alp, by contrast, is very bloated (and therefore slow) and does not do encoding correctly (wrong normalisation for OS X).
rice.shawn Posted February 5, 2014 Posted February 5, 2014 In Alp's defense, if I remember correctly, you can just include whatever you need to include and delete the rest. Tyler Eich 1
Tyler Eich Posted February 5, 2014 Posted February 5, 2014 In Alp's defense, if I remember correctly, you can just include whatever you need to include and delete the rest. Yes, I can confirm this. I remove unnecessary modules for nearly every Python workflow I write. Each time, a different set is removed according to the workflow's needs.
deanishe Posted February 5, 2014 Posted February 5, 2014 Yes, that's the way Alp's set up, but that's not immediately obvious and I'd argue Your First Alfred Library should probably be something simpler unless you need some of Alp's (very cool) features.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now