├── LICENSE
├── README.md
├── elements
├── AddressInput.py
├── AdjustDate.py
├── AppendtoVariable.py
├── Changetimezone.py
├── ConverttoNumber.py
├── ConverttoText.py
├── Count.py
├── Date.py
├── DateInput.py
├── ElementBase.py
├── ElementParameter.py
├── ElementValue.py
├── Else.py
├── EndFor.py
├── EndForEach.py
├── EndIf.py
├── For.py
├── ForEach.py
├── GenerateHashOfString.py
├── GetAddressfromLocation.py
├── GetBatteryDetails.py
├── GetClipboardImage.py
├── GetClipboardText.py
├── GetCurrentLocation.py
├── GetImagesfromAppextension.py
├── GetLocationfromAddress.py
├── GetName.py
├── GetScreenBrightness.py
├── GetURLContents.py
├── GetVariable.py
├── If.py
├── ListTest.py
├── Nothing.py
├── NumberInput.py
├── OpenLocationinAppleMaps.py
├── OpenLocationinGoogleMaps.py
├── OpenURLin.py
├── PickImagefromPhotos.py
├── PlayAudio.py
├── Print.py
├── RecordAudio.py
├── SaveImagetoCameraRoll.py
├── SetClipboardImage.py
├── SetClipboardText.py
├── SetName.py
├── SetScreenBrightness.py
├── SetVariable.py
├── SetVolume.py
├── ShowAlert.py
├── ShowlocationonMap.py
├── Sleep.py
├── SpeakText.py
├── TakePhoto.py
├── Template.py
├── TextInput.py
├── TexttoURL.py
├── VibrateDevice.py
└── __init__.py
├── istaflow.py
├── managers
├── ElementManager.py
├── FlowManager.py
├── HomeScreenManager.py
├── SettingsManager.py
├── ThemeManager.py
├── WebClipper.py
└── __init__.py
└── views
├── AssetPickerView.py
├── ElementCreationView.py
├── ElementListView.py
├── ElementManagementView.py
├── ElementParameterDictionaryInputView.py
├── ElementRuntimeView.py
├── FlowCreationView.py
├── FlowsView.py
├── MapView.py
├── ToastView.py
└── __init__.py
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Shaun Hevey
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #istaflow
2 | Istaflow is automation app built for pythonista. This has been inspired by workflow for iOS you can find it here [Workflow](https://workflow.is)
3 |
4 | You create flows to run flows. Each flow is made up of a series of elements. These elements have a single purpose and are reusable across flows.
5 |
6 | Istaflow currently can run basic flows currently with simple validation for an input to each element.
7 | Istaflow it is in active development but should still be classed as beta as there will be plenty of bugs and features still to add.
8 |
9 | This has been built with pythonista 3 and has only had slight testing in 2.
10 | NOTE: Now that Pythonista 3 has been released I wont be supporting Pythonista 2 so all work arounds that have been included will eventually be removed.
11 |
12 |
--------------------------------------------------------------------------------
/elements/AddressInput.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import dialogs
6 |
7 | class AddressInput(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return None
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'address'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'Manually enter an address'
41 |
42 | def get_title(self):
43 | return 'Address Input'
44 |
45 | def get_icon(self):
46 | return 'iob:map_32'
47 |
48 | def get_category(self):
49 | return 'Location'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input=''):
55 | formDict = [{'type':'text','title':'Title','key':'title'},
56 | {'type':'text', 'title':'Street', 'autocorrection':False},
57 | {'type':'text', 'title':'City', 'autocorrection':False},
58 | {'type':'text', 'title':'Country', 'autocorrection':False},
59 | {'type':'text', 'title':'Zip Postcode','key':'ZIP', 'autocorrection':False}]
60 | address = dialogs.form_dialog(title='Address Input', fields=formDict)
61 | ev = ElementValue(type = self.get_output_type(), value = address)
62 | self.status = 'complete'
63 | return ev
64 |
65 | if __name__ == '__main__':
66 | AddressInput().run()
67 |
68 |
--------------------------------------------------------------------------------
/elements/AdjustDate.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | import datetime
7 |
8 | class AdjustDate(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | self.params.append(ElementParameter(name='timeadjusttype',displayName='Adjust Type',display=True,type='list',value='Seconds',allowedValues=['Microseconds', 'Milliseconds','Seconds','Minutes','Hours','Days','Weeks'],multipleAllowed=False,isVariableAllowed=False))
21 | self.params.append(ElementParameter(name='amount',displayName='Amount',display=True,type='int',value=0))
22 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return 'datetime'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return 'datetime'
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'Add some time to the date'
44 |
45 | def get_title(self):
46 | return 'Adjust Date'
47 |
48 | def get_icon(self):
49 | return 'iob:clock_32'
50 |
51 | def get_category(self):
52 | return 'Date'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | amount = self.get_param_by_name('amount')
59 | option = self.get_param_by_name('timeadjusttype')
60 | td = None
61 | if option.value == 'Microseconds':
62 | td = datetime.timedelta(microseconds=amount.value)
63 | elif option.value == 'Milliseconds':
64 | td = datetime.timedelta(milliseconds = amount.value)
65 | elif option.value == 'Seconds':
66 | td = datetime.timedelta(seconds=amount.value)
67 | elif option.value == 'Minutes':
68 | td = datetime.timedelta(minutes=amount.value)
69 | elif option.value == 'Hours':
70 | td = datetime.timedelta(hours=amount.value)
71 | elif option.value == 'Days':
72 | td = datetime.timedelta(days=amount.value)
73 | elif option.value == 'Weeks':
74 | td = datetime.timedelta(weeks=amount.value)
75 | if td:
76 | input.value = input.value + td
77 | self.status = 'Complete'
78 | return input
79 |
--------------------------------------------------------------------------------
/elements/AppendtoVariable.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 | import copy
7 | from objc_util import *
8 |
9 | class AppendtoVariable(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = []
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return True
19 |
20 | def setup_params(self):
21 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
22 | self.params.append(ElementParameter(name='VariableName',displayName='Variable Name',display=True,type='string'))
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return '*'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return None
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'Appends input to a set variable'
44 |
45 | def get_title(self):
46 | return 'Append to Variable'
47 |
48 | def get_icon(self):
49 | return 'iob:gear_a_32'
50 |
51 | def get_category(self):
52 | return 'Utility'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | np = self.get_param_by_name('VariableName')
59 | name = np.value or console.input_alert('Please enter Variable name')
60 | rv = self.get_param_by_name('fm:runtime_variables')
61 | if not name in rv.value:
62 | rv.value[name] = None
63 | if rv.value[name] == None:
64 | rv.value[name] = input.copyMe()
65 | rv.value[name].value = []
66 | rv.value[name].value.append(input.copyValue())
67 | #if not input.objcCopy:
68 | # rv.value[name] = copy.deepcopy(input)
69 | #else:
70 | # ev = ElementValue(input.type, input.value.copy(), input.isList, )
71 | # rv.value[name] = ev
72 | else:
73 | if input.type == rv.value[name].type:
74 | if not isinstance(rv.value[name].value,list):
75 | #t = copy.deepcopy(rv.value[name].value)
76 | t = rv.value[name].copyValue()
77 | rv.value[name].value = []
78 | rv.value[name].value.append(t)
79 |
80 | if isinstance(input,list):
81 |
82 | for i in input.copyValue():
83 | rv.value[name].value.append(i)
84 | else:
85 | rv.value[name].value.append(input.copyValue())
86 | else:
87 | console.alert('Error','Incorrect type to append to variable',button1='Ok',hide_cancel_button=True)
88 |
89 | self.status = 'complete'
90 |
91 |
--------------------------------------------------------------------------------
/elements/Changetimezone.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import pytz
6 |
7 | class Changetimezone(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = []
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | a = pytz.all_timezones_set
20 | tm = []
21 | for aa in a:
22 | tm.append(aa)
23 | tm.sort()
24 | self.params.append(ElementParameter(name='timezone',displayName='Time Zone',display=True,type='list',value=None,allowedValues=tm,multipleAllowed=False,isVariableAllowed=False))
25 |
26 | def get_status(self):
27 | return self.status
28 |
29 | def get_input_type(self):
30 | return 'datetime'
31 |
32 | def get_output(self):
33 | return self.output
34 |
35 | def get_output_type(self):
36 | return 'datetime'
37 |
38 | def get_params(self):
39 | return self.params
40 |
41 | def set_params(self, params = None):
42 | self.params = params or []
43 |
44 | def get_description(self):
45 | return 'Changes the timezone of the passed datetime object'
46 |
47 | def get_title(self):
48 | return 'Change timezone'
49 |
50 | def get_icon(self):
51 | return 'iob:earth_32'
52 |
53 | def get_category(self):
54 | return 'Date'
55 |
56 | def get_type(self):
57 | return self.type
58 |
59 | def run(self, input=''):
60 | tz = self.get_param_by_name('timezone')
61 | if not tz.value == None:
62 | timezonetouse = pytz.timezone(tz.value)
63 | input.value = input.value.astimezone(timezonetouse)
64 | self.status = 'complete'
65 | return input
66 |
--------------------------------------------------------------------------------
/elements/ConverttoNumber.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class ConverttoNumber(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return False
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return 'number'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Tries to convert the input to a number'
40 |
41 | def get_title(self):
42 | return 'Convert to Number'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_cog_32'
46 |
47 | def get_category(self):
48 | return 'Number'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | if not input.value == None and input.value.isdigit():
55 | self.output = float(str(input.value))
56 | self.status = 'complete'
57 | return ElementValue(type = self.get_output_type(), value = self.output)
58 | else:
59 | self.status = 'error'
60 |
--------------------------------------------------------------------------------
/elements/ConverttoText.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class ConverttoText(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return False
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return 'text'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Tries to convert input to a string'
40 |
41 | def get_title(self):
42 | return 'Convert to Text'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_cog_32'
46 |
47 | def get_category(self):
48 | return 'Text'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.output = str(input.value)
55 | self.status = 'complete'
56 | return ElementValue(type = self.get_output_type(), value = self.output)
57 |
58 |
--------------------------------------------------------------------------------
/elements/Count.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class Count(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return 'number'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Get the count of an object or list'
40 |
41 | def get_title(self):
42 | return 'Count'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_cog_outline_32'
46 |
47 | def get_category(self):
48 | return 'Utility'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.status = 'complete'
55 | return ElementValue(type=self.get_output_type(), value=len(input.value))
56 |
--------------------------------------------------------------------------------
/elements/Date.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import datetime
6 | from dateutil.tz import *
7 |
8 | class Date(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | self.params.append(ElementParameter(name='useutc',displayName='Return in UTC (otherwise local time)',display=True,type='bool',value=False))
21 |
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return None
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return 'datetime'
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Return the current date and time'
43 |
44 | def get_title(self):
45 | return 'Date'
46 |
47 | def get_icon(self):
48 | return 'iob:clock_32'
49 |
50 | def get_category(self):
51 | return 'Date'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self, input=''):
57 | utcparam = self.get_param_by_name('useutc')
58 | local = tzlocal()
59 | utc = tzutc()
60 | now = datetime.datetime.now()
61 | now = now.replace(tzinfo = local)
62 | if utcparam.value:
63 | now = now.astimezone(utc)
64 | self.status = 'Complete'
65 | return ElementValue(type=self.get_output_type(), value=now)
66 |
--------------------------------------------------------------------------------
/elements/DateInput.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | import dialogs
7 | import ui
8 |
9 | class DateInput(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = []
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | self.params.append(ElementParameter(name='type',displayName='DateTime/Date',display=True,type='list',value='DateTime',allowedValues=['DateTime','Date'],isVariableAllowed=False))
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return None
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return 'datetime'
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Date input element'
43 |
44 | def get_title(self):
45 | return 'Date Input'
46 |
47 | def get_icon(self):
48 | return 'iob:clock_32'
49 |
50 | def get_category(self):
51 | return 'Date'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 |
57 | def run(self, input=''):
58 | type = self.get_param_by_name('type').value
59 | value = None
60 | if type == 'DateTime':
61 | value = dialogs.datetime_dialog('Date entry')
62 | elif type == 'Date':
63 | value = dialogs.date_dialog('Date entry')
64 | if value == None:
65 | raise KeyboardInterrupt
66 | self.status = 'complete'
67 | return ElementValue(type=self.get_output_type(), value=value)
68 |
--------------------------------------------------------------------------------
/elements/ElementBase.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | import dialogs
3 | import console
4 | import copy
5 |
6 | class ElementBase (object):
7 | def can_handle_list(self):
8 | raise self.not_implemented()
9 |
10 | def get_status(self):
11 | raise self.not_implemented()
12 |
13 | def get_input(self):
14 | raise self.not_implemented()
15 |
16 | def get_output(self):
17 | raise self.not_implemented()
18 |
19 | def get_input_type(self):
20 | raise self.not_implemented()
21 |
22 | def get_output_type(self):
23 | raise self.not_implemented()
24 |
25 | def get_params(self):
26 | raise self.not_implemented()
27 |
28 | def set_params(self):
29 | raise self.not_implemented()
30 |
31 | def get_description(self):
32 | raise self.not_implemented()
33 |
34 | def get_title(self):
35 | raise self.not_implemented()
36 |
37 | def get_icon(self):
38 | raise self.not_implemented()
39 |
40 | def get_category(self):
41 | raise self.not_implemented()
42 |
43 | def get_type(self):
44 | raise self.not_implemented()
45 |
46 | def run(self):
47 | raise self.not_implemented()
48 |
49 | def get_runtime_variable_for_parameter(self, parameter):
50 | rv = self.get_param_by_name('fm:runtime_variables')
51 | if rv == None:
52 | raise LookupError('Element requires fm:runtime_variables')
53 |
54 | keysavailablestring = ''
55 | for k in rv.value:
56 | keysavailablestring += k + ' '
57 | keysavailablemessage = 'Keys to choose from are: ' + keysavailablestring
58 | while parameter.variableName == None or parameter.variableName.replace(' ', '') == '':
59 | try:
60 | key = dialogs.list_dialog('Vars',list(rv.value.keys()))
61 | parameter.variableName = key
62 | except :
63 | # if dialogs isnt available then fall back to console input
64 | parameter.variableName = console.input_alert(title='Please enter variable title', message=keysavailablemessage)
65 | if parameter.variableName in rv.value:
66 | parameter.value = copy.deepcopy(rv.value[parameter.variableName].value)
67 | else:
68 | raise KeyError('Parameter ' + parameter.variableName + ' does not exist')
69 |
70 | def get_param_by_name(self, name):
71 | params_by_name = [p for p in self.params if p.name == name]
72 | return params_by_name[-1] if params_by_name else None
73 |
74 | def not_implemented(self):
75 | import inspect
76 | fmt = 'Class {} does not implement {}()'
77 | caller_name = inspect.getouterframes(inspect.currentframe(), 2)[1][3]
78 | return NotImplementedError(fmt.format(self.__class__.__name__, caller_name))
79 |
--------------------------------------------------------------------------------
/elements/ElementParameter.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | class ElementParameter (object):
3 | def __init__(self, name, type, displayName='', display=False, value=None, allowedValues=None, multipleAllowed=False, isVariableAllowed = True, askAtRuntime = False):
4 | self.name = name
5 | self.displayName = displayName
6 | self.display = display
7 | self.type = type
8 | self.value = value
9 | self.allowedValues = allowedValues or []
10 | self.multipleAllowed = multipleAllowed
11 | self.useVariable = False
12 | self.isVariableAllowed = isVariableAllowed
13 | self.variableName = ''
14 | self.askAtRuntime = askAtRuntime
15 |
--------------------------------------------------------------------------------
/elements/ElementValue.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | class ElementValue (object):
3 | def __init__(self, type, value, name='', objcCopy=False):
4 | self.type = type
5 | self.value = value
6 | #self.isList = isinstance(value, list)
7 | self.name = name
8 | self.objcCopy = objcCopy
9 |
10 | @property
11 | def isList(self):
12 | return isinstance(self.value, list)
13 |
14 | def copyMe(self):
15 | if self.objcCopy:
16 | type = self.type
17 | if isinstance(self.value,list):
18 | data = []
19 | for d in self.value:
20 | data.append(d.copy())
21 | else:
22 | data = self.value.copy()
23 | value = data
24 | name = self.name
25 | objcCopy = self.objcCopy
26 | ev = ElementValue(type=type, value=value, name=name, objcCopy=self.objcCopy)
27 | return ev
28 | else:
29 | import copy
30 | return copy.deepcopy(self)
31 | def copyValue(self):
32 | if self.objcCopy:
33 | if isinstance(self.value,list):
34 | data = []
35 | for d in self.value:
36 | data.append(d.copy())
37 | else:
38 | data = self.value.copy()
39 | return data
40 | else:
41 | import copy
42 | return copy.deepcopy(self.value)
43 |
--------------------------------------------------------------------------------
/elements/Else.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class Else(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Else'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return '*'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Else conditional block'
40 |
41 | def get_title(self):
42 | return 'Else'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_drag_32'
46 |
47 | def get_category(self):
48 | return 'Dont Display'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.status = 'complete'
55 | return input
56 |
--------------------------------------------------------------------------------
/elements/EndFor.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class EndFor(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'EndFor'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return False
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return None
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return None
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'End of For loop'
40 |
41 | def get_title(self):
42 | return 'End For'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_drag_32'
46 |
47 | def get_category(self):
48 | return 'Dont Display'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.status = 'complete'
55 | return None
56 |
57 |
--------------------------------------------------------------------------------
/elements/EndForEach.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class EndForEach(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'EndForeach'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | pass
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return None
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return None
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'End of Foreach'
40 |
41 | def get_title(self):
42 | return 'End Foreach'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_drag_32'
46 |
47 | def get_category(self):
48 | return 'Dont Display'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | return ElementValue(type='',value='')
55 |
--------------------------------------------------------------------------------
/elements/EndIf.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class EndIf(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'EndIf'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return None
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return None
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'End of the if conditional block'
40 |
41 | def get_title(self):
42 | return 'End If'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_drag_32'
46 |
47 | def get_category(self):
48 | return 'Dont Display'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.status = 'complete'
55 | return None
56 |
--------------------------------------------------------------------------------
/elements/For.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class For(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = []
11 | self.type = 'For'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return False
16 |
17 | def setup_params(self):
18 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
19 | self.params.append(ElementParameter(name='forcount',displayName='For Loop Count',display=True,type='int',value=1))
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return None
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return None
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'For Loop'
41 |
42 | def get_title(self):
43 | return 'For'
44 |
45 | def get_icon(self):
46 | return 'iob:arrow_return_right_32'
47 |
48 | def get_category(self):
49 | return 'Conditional'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input=''):
55 | self.status = 'complete'
56 | return None
57 |
58 |
--------------------------------------------------------------------------------
/elements/ForEach.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class ForEach(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Foreach'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return '*'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Pull each element of a list out'
40 |
41 | def get_title(self):
42 | return 'Foreach'
43 |
44 | def get_icon(self):
45 | return 'iob:arrow_return_right_32'
46 |
47 | def get_category(self):
48 | return 'Conditional'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | if not isinstance(input.value, list):
55 | print('List not provided to foreach')
56 | self.status = 'complete'
57 | return input
58 |
59 |
--------------------------------------------------------------------------------
/elements/GenerateHashOfString.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | import hashlib
7 |
8 | class GenerateHashOfString(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | algs = []
21 | for t in hashlib.algorithms_available:
22 | algs.append(t)
23 | self.params.append(ElementParameter(name='algorithms',displayName='Hash Algorithm',display=True, type='list',value='md5',allowedValues=algs, isVariableAllowed = False))
24 |
25 |
26 | def get_status(self):
27 | return self.status
28 |
29 | def get_input_type(self):
30 | return 'string'
31 |
32 | def get_output(self):
33 | return self.output
34 |
35 | def get_output_type(self):
36 | return 'string'
37 |
38 | def get_params(self):
39 | return self.params
40 |
41 | def set_params(self, params = None):
42 | self.params = params or []
43 |
44 | def get_description(self):
45 | return 'Generates a hash of the input value and returns it'
46 |
47 | def get_title(self):
48 | return 'Generate Hash of string'
49 |
50 | def get_icon(self):
51 | return 'iob:ios7_cog_outline_32'
52 |
53 | def get_category(self):
54 | return 'Utility'
55 |
56 | def get_type(self):
57 | return self.type
58 |
59 | def run(self, input=''):
60 | algo = self.get_param_by_name('algorithms')
61 | self.status = 'complete'
62 | return ElementValue(type=self.get_output_type(), value=hashlib.new(algo.value, input.value.encode('utf-8')).hexdigest())
63 |
--------------------------------------------------------------------------------
/elements/GetAddressfromLocation.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import location
6 |
7 | class GetAddressfromLocation(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return 'location'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'address'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'Get address from location passed in.'
41 |
42 | def get_title(self):
43 | return 'Get Address from Location'
44 |
45 | def get_icon(self):
46 | return 'iob:location_32'
47 |
48 | def get_category(self):
49 | return 'Location'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input):
55 | self.status = 'complete'
56 | loc = location.reverse_geocode(input.value)
57 | return ElementValue(type = self.get_output_type(), value = loc)
58 |
59 |
--------------------------------------------------------------------------------
/elements/GetBatteryDetails.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | # The get battery code is highly based of the battery level example in pythonista 2.0
3 |
4 | from ElementBase import ElementBase
5 | from ElementParameter import ElementParameter
6 | from ElementValue import ElementValue
7 | from objc_util import *
8 |
9 | class GetBatteryDetails(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = None
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | pass
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return None
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return 'battery'
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Get details about the current state of the battery.'
43 |
44 | def get_title(self):
45 | return 'Get Battery Details'
46 |
47 | def get_icon(self):
48 | return 'iob:battery_half_32'
49 |
50 | def get_category(self):
51 | return 'Battery'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self, input=''):
57 | battery_states = {1: 'unplugged', 2: 'charging', 3: 'full'}
58 | device = ObjCClass('UIDevice').currentDevice()
59 | device.setBatteryMonitoringEnabled_(True)
60 | battery_percent = device.batteryLevel() * 100
61 | state = device.batteryState()
62 | device.setBatteryMonitoringEnabled_(False)
63 | batteryDetails = {'Level': battery_percent, 'State': battery_states.get(state, 'unknown')}
64 | self.status = 'complete'
65 | return ElementValue(type=self.get_output_type(), value=batteryDetails)
66 |
67 |
--------------------------------------------------------------------------------
/elements/GetClipboardImage.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import clipboard
6 |
7 | class GetClipboardImage(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return None
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'image'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'This gets the an image from the system clipboard"'
41 |
42 | def get_title(self):
43 | return 'Get Clipboard Image'
44 |
45 | def get_icon(self):
46 | return 'iob:image_32'
47 |
48 | def get_category(self):
49 | return 'Image'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self):
55 | self.status = 'complete'
56 | img = clipboard.get_image()
57 | return ElementValue(type=self.get_output_type(), value=img)
58 |
59 |
--------------------------------------------------------------------------------
/elements/GetClipboardText.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import clipboard
6 |
7 | class GetClipboardText(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return None
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'string'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return "This gets the text value of the system clipboard"
41 |
42 | def get_title(self):
43 | return 'Get Clipboard Text'
44 |
45 | def get_icon(self):
46 | return 'iob:ios7_copy_32'
47 |
48 | def get_category(self):
49 | return 'Text'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self):
55 | clip = clipboard.get()
56 | self.status = 'complete'
57 | return ElementValue(type = self.get_output_type(), value = clip)
58 |
59 |
--------------------------------------------------------------------------------
/elements/GetCurrentLocation.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import location
6 |
7 | class GetCurrentLocation(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = []
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | self.params.append(ElementParameter(name='title',displayName='Title',display=True,type='string',value='Current Location'))
20 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
21 |
22 | def get_status(self):
23 | return self.status
24 |
25 | def get_input_type(self):
26 | return None
27 |
28 | def get_output(self):
29 | return self.output
30 |
31 | def get_output_type(self):
32 | return 'location'
33 |
34 | def get_params(self):
35 | return self.params
36 |
37 | def set_params(self, params = None):
38 | self.params = params or []
39 |
40 | def get_description(self):
41 | return 'Get current location of the device'
42 |
43 | def get_title(self):
44 | return 'Get Current Location'
45 |
46 | def get_icon(self):
47 | return 'iob:location_32'
48 |
49 | def get_category(self):
50 | return 'Location'
51 |
52 | def get_type(self):
53 | return self.type
54 |
55 | def run(self, input=''):
56 | location.start_updates()
57 | loc = location.get_location()
58 | location.stop_updates()
59 | titleParam = self.get_param_by_name('title').value
60 | loc['title'] = titleParam or 'Current Location'
61 | return ElementValue(type = self.get_output_type(), value = loc)
62 |
63 |
--------------------------------------------------------------------------------
/elements/GetImagesfromAppextension.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import appex
6 | import console
7 |
8 | class GetImagesfromAppextension(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | self.params.append(ElementParameter(name='allowMultiple',displayName='Allow Multiple Images',display=True, type='bool',value=False))
21 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return None
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return 'image'
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Returns a list or single image from the app extension'
43 |
44 | def get_title(self):
45 | return 'Get Image(s) from App extension'
46 |
47 | def get_icon(self):
48 | return 'iob:archive_32'
49 |
50 | def get_category(self):
51 | return 'App Extension'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self, input=''):
57 | console.alert(title='Not complete', message='Does not work',button1='Ok',hide_cancel_button=True)
58 | if not appex.is_running_extension():
59 | console.alert(title='Error', message='Not running from app extension',button1='Ok',hide_cancel_button=True)
60 | else:
61 | try:
62 | allowMultiple = self.get_param_by_name('allowMultiple').value
63 | if allowMultiple:
64 | images = appex.get_images()
65 | else:
66 | images = appex.get_image()
67 | ev = ElementValue(type='image',value=images)
68 | return ev
69 | except error:
70 | console.alert(title='Error', message='error: {}'.format(error),button1='Ok',hide_cancel_button=True)
71 |
72 |
--------------------------------------------------------------------------------
/elements/GetLocationfromAddress.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import location
6 |
7 | class GetLocationfromAddress(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return 'address'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'location'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'Get location from Address'
41 |
42 | def get_title(self):
43 | return 'Get Location from Address'
44 |
45 | def get_icon(self):
46 | return 'iob:location_32'
47 |
48 | def get_category(self):
49 | return 'Location'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input):
55 | self.status = 'complete'
56 | v = input.value[0] if isinstance(input.value, list) else input.value
57 | loc = location.geocode(v)
58 | if 'title' in v:
59 | loc[0]['title'] = v['title']
60 | return ElementValue(type = self.get_output_type(), value = loc)
61 |
62 |
--------------------------------------------------------------------------------
/elements/GetName.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class GetName(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return False
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return 'string'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Returns the name of the input '
40 |
41 | def get_title(self):
42 | return 'Get Name'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_cog_32'
46 |
47 | def get_category(self):
48 | return 'Utility'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.status = 'complete'
55 | return ElementValue(type = self.get_output_type(), value = input.name)
56 |
--------------------------------------------------------------------------------
/elements/GetScreenBrightness.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | from objc_util import *
7 | UIScreen = ObjCClass('UIScreen')
8 |
9 | class GetScreenBrightness(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = None
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | pass
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return None
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return 'number'
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Returns the screen brightness as a number between 0-100'
43 |
44 | def get_title(self):
45 | return 'Get Screen Brightness'
46 |
47 | def get_icon(self):
48 | return 'iob:iphone_32'
49 |
50 | def get_category(self):
51 | return 'Utility'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self, input=''):
57 | screen = UIScreen.mainScreen()
58 | val = screen.brightness() * 100
59 | return ElementValue(type = self.get_output_type(), value = val)
60 |
--------------------------------------------------------------------------------
/elements/GetURLContents.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | from ElementBase import ElementBase
4 | from ElementParameter import ElementParameter
5 | from ElementValue import ElementValue
6 | from PIL import Image
7 | try:
8 | import StringIO
9 | except:
10 | from io import StringIO
11 |
12 | import requests
13 | import console
14 | import time
15 | import copy
16 |
17 | class GetURLContents(ElementBase):
18 | def __init__(self):
19 | self.status = 'running'
20 | self.output = None
21 | self.params = []
22 | self.type = 'Standard'
23 | self.setup_params()
24 |
25 | def can_handle_list(self):
26 | return False
27 |
28 | def setup_params(self):
29 | allowedValues = 'GET POST PUT DELETE'.split()
30 | self.params.append(ElementParameter(name='verb',displayName='Verb',display=True, type='list',value='GET',allowedValues=allowedValues, isVariableAllowed = False))
31 | self.params.append(ElementParameter(name='params', displayName='Parameters', display=True, type='dictionary', value=None))
32 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
33 |
34 | def get_status(self):
35 | return self.status
36 |
37 | def get_input_type(self):
38 | return 'url'
39 |
40 | def get_output(self):
41 | return self.output
42 |
43 | def get_output_type(self):
44 | return '*'
45 |
46 | def get_params(self):
47 | return self.params
48 |
49 | def set_params(self, params = None):
50 | self.params = params or []
51 |
52 | def get_description(self):
53 | return 'Get the contents from a URL'
54 |
55 | def get_title(self):
56 | return 'Get URL Contents'
57 |
58 | def get_icon(self):
59 | return 'iob:ios7_download_32'
60 |
61 | def get_category(self):
62 | return 'Url'
63 |
64 | def get_type(self):
65 | return self.type
66 |
67 | def run(self, input=''):
68 | verbParam = self.get_param_by_name('verb')
69 | paramsParam = self.get_param_by_name('params')
70 | if verbParam.value == 'GET':
71 | if paramsParam.value == None:
72 | r = requests.get(input.value)
73 | else:
74 | r = requests.get(input.value, params=paramsParam.value)
75 | elif verbParam.value == 'POST':
76 | if paramsParam.value == None:
77 | r = requests.post(input.value)
78 | else:
79 | r = requests.get(input.value, data=paramsParam.value)
80 |
81 | elif verbParam.value == 'PUT':
82 | r = requests.put(input.value)
83 | elif verbParam.value == 'DELETE':
84 | r = requests.delete(input.value)
85 | self.status = 'complete'
86 | if r.status_code == 200:
87 | type = r.headers['content-type'].split('/')[0]
88 | value = Image.open(StringIO(r.content)) if type == 'image' else r.text
89 | return ElementValue(type=type, value=value)
90 | else:
91 | console.alert(title='Error',message=r.status_code,button1='Ok',hide_cancel_button=True)
92 | return ElementValue(type=None, value=None)
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/elements/GetVariable.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 | import copy
7 | try:
8 | import dialogs
9 | except ImportError:
10 | pass
11 | import ui
12 |
13 | class GetVariable(ElementBase):
14 | def __init__(self):
15 | self.status = 'running'
16 | self.output = None
17 | self.params = []
18 | self.name = None
19 | self.type = 'Standard'
20 | self.setup_params()
21 |
22 | def can_handle_list(self):
23 | return False
24 |
25 | def setup_params(self):
26 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
27 | self.params.append(ElementParameter(name='VariableName',displayName='Variable Name',display=True,type='string'))
28 |
29 | def get_status(self):
30 | return self.status
31 |
32 | def get_input_type(self):
33 | return None
34 |
35 | def get_output(self):
36 | return self.output
37 |
38 | def get_output_type(self):
39 | return '*'
40 |
41 | def get_params(self):
42 | return self.params
43 |
44 | def set_params(self, params = None):
45 | self.params = params or []
46 |
47 | def get_description(self):
48 | return 'Get a variable to be used within the flow.'
49 |
50 | def get_title(self):
51 | return 'Get Variable'
52 |
53 | def get_icon(self):
54 | return 'iob:ios7_gear_32'
55 |
56 | def get_category(self):
57 | return 'Utility'
58 |
59 | def selected_callback(self, item):
60 | self.name = item.name
61 | self.status = 'complete'
62 | self.get_param_by_name('fm:nav_view').value.pop_view()
63 |
64 | def get_type(self):
65 | return self.type
66 |
67 | def run(self):
68 | np = self.get_param_by_name('VariableName')
69 | rv = self.get_param_by_name('fm:runtime_variables')
70 | keysavailablestring = ''
71 | for k in rv.value:
72 | keysavailablestring += k + ' '
73 | keysavailablemessage = 'Keys to choose from are: ' + keysavailablestring
74 | if (np.value or '').replace(' ', '') == '':
75 | try:
76 | key = dialogs.list_dialog('Vars',list(rv.value.keys()))
77 | self.name = key
78 | except :
79 | # if dialogs isnt available then fall back to console input
80 | self.name = console.input_alert(title='Please enter variable title', message=keysavailablemessage)
81 |
82 | else:
83 | self.name = np.value
84 | self.name = self.name or console.input_alert(title='Please enter variable title', message=keysavailablemessage)
85 | return rv.value[self.name].copyMe()
86 |
87 |
--------------------------------------------------------------------------------
/elements/If.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class If(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = []
11 | self.type = 'If'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | self.params.append(ElementParameter(name='checkoption',displayName='Item to check',display=True,type='list',value='input value',allowedValues=['input value','input type'], isVariableAllowed=False))
19 | self.params.append(ElementParameter(name='conditiontype',displayName='Condition Type',display=True,type='list',value='==',allowedValues=['==','<','>','>=','<=','not =='], isVariableAllowed = False))
20 | self.params.append(ElementParameter(name='checkvalue',displayName='Check Value',display=True,type='string',value=None))
21 | self.params.append(ElementParameter(name='ifresult',displayName='If Result',display=False,type='Boolean', value = None))
22 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return '*'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return '*'
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'If conditional branching element'
44 |
45 | def get_title(self):
46 | return 'If'
47 |
48 | def get_icon(self):
49 | return 'iob:arrow_down_c_32'
50 |
51 | def get_category(self):
52 | return 'Conditional'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | ifresult = self.get_param_by_name('ifresult')
59 | ifcondition = self.get_param_by_name('conditiontype')
60 | checkoption = self.get_param_by_name('checkoption')
61 | checkvalue = self.get_param_by_name('checkvalue')
62 | if checkoption.value == 'input value':
63 | ifresult.value = self.checkvalue(input, ifcondition.value, checkvalue.value)
64 | elif checkoption.value == 'input type':
65 | ifresult.value = self.checktype(input, ifcondition.value, checkvalue.value)
66 | self.status = 'Complete'
67 | return input
68 |
69 | def checkvalue(self, value, condition, check_against):
70 | return self.ifcondition(value.value, check_against, condition)
71 |
72 | def checktype(self, value, condition, check_against):
73 | return self.ifcondition(value.type, check_against, condition)
74 |
75 | def ifcondition(self, value, check_against, condition):
76 | if condition == '==':
77 | return self.equals(value, check_against)
78 | elif condition == '<':
79 | return self.lessthan(value, check_against)
80 | elif condition == '>':
81 | return self.greaterthan(value, check_against)
82 | elif condition == '>=':
83 | return self.greaterthanorequal(value, check_against)
84 | elif condition == '<=':
85 | return self.lessthanorequals(value, check_against)
86 | elif condition == 'not ==':
87 | return self.notequal(value, check_against)
88 | return None
89 |
90 | def equals(self, value, checkvalue):
91 | return str(value) == str(checkvalue)
92 |
93 | def lessthan(self, value, checkvalue):
94 | return value < checkvalue
95 |
96 | def greaterthan(self, value, checkvalue):
97 | return value > checkvalue
98 |
99 | def lessthanorequals(self, value, checkvalue):
100 | return value <= checkvalue
101 |
102 | def greaterthanorequal(self, value, checkvalue):
103 | return value >= checkvalue
104 |
105 | def notequal(self, value, checkvalue):
106 | return not value == checkvalue
107 |
--------------------------------------------------------------------------------
/elements/ListTest.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class ListTest(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | pass
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return None
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return 'string'
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return ''
40 |
41 | def get_title(self):
42 | return 'List Test'
43 |
44 | def get_icon(self):
45 | return 'iob:alert_32'
46 |
47 | def get_category(self):
48 | return 'Test'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | return ElementValue(type='string', value=['test','234','qwerty'])
55 |
56 |
--------------------------------------------------------------------------------
/elements/Nothing.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class Nothing(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return None
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return 'Returns nothing, it makes sure nothing is passed to the next element'
40 |
41 | def get_title(self):
42 | return 'Nothing'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_cog_32'
46 |
47 | def get_category(self):
48 | return 'Utility'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | self.status = 'complete'
55 | return None
56 |
--------------------------------------------------------------------------------
/elements/NumberInput.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | import console
7 |
8 | class NumberInput(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = None
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | pass
21 |
22 | def get_status(self):
23 | return self.status
24 |
25 | def get_input_type(self):
26 | return None
27 |
28 | def get_output(self):
29 | return self.output
30 |
31 | def get_output_type(self):
32 | return 'number'
33 |
34 | def get_params(self):
35 | return self.params
36 |
37 | def set_params(self, params = None):
38 | self.params = params or []
39 |
40 | def get_description(self):
41 | return 'Get a number from the user'
42 |
43 | def get_title(self):
44 | return 'Number Input'
45 |
46 | def get_icon(self):
47 | return 'iob:minus_round_32'
48 |
49 | def get_category(self):
50 | return 'Number'
51 |
52 | def get_type(self):
53 | return self.type
54 |
55 | def run(self, input=''):
56 | output = None
57 | while output == None or not output.isdigit():
58 | output = console.input_alert(title='Input', message='Please enter a valid number')
59 | output = float(output)
60 | self.status = 'complete'
61 | return ElementValue(type = self.get_output_type(), value = output)
62 |
--------------------------------------------------------------------------------
/elements/OpenLocationinAppleMaps.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | from objc_util import *
7 |
8 | class OpenLocationinAppleMaps(ElementBase):
9 | map_mode_dict = {'standard': 'm', 'satellite': 'k', 'hybrid': 'h', 'transit': 'r'}
10 |
11 | def __init__(self):
12 | self.status = 'running'
13 | self.output = None
14 | self.params = []
15 | self.type = 'Standard'
16 | self.setup_params()
17 |
18 | def can_handle_list(self):
19 | return False
20 |
21 | def setup_params(self):
22 | self.params.append(ElementParameter(name='mapmode',displayName='Map Mode',display=True,type='list',value='standard',allowedValues=sorted(self.map_mode_dict.keys()),isVariableAllowed=False))
23 | self.params.append(ElementParameter(name='zoom',displayName='Zoom',display=True,type='string',value='12',isVariableAllowed=False))
24 |
25 | def get_status(self):
26 | return self.status
27 |
28 | def get_input_type(self):
29 | return 'location'
30 |
31 | def get_output(self):
32 | return self.output
33 |
34 | def get_output_type(self):
35 | return None
36 |
37 | def get_params(self):
38 | return self.params
39 |
40 | def set_params(self, params = None):
41 | self.params = params or []
42 |
43 | def get_description(self):
44 | return 'Opens a location in the Apple Maps app'
45 |
46 | def get_title(self):
47 | return 'Open Location in Apple Maps'
48 |
49 | def get_icon(self):
50 | return 'iob:map_32'
51 |
52 | def get_category(self):
53 | return 'External App'
54 |
55 | def get_type(self):
56 | return self.type
57 |
58 | def run(self, input=''):
59 | mapmodeparam = self.get_param_by_name('mapmode')
60 | zoomparam = self.get_param_by_name('zoom')
61 | url = 'http://maps.apple.com/?ll={latitude},{longitude}'.format(**input.value)
62 | mm = self.map_mode_dict.get(mapmodeparam.value, '')
63 | if mm:
64 | url += '&t=' + mm
65 | if zoomparam.value:
66 | url += '&z=' + zoomparam.value
67 | uia = ObjCClass('UIApplication').sharedApplication()
68 | if not uia.openURL_(nsurl(url)):
69 | console.alert(title='Error oppening App',message='Something went wrong!',button1='Ok',hide_cancel_button=True)
70 | self.status = 'complete'
71 |
72 |
--------------------------------------------------------------------------------
/elements/OpenLocationinGoogleMaps.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | from objc_util import *
6 | import console
7 |
8 | class OpenLocationinGoogleMaps(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | self.params.append(ElementParameter(name='mapmode',displayName='Map Mode',display=True,type='list',value='standard',allowedValues=['standard','streetview'],isVariableAllowed=False))
21 | self.params.append(ElementParameter(name='viewmode',displayName='View Mode',display=True,type='list',value=None,allowedValues=['satellite', 'traffic', 'transit'],multipleAllowed=True,isVariableAllowed=False))
22 |
23 | self.params.append(ElementParameter(name='zoom',displayName='Zoom',display=True,type='string',value='12',isVariableAllowed=False))
24 |
25 | self.params.append(ElementParameter(name='query',displayName='Query in area',display=True,type='string'))
26 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
27 |
28 | def get_status(self):
29 | return self.status
30 |
31 | def get_input_type(self):
32 | return 'location'
33 |
34 | def get_output(self):
35 | return self.output
36 |
37 | def get_output_type(self):
38 | return None
39 |
40 | def get_params(self):
41 | return self.params
42 |
43 | def set_params(self, params = None):
44 | self.params = params or []
45 |
46 | def get_description(self):
47 | return 'Opens a location in the Google Maps app'
48 |
49 | def get_title(self):
50 | return 'Open Location in Google Maps'
51 |
52 | def get_icon(self):
53 | return 'iob:map_32'
54 |
55 | def get_category(self):
56 | return 'External App'
57 |
58 | def get_type(self):
59 | return self.type
60 |
61 | def run(self, input=''):
62 | mapmodeparam = self.get_param_by_name('mapmode')
63 | viewsparam = self.get_param_by_name('viewmode')
64 | zoomparam = self.get_param_by_name('zoom')
65 | queryparam = self.get_param_by_name('query')
66 | url = 'comgooglemaps://?center={latitude},{longitude}'.format(**input.value)
67 | if mapmodeparam.value:
68 | url += '&mapmode='+ mapmodeparam.value
69 | if viewsparam.value:
70 | url += '&views=' + viewsparam.value
71 | if zoomparam.value:
72 | url += '&zoom=' + zoomparam.value
73 | if queryparam.value:
74 | url += '&q=' + queryparam.value
75 | uia = ObjCClass('UIApplication').sharedApplication()
76 | if not uia.openURL_(nsurl(url)):
77 | console.alert(title='Error oppening App',message='Is Google Maps app installed?',button1='Ok',hide_cancel_button=True)
78 | self.status = 'complete'
79 |
80 |
--------------------------------------------------------------------------------
/elements/OpenURLin.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | from objc_util import *
7 | import console
8 |
9 | class OpenURLin(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = []
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | self.params.append(ElementParameter(name='app',displayName='App to Open in',display=True,type='list',value='safari',allowedValues=['safari','chrome']))
22 |
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return 'url'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return None
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'Open Url in chosen application '
44 |
45 | def get_title(self):
46 | return 'Open URL in'
47 |
48 | def get_icon(self):
49 | return 'iob:ios7_world_outline_32'
50 |
51 | def get_category(self):
52 | return 'Url'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | appparam = self.get_param_by_name('app')
59 | app = appparam.value
60 | uia = ObjCClass('UIApplication').sharedApplication()
61 | url = input.value
62 | if app == 'chrome':
63 | url = url.replace('https://','googlechromes://')
64 | url = url.replace('http://','googlechrome://')
65 | if not uia.openURL_(nsurl(url)):
66 | console.alert(title='Error oppening App',message='Something went wrong!',button1='Ok',hide_cancel_button=True)
67 | self.status = 'complete'
68 |
69 |
70 |
--------------------------------------------------------------------------------
/elements/PickImagefromPhotos.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import photos
6 |
7 | class PickImagefromPhotos(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return None
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'image'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'Pick a image from photo library and returns it.'
41 |
42 | def get_title(self):
43 | return 'Pick Image from Photos'
44 |
45 | def get_icon(self):
46 | return 'iob:camera_32'
47 |
48 | def get_category(self):
49 | return 'Image'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self):
55 | img = photos.pick_asset().get_ui_image()
56 | return ElementValue(type = self.get_output_type(), value = img)
57 |
58 |
--------------------------------------------------------------------------------
/elements/PlayAudio.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | from objc_util import *
6 | import threading
7 | import time
8 |
9 | class PlayAudio(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = []
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | self.params.append(ElementParameter(name='volume',displayName='Player Volume',display=True,type='slider',value=0.5))
22 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return 'audio'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return None
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'Play audio that is input'
44 |
45 | def get_title(self):
46 | return 'Play Audio'
47 |
48 | def get_icon(self):
49 | return 'iob:volume_medium_32'
50 |
51 | def get_category(self):
52 | return 'Audio'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | volume = self.get_param_by_name('volume').value
59 | AVAudioPlayer = ObjCClass('AVAudioPlayer')
60 | player = AVAudioPlayer.alloc().initWithData_error_(input.value['audiodata'], None)
61 | player.volume = volume
62 | player.play()
63 | while player.playing():
64 | time.sleep(0.1)
65 | player.release()
66 | self.status = 'complete'
67 |
68 |
--------------------------------------------------------------------------------
/elements/Print.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class Print(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return True
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return '*'
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return None
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return "This prints the string that is in the input parameter"
40 |
41 | def get_title(self):
42 | return 'Print'
43 |
44 | def get_icon(self):
45 | return 'iob:ios7_printer_32'
46 |
47 | def get_category(self):
48 | return 'Utility'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input):
54 | print((input.value))
55 | self.status = 'complete'
56 |
57 |
--------------------------------------------------------------------------------
/elements/RecordAudio.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | # Based on omz record audio example
3 | from ElementBase import ElementBase
4 | from ElementParameter import ElementParameter
5 | from ElementValue import ElementValue
6 | from objc_util import *
7 | import os
8 | import console
9 |
10 | AVAudioSession = ObjCClass('AVAudioSession')
11 | NSURL = ObjCClass('NSURL')
12 | AVAudioRecorder = ObjCClass('AVAudioRecorder')
13 | NSData = ObjCClass('NSData')
14 |
15 | class RecordAudio(ElementBase):
16 | def __init__(self):
17 | self.status = 'running'
18 | self.output = None
19 | self.params = []
20 | self.type = 'Standard'
21 | self.setup_params()
22 |
23 | def can_handle_list(self):
24 | return False
25 |
26 | def setup_params(self):
27 | self.params.append(ElementParameter(name='tempfilename',displayName='Temporary File name',display=True,type='string',value='recording.m4a'))
28 | self.params.append(ElementParameter(name='removetempfile',displayName='Remove Temporary File',display=True,type='bool',value=True))
29 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
30 | def get_status(self):
31 | return self.status
32 |
33 | def get_input_type(self):
34 | return None
35 |
36 | def get_output(self):
37 | return self.output
38 |
39 | def get_output_type(self):
40 | return 'audio'
41 |
42 | def get_params(self):
43 | return self.params
44 |
45 | def set_params(self, params = None):
46 | self.params = params or []
47 |
48 | def get_description(self):
49 | return 'Record audio from Microphone input'
50 |
51 | def get_title(self):
52 | return 'Record Audio'
53 |
54 | def get_icon(self):
55 | return 'iob:ios7_mic_32'
56 |
57 | def get_category(self):
58 | return 'Audio'
59 |
60 | def get_type(self):
61 | return self.type
62 |
63 | def run(self, input=''):
64 | shared_session = AVAudioSession.sharedInstance()
65 | category_set = shared_session.setCategory_error_(ns('AVAudioSessionCategoryPlayAndRecord'), None)
66 |
67 | settings = {ns('AVFormatIDKey'): ns(1633772320), ns('AVSampleRateKey'):ns(44100.00), ns('AVNumberOfChannelsKey'):ns(2)}
68 |
69 | tempfilenameparam = self.get_param_by_name('tempfilename')
70 | removetempfileparam = self.get_param_by_name('removetempfile')
71 | output_path = os.path.abspath(tempfilenameparam.value)
72 |
73 | out_url = NSURL.fileURLWithPath_(ns(output_path))
74 | recorder = AVAudioRecorder.alloc().initWithURL_settings_error_(out_url, settings, None)
75 | started_recording = recorder.record()
76 | try:
77 | if started_recording:
78 | while True:
79 | console.alert(title='Recording started', message='close this alert to end recording...')
80 | except KeyboardInterrupt:
81 | recorder.stop()
82 | recorder.release()
83 | data = NSData.dataWithContentsOfURL_(out_url)
84 | retfilepath = output_path
85 | if removetempfileparam.value:
86 | os.remove(output_path)
87 | retfilepath = None
88 | return ElementValue(type=self.get_output_type(), value={'type':'m4a','filename':tempfilenameparam.value, 'audiodata':data, 'filepath':retfilepath}, objcCopy = True)
89 | self.status = 'complete'
90 |
--------------------------------------------------------------------------------
/elements/SaveImagetoCameraRoll.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 | import photos
7 |
8 | class SaveImagetoCameraRoll(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = None
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return False
18 |
19 | def setup_params(self):
20 | pass
21 |
22 | def get_status(self):
23 | return self.status
24 |
25 | def get_input_type(self):
26 | return 'image'
27 |
28 | def get_output(self):
29 | return self.output
30 |
31 | def get_output_type(self):
32 | return None
33 |
34 | def get_params(self):
35 | return self.params
36 |
37 | def set_params(self, params = None):
38 | self.params = params or []
39 |
40 | def get_description(self):
41 | return 'Saves input image to Camera Roll'
42 |
43 | def get_title(self):
44 | return 'Save Image to Camera Roll'
45 |
46 | def get_icon(self):
47 | return 'iob:camera_32'
48 |
49 | def get_category(self):
50 | return 'Image'
51 |
52 | def get_type(self):
53 | return self.type
54 |
55 | def run(self, input):
56 | try:
57 | if not photos.save_image(input.value):
58 | console.alert("didn't work")
59 | except error:
60 | console.alert('error: {}'.format(error))
61 | self.status = 'complete'
62 |
63 |
--------------------------------------------------------------------------------
/elements/SetClipboardImage.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import clipboard
6 |
7 | class SetClipboardImage(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return 'image'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return None
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = []):
37 | self.params = params
38 |
39 | def get_description(self):
40 | return "This sets the system clipboard with image input provided."
41 |
42 | def get_title(self):
43 | return 'Set Clipboard Image'
44 |
45 | def get_icon(self):
46 | return 'iob:image_32'
47 |
48 | def get_category(self):
49 | return 'Image'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input):
55 | clipboard.set_image(input.value)
56 | self.status = 'complete'
57 |
--------------------------------------------------------------------------------
/elements/SetClipboardText.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import clipboard
6 |
7 | class SetClipboardText(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return 'string'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return None
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params=[]):
37 | self.params=params
38 |
39 | def get_description(self):
40 | return "This sets the system clipboard with text input provided."
41 |
42 | def get_title(self):
43 | return 'Set Clipboard Text'
44 |
45 | def get_icon(self):
46 | return 'iob:ios7_copy_32'
47 |
48 | def get_category(self):
49 | return 'Text'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input):
55 | clipboard.set(input.value)
56 | self.status = 'complete'
57 |
--------------------------------------------------------------------------------
/elements/SetName.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class SetName(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = []
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return False
16 |
17 | def setup_params(self):
18 | self.params.append(ElementParameter(name='name',displayName='Name',display=True,type='string', value=''))
19 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return '*'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return '*'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'Sets the name of the input value and returns it.'
41 |
42 | def get_title(self):
43 | return 'Set Name'
44 |
45 | def get_icon(self):
46 | return 'iob:ios7_cog_32'
47 |
48 | def get_category(self):
49 | return 'Utility'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input=''):
55 | name = self.get_param_by_name('name')
56 | input.name = name.value
57 | self.status = 'complete'
58 | return input
59 |
--------------------------------------------------------------------------------
/elements/SetScreenBrightness.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | from objc_util import *
7 | UIScreen = ObjCClass('UIScreen')
8 |
9 | class SetScreenBrightness(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = None
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | pass
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return 'number'
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return None
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Set Screen Brightness based on input'
43 |
44 | def get_title(self):
45 | return 'Set Screen Brightness'
46 |
47 | def get_icon(self):
48 | return 'iob:iphone_32'
49 |
50 | def get_category(self):
51 | return 'Utility'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self, input=''):
57 | brightness = input.value
58 | if brightness > 100:
59 | brightness = 100
60 | elif brightness < 0:
61 | brightness = 0
62 |
63 | brightness = brightness/100
64 | screen = UIScreen.mainScreen()
65 | screen.setBrightness_(brightness)
66 | #time.sleep(0.3)
67 | self.status = 'complete'
68 |
69 |
--------------------------------------------------------------------------------
/elements/SetVariable.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 | import copy
7 |
8 | class SetVariable(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return True
18 |
19 | def setup_params(self):
20 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
21 | self.params.append(ElementParameter(name='VariableName',displayName='Variable Name',display=True,type='string'))
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return '*'
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return None
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = []):
39 | self.params = params
40 |
41 | def get_description(self):
42 | return 'Set a variable to be used within the flow.'
43 |
44 | def get_title(self):
45 | return 'Set Variable'
46 |
47 | def get_icon(self):
48 | return 'iob:ios7_gear_32'
49 |
50 | def get_category(self):
51 | return 'Utility'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self, input):
57 | np = self.get_param_by_name('VariableName')
58 | if np.value == None:
59 | name = console.input_alert('Please enter Variable name')
60 | else:
61 | name = np.value
62 | rv = self.get_param_by_name('fm:runtime_variables')
63 | rv.value[name] = copy.deepcopy(input)
64 | self.status = 'complete'
65 |
--------------------------------------------------------------------------------
/elements/SetVolume.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | from objc_util import NSBundle, ObjCClass, on_main_thread
7 | NSBundle.bundleWithPath_('/System/Library/Frameworks/MediaPlayer.framework').load()
8 | MPVolumeView = ObjCClass('MPVolumeView')
9 |
10 | class SetVolume(ElementBase):
11 | def __init__(self):
12 | self.status = 'running'
13 | self.output = None
14 | self.params = None
15 | self.type = 'Standard'
16 | self.setup_params()
17 |
18 | def can_handle_list(self):
19 | return False
20 |
21 | def setup_params(self):
22 | pass
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return 'number'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return None
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'Changes System volume to input value between 0 - 100'
44 |
45 | def get_title(self):
46 | return 'Set Volume'
47 |
48 | def get_icon(self):
49 | return 'iob:ios7_volume_high_32'
50 |
51 | def get_category(self):
52 | return 'Utility'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | val = input.value
59 | if val > 100:
60 | val = 100
61 | elif val < 0:
62 | val = 0
63 |
64 | val = val/100
65 | set_system_volume(val)
66 |
67 | @on_main_thread
68 | def set_system_volume(value):
69 | volume_view = MPVolumeView.new().autorelease()
70 | for subview in volume_view.subviews():
71 | if subview.isKindOfClass_(ObjCClass('UISlider')):
72 | subview.value = value
73 | break
74 |
75 |
--------------------------------------------------------------------------------
/elements/ShowAlert.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 |
7 | class ShowAlert(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return True
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return '*'
26 |
27 | def get_output(self):
28 | self.output
29 |
30 | def get_output_type(self):
31 | return None
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params=[]):
37 | self.params = params
38 |
39 | def get_description(self):
40 | return "This show an alert from the string that is in the input parameter"
41 |
42 | def get_title(self):
43 | return 'Show Alert'
44 |
45 | def get_icon(self):
46 | return 'iob:alert_circled_32'
47 |
48 | def get_category(self):
49 | return 'Utility'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input):
55 | self.status = 'complete'
56 | input = str(input.value)
57 | title = __file__.rpartition('/')[2].partition('.')[0] or 'Message'
58 | console.alert(title=title, message=input, button1='Ok', hide_cancel_button=True)
59 |
60 |
--------------------------------------------------------------------------------
/elements/ShowlocationonMap.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | import sys
3 | if not '..' in sys.path:
4 | sys.path.append('..')
5 | import time
6 |
7 | from ElementBase import ElementBase
8 | from ElementParameter import ElementParameter
9 | from ElementValue import ElementValue
10 | from views.MapView import MapView
11 |
12 | sys.path.remove('..')
13 | class ShowlocationonMap(ElementBase):
14 | def __init__(self):
15 | self.status = 'running'
16 | self.output = None
17 | self.params = None
18 | self.type = 'Standard'
19 | self.setup_params()
20 |
21 | def can_handle_list(self):
22 | return True
23 |
24 | def setup_params(self):
25 | pass
26 |
27 | def get_status(self):
28 | return self.status
29 |
30 | def get_input_type(self):
31 | return 'location'
32 |
33 | def get_output(self):
34 | return self.output
35 |
36 | def get_output_type(self):
37 | return None
38 |
39 | def get_params(self):
40 | return self.params
41 |
42 | def set_params(self, params = None):
43 | self.params = params or []
44 |
45 | def get_description(self):
46 | return 'Shows a location or list of on a map'
47 |
48 | def get_title(self):
49 | return 'Show location on Map'
50 |
51 | def get_icon(self):
52 | return 'iob:map_32'
53 |
54 | def get_category(self):
55 | return 'Location'
56 |
57 | def get_type(self):
58 | return self.type
59 |
60 | def run(self, input=''):
61 | m = MapView()
62 |
63 | if input.isList:
64 | for loc in input.value:
65 | title = str(loc['latitude']) + ', ' + str(loc['longitude'])
66 | if 'title' in list(loc.keys()):
67 | title = loc['title']
68 | m.add_pin(lat = loc['latitude'], lon = loc['longitude'],title=title)
69 | else:
70 | title = str(input.value['latitude']) + ', ' + str(input.value['longitude'])
71 | if 'title' in list(input.value.keys()):
72 | title = input.value['title']
73 | m.add_pin(lat = input.value['latitude'], lon = input.value['longitude'],title=title)
74 | m.present()
75 | while m.on_screen:
76 | time.sleep(0.1)
77 | self.status = 'complete'
78 |
79 |
--------------------------------------------------------------------------------
/elements/Sleep.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | import time
7 |
8 | class Sleep(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = []
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | return True
18 |
19 | def setup_params(self):
20 | self.params.append(ElementParameter(name='secondstosleep',displayName='Seconds to sleep',display=True,type='int',value=1))
21 |
22 | self.params.append(ElementParameter(name='fm:runtime_variables',type='*'))
23 |
24 | def get_status(self):
25 | return self.status
26 |
27 | def get_input_type(self):
28 | return '*'
29 |
30 | def get_output(self):
31 | return self.output
32 |
33 | def get_output_type(self):
34 | return None
35 |
36 | def get_params(self):
37 | return self.params
38 |
39 | def set_params(self, params = None):
40 | self.params = params or []
41 |
42 | def get_description(self):
43 | return 'Sleep for the number of seconds set'
44 |
45 | def get_title(self):
46 | return 'Sleep'
47 |
48 | def get_icon(self):
49 | return 'iob:ios7_time_32'
50 |
51 | def get_category(self):
52 | return 'Utility'
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self, input=''):
58 | t = self.get_param_by_name('secondstosleep')
59 | ttu = t.value
60 | if ttu < 0:
61 | ttu = 0
62 | time.sleep(ttu)
63 |
--------------------------------------------------------------------------------
/elements/SpeakText.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import speech
6 |
7 | class SpeakText(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = []
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | self.params.append(ElementParameter(name='speechlanguage',displayName='Speech Language',display=True,type='list',value='en_US',allowedValues=speech.get_languages(), isVariableAllowed=False))
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return 'string'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return None
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return 'Speak the text that is input to it'
41 |
42 | def get_title(self):
43 | return 'Speak Text'
44 |
45 | def get_icon(self):
46 | return 'iob:volume_medium_32'
47 |
48 | def get_category(self):
49 | return 'Text'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input):
55 | lang = self.get_param_by_name('speechlanguage')
56 | speech.say(input.value, lang.value)
57 | self.status = 'complete'
58 |
--------------------------------------------------------------------------------
/elements/TakePhoto.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import photos
6 | import console
7 | import time
8 |
9 | class TakePhoto(ElementBase):
10 | def __init__(self):
11 | self.status = 'running'
12 | self.output = None
13 | self.params = None
14 | self.type = 'Standard'
15 | self.setup_params()
16 |
17 | def can_handle_list(self):
18 | return False
19 |
20 | def setup_params(self):
21 | pass
22 |
23 | def get_status(self):
24 | return self.status
25 |
26 | def get_input_type(self):
27 | return None
28 |
29 | def get_output(self):
30 | return self.output
31 |
32 | def get_output_type(self):
33 | return 'image'
34 |
35 | def get_params(self):
36 | return self.params
37 |
38 | def set_params(self, params = None):
39 | self.params = params or []
40 |
41 | def get_description(self):
42 | return 'Take a photo using the devices camera and returns it.'
43 |
44 | def get_title(self):
45 | return 'Take Photo'
46 |
47 | def get_icon(self):
48 | return 'iob:ios7_camera_32'
49 |
50 | def get_category(self):
51 | return 'Image'
52 |
53 | def get_type(self):
54 | return self.type
55 |
56 | def run(self):
57 | self.status = 'complete'
58 | #console.alert(title='Known Issue',message='Take Photo sometimes freezes the ui and pythonista needs to be killed.',button1='Ok',hide_cancel_button=True)
59 | time.sleep(.5)
60 | return ElementValue(type = self.get_output_type(), value = photos.capture_image())
61 |
62 |
--------------------------------------------------------------------------------
/elements/Template.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 |
6 | class {title}(ElementBase):
7 | def __init__(self):
8 | self.status = 'running'
9 | self.output = None
10 | self.params = None
11 | self.type = 'Standard'
12 | self.setup_params()
13 |
14 | def can_handle_list(self):
15 | return {canHandleList}
16 |
17 | def setup_params(self):
18 | pass
19 |
20 | def get_status(self):
21 | return self.status
22 |
23 | def get_input_type(self):
24 | return {input_type}
25 |
26 | def get_output(self):
27 | return self.output
28 |
29 | def get_output_type(self):
30 | return {output_type}
31 |
32 | def get_params(self):
33 | return self.params
34 |
35 | def set_params(self, params = None):
36 | self.params = params or []
37 |
38 | def get_description(self):
39 | return '{description}'
40 |
41 | def get_title(self):
42 | return '{title_space}'
43 |
44 | def get_icon(self):
45 | return '{icon}'
46 |
47 | def get_category(self):
48 | return '{category}'
49 |
50 | def get_type(self):
51 | return self.type
52 |
53 | def run(self, input=''):
54 | #where the magic happens, put element logic here input is only used if input type is not None, return something if output type is not None, NOTE: for future changes please set self.status to 'complete' if successful or 'error' if error required
55 | pass
56 |
--------------------------------------------------------------------------------
/elements/TextInput.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 |
7 | class TextInput(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = None
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | return False
17 |
18 | def setup_params(self):
19 | pass
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return None
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'string'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = None):
37 | self.params = params or []
38 |
39 | def get_description(self):
40 | return "This displays a text box for the user to enter text"
41 |
42 | def get_title(self):
43 | return 'Text Input'
44 |
45 | def get_icon(self):
46 | return 'iob:document_text_32'
47 |
48 | def get_category(self):
49 | return 'Text'
50 |
51 | def show_input(self):
52 | self.output = console.input_alert('Please enter text')
53 |
54 | def get_type(self):
55 | return self.type
56 |
57 | def run(self):
58 | self.status = 'complete'
59 | self.show_input()
60 | return ElementValue(type = self.get_output_type(), value = self.output)
61 |
62 |
--------------------------------------------------------------------------------
/elements/TexttoURL.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | import console
6 |
7 | class TexttoURL(ElementBase):
8 | def __init__(self):
9 | self.status = 'running'
10 | self.output = None
11 | self.params = []
12 | self.type = 'Standard'
13 | self.setup_params()
14 |
15 | def can_handle_list(self):
16 | pass
17 |
18 | def setup_params(self):
19 | self.params.append(ElementParameter(name='protocol',displayName='Protocol',display=True,type='list',value='http://',allowedValues=['http://','https://','ftp://'],isVariableAllowed=False))
20 |
21 | def get_status(self):
22 | return self.status
23 |
24 | def get_input_type(self):
25 | return 'string'
26 |
27 | def get_output(self):
28 | return self.output
29 |
30 | def get_output_type(self):
31 | return 'url'
32 |
33 | def get_params(self):
34 | return self.params
35 |
36 | def set_params(self, params = []):
37 | self.params = params
38 |
39 | def get_description(self):
40 | return 'Takes a string input and converts to a URL'
41 |
42 | def get_title(self):
43 | return 'Text to URL'
44 |
45 | def get_icon(self):
46 | return 'iob:ios7_world_outline_32'
47 |
48 | def get_category(self):
49 | return 'Url'
50 |
51 | def get_type(self):
52 | return self.type
53 |
54 | def run(self, input=''):
55 | stringUrl = input.value
56 | protoParam = self.get_param_by_name('protocol').value
57 | if not stringUrl:
58 | console.alert(title='Error',message='No url was given',button1='Ok',hide_cancel_button=True)
59 | return None
60 | if stringUrl[:len(protoParam)].find(protoParam) == -1:
61 | if not '//' in stringUrl:
62 | stringUrl = protoParam + stringUrl
63 | else:
64 | console.alert(title='Information',message='Url passed with incorrect protocol given',button1='Ok',hide_cancel_button=True)
65 | return ElementValue(type='url',value=stringUrl)
66 |
67 |
--------------------------------------------------------------------------------
/elements/VibrateDevice.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | from ElementBase import ElementBase
3 | from ElementParameter import ElementParameter
4 | from ElementValue import ElementValue
5 | from objc_util import *
6 | import ctypes
7 |
8 | class VibrateDevice(ElementBase):
9 | def __init__(self):
10 | self.status = 'running'
11 | self.output = None
12 | self.params = None
13 | self.type = 'Standard'
14 | self.setup_params()
15 |
16 | def can_handle_list(self):
17 | pass
18 |
19 | def setup_params(self):
20 | pass
21 |
22 | def get_status(self):
23 | return self.status
24 |
25 | def get_input_type(self):
26 | return '*'
27 |
28 | def get_output(self):
29 | return self.output
30 |
31 | def get_output_type(self):
32 | return None
33 |
34 | def get_params(self):
35 | return self.params
36 |
37 | def set_params(self, params = None):
38 | self.params = params or []
39 |
40 | def get_description(self):
41 | return 'Vibrates the device'
42 |
43 | def get_title(self):
44 | return 'Vibrate Device'
45 |
46 | def get_icon(self):
47 | return 'iob:load_b_32'
48 |
49 | def get_category(self):
50 | return 'Utility'
51 |
52 | def get_type(self):
53 | return self.type
54 |
55 | def run(self, input=''):
56 | p = ctypes.CDLL(None).AudioServicesPlaySystemSound
57 | p.restype, p.argtypes = None, [ctypes.c_int32]
58 | vibrate_id = 0x00000fff
59 | p(vibrate_id)
60 | self.status = 'complete'
61 |
62 |
--------------------------------------------------------------------------------
/elements/__init__.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
--------------------------------------------------------------------------------
/istaflow.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # coding: utf-8
3 |
4 | from __future__ import absolute_import
5 | from views import ElementListView, FlowCreationView, FlowsView, ElementManagementView, ElementCreationView, ElementRuntimeView, ToastView
6 | from managers import ElementManager, FlowManager, ThemeManager, HomeScreenManager, SettingsManager
7 | import ui
8 | import collections
9 | import console
10 | import os
11 | import dialogs
12 | import appex
13 | import sys
14 | import clipboard
15 |
16 | class ista(object):
17 | def __init__(self):
18 | self.hide_title_bar=True
19 | self.elements_view = None
20 | self.element_management_view = None
21 | self.element_creation_view = None
22 | self.flow_creation_view = None
23 | self.navigation_view = None
24 | self.flow_view = None
25 | self.element_runtime_view = None
26 | self.element_manager = None
27 | self.flow_manager = None
28 | self.theme_manager = None
29 | self.home_screen_manager = None
30 | self.elements = None
31 | self.selectedElements = []
32 | self.selectedFlowType = ''
33 | self.flows = []
34 | self.selectedFlow = None
35 | self.flow_passed_in = None
36 | self.settings_manager = None
37 | self.setup_settingsmanager()
38 | self.setup_thememanager()
39 | self.setup_homescreenmanager()
40 | self.setup_elementsmanager()
41 | self.setup_flowsmanager()
42 | self.get_valid_elements()
43 | self.get_flows(appex.is_running_extension())
44 | self.setup_elementsview()
45 | self.setup_elementmanagementview()
46 | self.setup_elementcreationview()
47 | self.setup_flowsview()
48 | self.setup_flowcreationview()
49 | self.setup_elementruntimeview()
50 | self.setup_navigationview(self.flow_view)
51 | self.check_params()
52 |
53 | def check_params(self):
54 | if len(sys.argv) > 1:
55 | self.flow_passed_in = sys.argv[1]
56 | if self.flow_passed_in in self.flows:
57 | self.flowselectedcb(self.flow_passed_in, True)
58 | self.flow_passed_in = None
59 | else:
60 | console.alert('Error', self.flow_passed_in + ' does not exist!', button1='Ok',hide_cancel_button=True)
61 | self.flow_passed_in = None
62 |
63 | def setup_homescreenmanager(self):
64 | self.home_screen_manager = HomeScreenManager.HomeScreenManager()
65 |
66 | def setup_elementruntimeview(self):
67 | self.element_runtime_view = ElementRuntimeView.get_view(self.theme_manager)
68 |
69 | def setup_settingsmanager(self):
70 | self.settings_manager = SettingsManager.SettingsManager()
71 |
72 | def show_settingmanager(self, sender):
73 | self.settings_manager.show_form()
74 |
75 | def get_valid_elements(self):
76 | if self.element_manager == None:
77 | raise ValueError("element_manager hasnt been initialised")
78 | else:
79 | self.elements = {}
80 | elements_to_sort = self.element_manager.get_all_elements('valid')
81 | for element in elements_to_sort:
82 | if self.elements == None:
83 | self.elements = {}
84 | try:
85 | ele_value = self.elements[element.get_category()]
86 | ele_value.append(element)
87 | ele_value.sort(key=lambda x:x.get_title())
88 | self.elements[element.get_category()] = ele_value
89 | except KeyError:
90 | self.elements[element.get_category()]=[element]
91 | self.elements = collections.OrderedDict(sorted(list(self.elements.items()), key=lambda t:t[0] ))
92 |
93 | def get_flows(self, appexonly):
94 | self.flows = self.flow_manager.get_flows(appexonly=appexonly)
95 |
96 | def show_elementruntimeview(self, element):
97 | self.element_runtime_view.data_source.load_element(element)
98 | self.element_runtime_view.reload()
99 | self.navigation_view.push_view(self.element_runtime_view)
100 |
101 | def show_flowcreationview(self, sender, autorun=False):
102 | self.validate_navigationview()
103 | self.selectedElements = []
104 | if not self.selectedFlow == None:
105 | elements = self.flow_manager.get_element_details_for_flow(self.selectedFlow)
106 | for element in elements:
107 | e = self.element_manager.get_element_with_title(element['title'])
108 | if e == None:
109 | raise ValueError('Flow has an element that isn\'t available. Title: ' + element['title'])
110 | if not e.get_params() == None:
111 | for p in e.get_params():
112 | if p.name in list(element['params'].keys()):
113 | temp = element['params'][p.name]
114 | if(isinstance(temp, dict)):
115 | p.value = temp['value']
116 | p.useVariable = temp['useVariable']
117 | p.variableName = temp['variableName']
118 | p.askAtRuntime = temp['askAtRuntime']
119 | else:
120 | p.value = temp
121 | self.selectedElements.append(e)
122 | type = self.flow_manager.get_type_for_flow(self.selectedFlow)
123 | title = os.path.splitext(self.selectedFlow)[0]
124 | self.flow_creation_view.name = title
125 | self.flow_creation_view.data_source.title = title
126 | self.flow_creation_view.data_source.flowType = type
127 | self.selectedFlow = None
128 | if autorun:
129 | self.runflow(None)
130 | else:
131 | self.flow_creation_view.data_source.title = ''
132 | self.flow_creation_view.name = 'New Flow'
133 | self.flow_creation_view.data_source.flowType = 'Normal'
134 | self.flow_creation_view.data_source.elements = self.selectedElements
135 | self.flow_creation_view.data_source.update_buttons()
136 | self.flow_creation_view.reload_data()
137 |
138 | if self.flow_creation_view == None:
139 | raise ValueError("flow_creation_view hasnt been initialised")
140 | else:
141 | self.flow_creation_view.editing = False
142 | self.navigation_view.push_view(self.flow_creation_view)
143 |
144 | def show_assetpicker(self, view):
145 | self.navigation_view.push_view(view)
146 |
147 | def close_assetpicker(self, view):
148 | self.navigation_view.pop_view(view)
149 |
150 | def setup_navigationview(self, initview):
151 | initview.right_button_items = [ui.ButtonItem(title='Add Flow', action=self.show_flow_choice_menu)]
152 | initview.left_button_items = [ui.ButtonItem(title='Elements', action=self.show_elementmanagementview),ui.ButtonItem(title='Settings',action=self.show_settingmanager)]
153 | self.navigation_view = ui.NavigationView(initview)
154 | self.navigation_view.bar_tint_color=self.theme_manager.main_bar_colour
155 | self.navigation_view.tint_color = self.theme_manager.main_tint_colour
156 | self.navigation_view.background_color = self.theme_manager.main_background_colour
157 | self.navigation_view.title_color = self.theme_manager.main_title_text_colour
158 |
159 | @ui.in_background
160 | def show_flow_choice_menu(self,sender):
161 | option = console.alert(title='Create Flow', message='Would you like to import or create?', hide_cancel_button=True, button1='Import from Clipboard', button2='Create')
162 | if option == 1:
163 | title = ''
164 | while title == '':
165 | title = console.input_alert(title='Please enter title for flow', message='If flow exists it will be copied over')
166 |
167 | self.flow_manager.create_from_export(title, clipboard.get())
168 | self.get_flows(appex.is_running_extension())
169 | self.flow_view.data_source.flows = self.flows
170 | self.flow_view.reload_data()
171 | elif option == 2:
172 | self.show_flowcreationview(sender)
173 | def setup_flowsmanager(self):
174 | self.flow_manager = FlowManager.FlowManager(self.elementchange)
175 |
176 | def setup_elementsmanager(self):
177 | self.element_manager = ElementManager.ElementManager()
178 |
179 | def setup_thememanager(self):
180 | self.theme_manager = ThemeManager.ThemeManager()
181 |
182 | def setup_elementsview(self):
183 | self.elements_view = ElementListView.get_view(self.elements, self.elementselectedcb, self.theme_manager)
184 |
185 | def setup_elementmanagementview(self):
186 | self.element_management_view = ElementManagementView.get_view(self.elements, self.theme_manager)
187 |
188 | def setup_elementcreationview(self):
189 | self.element_creation_view = ElementCreationView.get_view(savecb=self.create_element, apcb=self.show_assetpicker, capcb = self.close_assetpicker, thememanager = self.theme_manager)
190 |
191 | def setup_flowsview(self):
192 | self.flow_view = FlowsView.get_view(self.flows, self.flowselectedcb,self.deleteflow, self.theme_manager)
193 |
194 | def setup_flowcreationview(self):
195 | self.flow_creation_view = FlowCreationView.get_view(elements = self.selectedElements, saveCallBack = self.savecb, addElementAction = self.show_elementsview, saveFlowAction = self.saveflow, runFlowAction = self.runflow, showElementRuntimeView = self.show_elementruntimeview, thememanager=self.theme_manager, flowType = self.selectedFlowType, flowTypeSelection = self.show_flowtypeselection, saveToHomeScreenAction = self.addFlowToHomeScreen, copyFlowToClipboardCallBack=self.copyFlowToClipboard)
196 |
197 | @ui.in_background
198 | def show_flowtypeselection(self):
199 | self.selectedFlowType = self.flow_creation_view.data_source.flowType
200 | type = dialogs.list_dialog(title='Flow Type', items=['Normal','Action Extension'])
201 | if not type == None:
202 | self.selectedFlowType = type
203 | self.flow_creation_view.data_source.flowType = self.selectedFlowType
204 | self.flow_creation_view.reload_data()
205 |
206 | def deleteflow(self, flowtitle):
207 | self.flow_manager.delete_flow(flowtitle)
208 |
209 | def copyFlowToClipboard(self):
210 | if self.flow_creation_view.data_source.title == '':
211 | console.alert(title='Error',message='Please enter a title',button1='Ok',hide_cancel_button=True)
212 | else:
213 | try:
214 | self.flow_manager.copy_Flow_To_Clipboard(self.flow_creation_view.data_source.title+'.flow')
215 | console.alert(title='Success', message='Flow copied to clipboard', hide_cancel_button=True, button1='Ok')
216 | except FileNotFoundError:
217 | console.alert(title='Error Sharing', message='Flow not found, have you saved your flow?')
218 |
219 | #@ui.in_background
220 | def saveflow(self,sender):
221 | if self.flow_creation_view.data_source.title == '':
222 | self.show_alert(title='Error', message='Please enter a title')
223 | #console.alert(title='Error',message='Please enter a title',button1='Ok',hide_cancel_button=True)
224 | else:
225 | if not self.flow_creation_view.data_source.oldtitle == '':
226 | self.deleteflow(self.flow_creation_view.data_source.oldtitle+'.flow')
227 | self.selectedFlowType = self.flow_creation_view.data_source.flowType
228 | self.flow_manager.save_flow(self.flow_creation_view.data_source.title, self.selectedElements, self.selectedFlowType)
229 | self.show_alert(title='Success', message='Flow has been saved')
230 | #console.alert(title='Success',message='Flow has been saved',button1='Ok',hide_cancel_button=True)
231 | self.get_flows(appex.is_running_extension())
232 | self.flow_view.data_source.flows = self.flows
233 | self.flow_view.reload_data()
234 |
235 | #@ui.in_background
236 | def addFlowToHomeScreen(self):
237 | if self.flow_creation_view.data_source.title == '':
238 | self.show_alert(title='Error', message='Please enter a title')
239 | #console.alert(title='Error',message='Please enter a title',button1='Ok',hide_cancel_button=True)
240 | else:
241 | self.home_screen_manager.show_form(self.flow_creation_view.data_source.title+'.flow')
242 |
243 | def validate_navigationview(self):
244 | if self.navigation_view == None:
245 | raise ValueError("navigation_view hasn't been initialised")
246 |
247 | def show_elementsview(self, sender):
248 | self.validate_navigationview()
249 | if self.elements_view == None:
250 | raise ValueError("elements_view hasnt been initialised")
251 | else:
252 | self.navigation_view.push_view(self.elements_view)
253 |
254 | def show_elementmanagementview(self, sender):
255 | self.validate_navigationview()
256 | if self.element_management_view == None:
257 | raise ValueError("element_management_view hasnt been initialised")
258 | else:
259 | self.element_management_view.right_button_items = [ui.ButtonItem(title='Create Element', action=self.show_elementcreationview)]
260 | self.navigation_view.push_view(self.element_management_view)
261 |
262 | def show_elementcreationview(self, sender):
263 | self.validate_navigationview()
264 | if self.element_creation_view == None:
265 | raise ValueError("element_creation_view hasnt been initialised")
266 | else:
267 | self.navigation_view.push_view(self.element_creation_view)
268 |
269 | def close_elementsview(self):
270 | if self.elements_view == None:
271 | raise ValueError("elements_view hasnt been initialised")
272 | else:
273 | self.navigation_view.pop_view(self.elements_view)
274 |
275 | def close_flowcreationview(self):
276 | if self.flow_creation_view == None:
277 | raise ValueError("flow_creation_view hasnt been initialised")
278 | else:
279 | self.navigation_view.pop_view(self.flow_creation_view)
280 |
281 | def show_mainview(self):
282 | self.validate_navigationview()
283 | #ui seems to need to be portrait otherwise capture image view breaks
284 | self.navigation_view.present(orientations=['portrait'], title_bar_color=self.theme_manager.main_bar_colour, hide_title_bar=self.hide_title_bar)
285 | show_setting = self.settings_manager.get_setting_by_key('displayHowToClose')
286 | if show_setting == None:
287 | show_setting = True
288 | if self.hide_title_bar and show_setting:
289 | ToastView.display_toast(view=self.navigation_view, help_text='Close by swiping down with two fingers')
290 |
291 | def elementselectedcb(self, element):
292 | self.selectedElements.append(element)
293 | extraElements = self.element_manager.get_extra_elements_for_element(element)
294 | for ele in extraElements:
295 | self.selectedElements.append(ele)
296 | self.flow_creation_view.data_source.elements=self.selectedElements
297 | self.flow_creation_view.reload_data()
298 | self.close_elementsview()
299 |
300 | def savecb(self, saveElements):
301 | self.selectedElements = saveElements
302 | self.close_flowcreationview()
303 |
304 | def flowselectedcb(self, flow, autorun = False):
305 | self.selectedFlow = flow
306 | self.selectedFlowType = self.flow_manager.get_type_for_flow(flow)
307 | try:
308 | self.show_flowcreationview(None, autorun)
309 | except ValueError as e:
310 | self.show_alert(title='Error', message=str(e))
311 |
312 | @ui.in_background
313 | def show_alert(self, title, message):
314 | console.alert(title=title, message=message, button1='Ok', hide_cancel_button=True)
315 |
316 | def create_element(self, title, inputType, outputType, description, icon, category, canHandleList):
317 |
318 | self.element_manager.create_element(title=title, inputType=inputType, outputType=outputType, description=description, icon=icon, category=category, canHandleList=canHandleList)
319 | console.hud_alert('Element created')
320 | self.get_valid_elements()
321 | self.element_management_view.data_source.elements = self.elements
322 | self.element_management_view.reload_data()
323 | self.elements_view.data_source.elements = self.elements
324 | self.elements_view.reload_data()
325 | self.element_creation_view.reload()
326 |
327 | #@ui.in_background
328 | def runflow(self,sender):
329 | try:
330 | self.flow_creation_view.reload()
331 | ret, message= self.flow_manager.run_flow(self.selectedElements,self.navigation_view, self.selectedFlowType)
332 | if ret:
333 | self.show_alert(title='Complete', message=message)
334 | #console.alert(title='Complete',message=message,button1='Ok',hide_cancel_button=True)
335 | else:
336 | self.show_alert(title='Error', message=message)
337 | #console.alert(title='Error',message=message,button1='Ok',hide_cancel_button=True)
338 | except ValueError as e:
339 | self.show_alert(title='Error', message=str(e))
340 | #console.alert(str(e))
341 | self.flow_creation_view.data_source.currentElementNumber = -1
342 | self.flow_creation_view.reload()
343 |
344 | def elementchange(self, currentelementnumber):
345 | self.flow_creation_view.data_source.currentElementNumber = currentelementnumber
346 | self.flow_creation_view.reload()
347 |
348 | def main():
349 | m = ista()
350 | m.show_mainview()
351 |
352 | if __name__ == '__main__':
353 | main()
354 |
355 |
--------------------------------------------------------------------------------
/managers/ElementManager.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 |
4 | from __future__ import absolute_import
5 | from __future__ import print_function
6 | import os
7 | # from os import listdir # -> Is not an issue however it is neater to just import os
8 | # from os.path import isfile, join, splitext # --> join is a builtin method causing name space issues
9 | from importlib import import_module
10 | import sys
11 | import copy
12 | import imp
13 | sys.path.append('elements')
14 |
15 |
16 | class ElementManager (object):
17 | def __init__(self):
18 | self.elementsFolder = 'elements'
19 | self.elementExclusionList = ('ElementBase.py','__init__.py','Template.py','ElementParameter.py','ElementValue.py')
20 |
21 | self.requiredElementInstanceMethods = ('get_status', 'get_input', 'get_output','get_input_type', 'get_output_type', 'get_params','set_params', 'get_description', 'get_title','get_category', 'get_icon', 'run')
22 | self.extraElements = {'For':['End For'], 'Foreach':['End Foreach'],'If':['Else','End If']}
23 | sys.path.append('elements')
24 |
25 | def get_all_elements(self, element_type=None):
26 | elements = [
27 | os.path.splitext(f) for f in os.listdir(self.elementsFolder)
28 | if os.path.isfile(os.path.join(self.elementsFolder, f)) and
29 | not f in self.elementExclusionList
30 | ]
31 | validElements = []
32 | invalidElements = []
33 | for i in elements:
34 | mod = import_module(i[0])
35 | try:
36 | imp.reload(mod)
37 | except NameError:
38 | try:
39 | from importlib import reload
40 | imp.reload(mod)
41 | except ImportError:
42 | from imp import reload
43 | imp.reload(mod)
44 | klass = getattr(mod,i[0])
45 | klassIsValid = True
46 | for method in self.requiredElementInstanceMethods:
47 | if not hasattr(klass, method):
48 | klassIsValid = False
49 | break
50 | if klassIsValid:
51 | validElements.append(klass())
52 | else:
53 | invalidElements.append(klass())
54 |
55 | if not element_type:
56 | return {'valid':validElements, 'invalid':invalidElements}
57 | elif element_type == 'valid':
58 | return validElements
59 | elif element_type == 'invalid':
60 | return inValidElements
61 | else:
62 | return []
63 |
64 | def get_extra_elements_for_element(self, element):
65 | elementsToReturn = []
66 | if element.get_title() in self.extraElements:
67 | for ele in self.extraElements[element.get_title()]:
68 | elementsToReturn.append(self.get_element_with_title(ele))
69 | return elementsToReturn
70 |
71 | def get_element_class(self, element):
72 | # The element class is element.__class__
73 | return element.__class__.__name__
74 |
75 | def get_element_with_title(self, title):
76 | elements = self.get_all_elements('valid')
77 | for element in elements:
78 | if element.get_title() == title:
79 | return copy.deepcopy(element)
80 | return None
81 |
82 | def create_element(self, title, inputType, outputType, description, icon, category, canHandleList):
83 | if not inputType == None:
84 | inputType = "'"+inputType+"'"
85 | if not outputType == None:
86 | outputType = "'"+outputType+"'"
87 | titleValidated = title.replace(" ","")
88 | templatePath = os.path.join(self.elementsFolder, 'Template.py')
89 | elementPath = os.path.join(self.elementsFolder, "{fileName}.py".format(fileName=titleValidated))
90 | if os.path.isfile(elementPath):
91 | print('Element Already Exists')
92 | return
93 | with open(templatePath, 'r') as f:
94 | # str.format thinks that on line 8 ```self.params = {}``` and
95 | # on line 27 ```def set_params(self, params = {})``` are fomatting values
96 | tem = f.read().format(**{'title':titleValidated, 'title_space':title, 'input_type':inputType, 'output_type':outputType,'description':description,'icon':icon,'category':category,'canHandleList':canHandleList})
97 | with open(elementPath, 'w') as f:
98 | f.write(tem)
99 |
100 |
101 | if __name__ == '__main__':
102 | sys.path[-1] = '../elements'
103 | ElementManager.elementsFolder = '../elements'
104 | manager = ElementManager()
105 | print((manager.get_all_elements()))
106 | print((manager.get_element_with_title('newElement')))
107 | manager.create_element('newElement1')
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/managers/FlowManager.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | from __future__ import absolute_import
4 | import json
5 | import os
6 | import time
7 | import copy
8 | import appex
9 | import sys
10 | import clipboard
11 | import traceback
12 |
13 | class FlowManager (object):
14 | def __init__(self, elementchangecb):
15 | self.elementchangecb = elementchangecb
16 | self.runtime_variables = {}
17 | self.nav_view = None
18 | self.dir = 'flows/'
19 | if not os.path.exists(self.dir):
20 | os.mkdir(self.dir)
21 |
22 | def get_flows(self, appexonly):
23 | flows = os.listdir(self.dir)
24 | if appexonly:
25 | return [f for f in flows if self.get_type_for_flow(f) == 'Action Extension']
26 | else:
27 | return flows
28 |
29 | def save_flow(self, title, elements, type):
30 | names = []
31 | for ele in elements:
32 | params = {p.name: {'value':p.value if not p.askAtRuntime else None, 'useVariable':p.useVariable, 'variableName':p.variableName if not p.askAtRuntime else '', 'askAtRuntime':p.askAtRuntime} for p in (ele.get_params() or []) if p.display}
33 | ob = {'title':ele.get_title(),'params':params}
34 | names.append(ob)
35 | fl = {'type':type,'elements':names}
36 | f = open(self.dir+title+'.flow','w')
37 | f.write(json.JSONEncoder().encode(fl))
38 | f.close()
39 |
40 | def delete_flow(self, title):
41 | if os.path.exists(self.dir+title):
42 | os.remove(self.dir+title)
43 |
44 | def get_element_details_for_flow(self, flow):
45 | with open(self.dir+flow,'r') as f:
46 | return json.JSONDecoder().decode(f.read())['elements']
47 |
48 | def get_type_for_flow(self, flow):
49 | with open(self.dir+flow,'r') as f:
50 | return json.JSONDecoder().decode(f.read())['type']
51 |
52 | def run_flow(self, elements, navview, type):
53 | output = None
54 | prevOutputType = None
55 | elementNumber = 1
56 | foreachstore = None
57 | forstore = None
58 | ifstore = None
59 | self.nav_view = navview
60 | self.runtime_variables = {}
61 | if type == 'Action Extension' and not appex.is_running_extension():
62 | return False, 'Flow type: Action Extension flow not running in extension'
63 | try:
64 | while elementNumber<= len(elements):
65 | element = elements[elementNumber-1]
66 | self.elementchangecb(elementNumber)
67 | elementType = element.get_type()
68 | self.set_runtime_element_params(element)
69 | if element.get_input_type() == None:
70 | output = element.run()
71 | else:
72 | if prevOutputType == element.get_input_type() or element.get_input_type() == '*':
73 | if output == None or not isinstance(output.value,list) or element.can_handle_list():
74 | output = element.run(output)
75 | else:
76 | raise ValueError('List provided to ' + element.get_title() + ' and cant handle list')
77 | else:
78 | raise ValueError('Invalid input type provided to ' + element.get_title())
79 | self.get_runtime_element_params(element)
80 | prevOutputType = output.type if output else element.get_output_type()
81 | if elementType == 'Foreach':
82 | foreachstore = [output.copyMe(),elementNumber,len(output.value),0]
83 | output.value = foreachstore[0].value[foreachstore[3]]
84 | self.handle_foreach()
85 | elif elementType == 'EndForeach':
86 | foreachstore[3] += 1
87 | if foreachstore[3] < foreachstore[2]:
88 | elementNumber = foreachstore[1]
89 | output.type = foreachstore[0].type
90 | prevOutputType = output.type
91 | output.value = foreachstore[0].value[foreachstore[3]]
92 | else:
93 | foreachstore = None
94 | output = None
95 | elif elementType == 'For':
96 | forcount = element.get_param_by_name('forcount')
97 | if forcount == None:
98 | return False, 'For element count parameter not setup correctly'
99 | forstore = [elementNumber,forcount.value,0]
100 | elif elementType == 'EndFor':
101 | output = None
102 | forstore[2] += 1
103 | if forstore[2] < forstore[1]:
104 | elementNumber = forstore[0]
105 | else:
106 | forstore = None
107 | elif elementType == 'If':
108 | ifresult = element.get_param_by_name('ifresult')
109 | if ifresult == None or ifresult.value == None:
110 | return False, 'Result from if not found or is None, uisomething is wrong'
111 | if not ifresult.value:
112 | elsefound= False
113 | i = elementNumber
114 | skipnumber = 0
115 | while not elsefound:
116 | if i >= len(elements):
117 | return False, 'Else not found for if block'
118 | if elements[i].get_type() == 'If':
119 | skipnumber = skipnumber + 1
120 | if elements[i].get_type() == 'Else':
121 | if skipnumber > 0:
122 | skipnumber = skipnumber - 1
123 | i = i + 1
124 | else:
125 | elsefound = True
126 | elementNumber = i+1
127 | else:
128 | i = i+1
129 | elif elementType == 'Else':
130 | endiffound = False
131 | i = elementNumber
132 | skipnumber = 0
133 | while not endiffound:
134 | if i >= len(elements):
135 | return False, 'End If not found for if block'
136 | if elements[i].get_type() == 'If':
137 | skipnumber = skipnumber + 1
138 | if elements[i].get_type() == 'EndIf':
139 | if skipnumber > 0:
140 | skipnumber = skipnumber - 1
141 | i = i + 1
142 | else:
143 | endiffound = True
144 | elementNumber = i
145 | else:
146 | i = i+1
147 | elif elementType == 'EndIf':
148 | output = None
149 | ifstore = None
150 |
151 | elementNumber += 1
152 | elementNumber = 0
153 | self.elementchangecb(elementNumber)
154 | return True, 'Flow completed successfully'
155 | except KeyboardInterrupt:
156 | return False, 'Cancelled by user'
157 | except:
158 | return False, str(sys.exc_info()[1])
159 |
160 | def set_runtime_element_params(self, element):
161 | params = element.get_params()
162 | if params:
163 | for param in params:
164 | if param.name =='fm:runtime_variables':
165 | param.value = self.runtime_variables
166 | if param.name == 'fm:nav_view':
167 | param.value = self.nav_view
168 | if param.useVariable:
169 | element.get_runtime_variable_for_parameter(param)
170 | element.set_params(params)
171 |
172 | def get_runtime_element_params(self, element):
173 | for param in element.get_params() or []:
174 | if param.name == 'fm:runtime_variables':
175 | self.runtime_variables = param.value
176 |
177 | def handle_foreach(self):
178 | pass
179 |
180 | def copy_Flow_To_Clipboard(self, title):
181 | with open(self.dir+title,'r') as f:
182 | clipboard.set(f.read())
183 |
184 | def create_from_export(self, title, contents):
185 | f = open(self.dir+title+'.flow','w')
186 | f.write(contents)
187 | f.close()
188 |
189 |
190 |
--------------------------------------------------------------------------------
/managers/HomeScreenManager.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | # script modified from script in omz forum.
3 | import ui
4 | import dialogs
5 | from managers import WebClipper
6 | class HomeScreenManager (object):
7 | def __init__(self):
8 | self.fields = [{'type':'text','key':'Label','title':'Icon Label'}]
9 |
10 | @ui.in_background
11 | def show_form(self, flow_name):
12 | data = dialogs.form_dialog(title='Icon details', fields=self.fields )
13 | WebClipper.save(data['Label'], flow_name)
14 |
--------------------------------------------------------------------------------
/managers/SettingsManager.py:
--------------------------------------------------------------------------------
1 | import dialogs
2 | import json
3 | import os
4 | class SettingsManager (object):
5 | def __init__(self):
6 | self.fields = [{'type':'switch','key':'displayHowToClose','title':'Display how to close', 'value':True}]
7 | self.data = None
8 | self.filename = 'settings.json'
9 | self.load_file()
10 | self.update_fields()
11 |
12 | def show_form(self):
13 | self.data = dialogs.form_dialog(title='Settings', fields=self.fields )
14 | if not self.data == None:
15 | self.save_file()
16 | self.update_fields()
17 |
18 | def save_file(self):
19 | f = open(self.filename,'w+')
20 | f.write(json.JSONEncoder().encode(self.data))
21 | f.close()
22 |
23 | def load_file(self):
24 | if not os.path.isfile(self.filename):
25 | g = open(self.filename,'w+')
26 | g.write(json.JSONEncoder().encode({}))
27 | g.close()
28 | with open(self.filename,'r') as f:
29 | self.data = json.JSONDecoder().decode(f.read())
30 |
31 | def update_fields(self):
32 | if not self.data == None:
33 | for f in self.fields:
34 | if f['key'] in self.data.keys():
35 | f['value'] = self.data[f['key']]
36 |
37 | def get_setting_by_key(self, key):
38 | self.load_file()
39 | if not self.data == None:
40 | if key in self.data.keys():
41 | return self.data[key]
42 | return self.get_field_value_by_key(key)
43 |
44 | def get_field_value_by_key(self,key):
45 | for f in self.fields:
46 | if f['key'] == key:
47 | return f['value']
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/managers/ThemeManager.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | class ThemeManager (object):
3 | def __init__(self):
4 | self.main_background_colour = .85, .85, .85
5 | self.main_text_colour = .31, .31, .31
6 | self.main_bar_colour = .85,.85,.85
7 | self.main_tint_colour = .31,.31,.31
8 | self.main_title_text_colour = .31,.31,.31
9 | self.running_cell_background_colour = .1, .18, 1.0
10 | self.running_cell_text_colour = 1.0, 1.0, 1.0
11 |
--------------------------------------------------------------------------------
/managers/WebClipper.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # modified scripts from
3 | # https://forum.omz-software.com/topic/2271/beta-suggestion-safariviewcontroller/2
4 |
5 | from __future__ import absolute_import
6 | from __future__ import print_function
7 | import uuid, six.moves.BaseHTTPServer, select, types, clipboard, console, webbrowser
8 | import urllib
9 | from six.moves.SimpleHTTPServer import SimpleHTTPRequestHandler
10 | try:
11 | from cStringIO import StringIO
12 | except ImportError:
13 | from io import StringIO
14 |
15 | from objc_util import *
16 |
17 | SFSafariViewController = ObjCClass('SFSafariViewController')
18 |
19 | global mobile_config_str
20 | mobile_config_str = ''
21 |
22 | global base_mobileconfig
23 | base_mobileconfig = ''
24 |
25 | global keep_running
26 | keep_running = True
27 |
28 | # The Icon key contains a base64 encoded green version of the Pythonista low-res
29 | # icon (for shortness)
30 |
31 | base_mobileconfig = """
32 |
33 |