KennedyOliveira Posted April 26, 2015 Share Posted April 26, 2015 (edited) Hello everyone! I just made a exchange rate workflow, check out on github and in packal! Github -> https://github.com/kennedyoliveira/alfred-rates Packal -> http://www.packal.org/workflow/rates Its simple, but very useful. I hope it can helps someone as help me. Any feedback is appreciated! Convert between many currencies using the YQL (Yahoo! Query Language) to get the exchange rates in realtime for free. Screenshots Convert from USD to EUR Convert from default configured currency (BRL in my case) to USD Autocomplete example Usage: rate <VAL> <CUR SRC> <CUR DST> -> Convert the value from the currency to the currency . Example: rate 100 BRL USD rate <VAL> <CUR DST> -> Convert the value to the default currency setted with ratesetcurrency comand. rate <CUR SRC> <VAL> -> Convert the value from the currency to the default currency setted with ratesetcurrency command. rate <CUR DST> -> Convert the default currency to the <CUR DST>, just to show the rates. ratesetcurrency <CUR DST> -> Set the default currency, for use with the comands rate <VAL> <CUR DST> and rate <CUR SRC> <VAL> rateclear -> Clears all the cached data, used when there is a new version for removing olds caches. New Version 2.4.0! Added support for multiple queries with one command. Added support for checking a conversion for many currencies, see below: Now the currencies list and info is online, so when there are new currencies update there's no need to update the workflow to get just the currency list, it'll be downloaded. New Update : Added support for basic mathDivision Multiplication Sum Substraction Support for 4 digits after the decimal Configurable division digit "," or "." Edited July 25, 2015 by KennedyOliveira raguay.customct 1 Link to comment
KennedyOliveira Posted June 14, 2015 Author Share Posted June 14, 2015 New Update: Added support for basic mathDivision Multiplication Sum Substraction Support for 4 digits after the decimal Configurable division digit "," or "." Checkout the new version! Link to comment
artform Posted June 29, 2015 Share Posted June 29, 2015 I'm unsure how to actually install this workflow. Could you post details here or on Github? Standard workflows come with a .workflow file, which is not contained in your workflow. Thanks! Link to comment
KennedyOliveira Posted June 29, 2015 Author Share Posted June 29, 2015 Hello artform! There is a .workflow file! Check the release page on github. Here is the link -> https://github.com/kennedyoliveira/alfred-rates/releases Link to comment
KennedyOliveira Posted July 25, 2015 Author Share Posted July 25, 2015 New version 2.4! Checkout the new changes in the main topic! Link to comment
OnR Posted September 23, 2015 Share Posted September 23, 2015 Hi, Workflow seems to not accept turkish lira (TRY or tl) even though yahoo accepts it without any problem. Could you update that please? Great work btw! Thanks a lot! Link to comment
KennedyOliveira Posted September 23, 2015 Author Share Posted September 23, 2015 Hi OnR! Thanks for your feedback! Could you please describe more you problem? Because i tryed here and it works just fine on my machine. Link to comment
OnR Posted September 27, 2015 Share Posted September 27, 2015 When I enter rate 1 try (or tl) it just says no currency found. Link to comment
KennedyOliveira Posted September 28, 2015 Author Share Posted September 28, 2015 OnR, try to run rateclear and after run rate 1 try again, because here it works fine. Link to comment
juniormcc Posted September 1, 2016 Share Posted September 1, 2016 Can you add KZT (Kazakhstan tenge)? You have some other lesser known currencies ... Thanks Michael Link to comment
deanishe Posted September 1, 2016 Share Posted September 1, 2016 (edited) Handy workflow. Just a couple of questions/observations about your use of Alfred-Workflow. Is it necessary to include requests? workflow.web should cover the needs of the workflow, and it's specifically written to be a standalone module that will work outside the context of an Alfred workflow (unlike the rest of the library, which is liable to explode without an info.plist), or is there some bug/lacking feature that requires requests? There's no need to pass the Workflow object wf around between your functions (e.g. handle_check_update(), handle_get_default_divisor() etc.). Because it's created in the if __name__ == '__main__' block, it's global to the script.You're not using Workflow.run() correctly. Workflow.run() doesn't care about the return value of the function you pass it (main()); it only responds to exceptions. So the line retorno = wf.run(main) will never receive the return value of main() and retorno will always be 0 unless an exception was raised by main(), in which case it will be 1. If an exception does occur, Alfred-Workflow will call send_feedback() itself with an error message for the user. Your subsequent call to wf.send_feedback() (line 658 of rates.py) will either break the XML/JSON (meaning the user will only see Alfred's fallback searches) or be ignored by Alfred. Instead of collecting return values in returns, you should do something like this in main(): err_count = 0 for query in queries: ... ... # no need to pass `wf`! err_msg = process_conversion(queries, query, currency_src, currency_dst, val, currencies) if err_msg: log.error(err_msg) err_count += 1 ... ... # Raise an exception if something went wrong if err_count: # wf.run() will catch this exception, show the message in Alfred, then return 1 # The logged error messages are also visible in Alfred's debugger, but it has to be # open during the workflow run. raise Exception('{} errors. Enter "rate workflow:openlog" for details.'.format(err_count)) # Won't be called if there was an error, so the XML/JSON output won't be broken wf.send_feedback() And then use sys.exit(wf.run(main)) in the if __name__ == '__main__' clause. Edited September 1, 2016 by deanishe Fix code example Link to comment
KennedyOliveira Posted September 2, 2016 Author Share Posted September 2, 2016 Can you add KZT (Kazakhstan tenge)? You have some other lesser known currencies ... Thanks Michael Yeah sure, i added, run rateclear command and check again, that should be there! Link to comment
KennedyOliveira Posted September 2, 2016 Author Share Posted September 2, 2016 Handy workflow. Just a couple of questions/observations about your use of Alfred-Workflow. Is it necessary to include requests? workflow.web should cover the needs of the workflow, and it's specifically written to be a standalone module that will work outside the context of an Alfred workflow (unlike the rest of the library, which is liable to explode without an info.plist), or is there some bug/lacking feature that requires requests? There's no need to pass the Workflow object wf around between your functions (e.g. handle_check_update(), handle_get_default_divisor() etc.). Because it's created in the if __name__ == '__main__' block, it's global to the script. You're not using Workflow.run() correctly. Workflow.run() doesn't care about the return value of the function you pass it (main()); it only responds to exceptions. So the line retorno = wf.run(main) will never receive the return value of main() and retorno will always be 0 unless an exception was raised by main(), in which case it will be 1. If an exception does occur, Alfred-Workflow will call send_feedback() itself with an error message for the user. Your subsequent call to wf.send_feedback() (line 658 of rates.py) will either break the XML/JSON (meaning the user will only see Alfred's fallback searches) or be ignored by Alfred. Instead of collecting return values in returns, you should do something like this in main(): err_count = 0 for query in queries: ... ... # no need to pass `wf`! err_msg = process_conversion(queries, query, currency_src, currency_dst, val, currencies) if err_msg: log.error(err_msg) err_count += 1 ... ... # Raise an exception if something went wrong if err_count: # wf.run() will catch this exception, show the message in Alfred, then return 1 # The logged error messages are also visible in Alfred's debugger, but it has to be # open during the workflow run. raise Exception('{} errors. Enter "rate workflow:openlog" for details.'.format(err_count)) # Won't be called if there was an error, so the XML/JSON output won't be broken wf.send_feedback() And then use sys.exit(wf.run(main)) in the if __name__ == '__main__' clause. Hello @deanishe! Thank you for taking time to look at the code and give some advices, i wrote this workflow some time ago, i don't remember exactly why i choose somethings, but regarding your observations, i guess it doesn't need request, i probably forgot Alfred-Workflow had a web module, and implemented the feature with requests, i'll refactor and remove this in next version, if i find something missing which i doubt because is a simple GET for a file, but anyway, i 'll point to you. About passing the wf reference around, i didn't remember this behavior, i probably didn't read the documentation well enough (shame on me haha), or i just don't remember right now or why the hell i did that, anyway, i'll refactor the code and read the documentation again so i don't miss any point. Link to comment
deanishe Posted September 2, 2016 Share Posted September 2, 2016 (edited) About passing the wf reference around, i didn't remember this behavior, i probably didn't read the documentation well enough (shame on me haha), or i just don't remember right now or why the hell i did that, anyway, i'll refactor the code and read the documentation again so i don't miss any point. That's not documented, tbh. At most it's just implied by the code examples. Glad to hear it isn't a bug in workflow.web. The return code handling isn't documented either (I had to go look at the Workflow.run() code to check). It honestly never occurred me to consider the return values of the called functions. I suppose zero/non-zero is a kind of de-facto standard, but I only focussed on unhandled exceptions rather than explicit error conditions like yours. Edited September 5, 2016 by deanishe Link to comment
KennedyOliveira Posted September 12, 2016 Author Share Posted September 12, 2016 @deanishe, i started to refactor the code, but i remembered why i was passing the workflow around, due to unittesting the code, since the wf reference is created in __name__ == '__main__' block, and in the unittests i run the code directly, calling the main or the functions i'm testing, global workflow is not available, how you suggest testing this way? I'm not a expert in python as you can see, hope you can help me. Thank you! Link to comment
deanishe Posted September 12, 2016 Share Posted September 12, 2016 (edited) in the unittests i run the code directly, calling the main or the functions i'm testing, global workflow is not available, how you suggest testing this way? If I were writing unit tests for a workflow, I'd initially try to write as many functions as possible so that they don't need the Workflow object (hence why my examples use a global log object, not Workflow.logger directly: if that's all you're using, it's easy to replace with a mock object, such as a real Logger with a NullHandler). When you need a Workflow object, you could put wf = Workflow() at the top of each test function, so it'll be in scope when you call the functions you're testing. But if you really want a global, Python gives you a reasonable workaround with the globals() function, which returns a (mutable) dictionary of all global variables. As such, you could put globals()['wf'] = Workflow() in your setUp() and (optionally) del globals()['wf'] in your tearDown() (if you're using the standard unittest library). As long as there's an info.plist beside or above your code, you should be able to instantiate a Workflow object without errors. Does that help? Edited September 13, 2016 by deanishe Remove irrelevant waffle Link to comment
KennedyOliveira Posted November 1, 2016 Author Share Posted November 1, 2016 @deanishe Sorry for the long time to reply, i went to a surgery and i'm currently overwhelmed with lots of things to do, without time to my personal projects, but yes your comments helps a lot! I'll try to work on it this week and reformulate some things and will get back at you. Thank you! Link to comment
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