Editorial Workflows

RV: Workflow to Module

public workflow

Install Workflow...

This workflow contains at least one Python script. Only use it if you trust the person who shared this with you, and if you know exactly what it does.

I understand, install the workflow!

This is a workflow for Editorial, a Markdown and plain text editor for iOS. To download it, you need to view this page on a device that has the app installed.

Description: Workflow to module converter. You can't edit .py files in Editorial, but what if you want to share functionality between workflows? Write your Python code in Run Python Script action and then convert it to module.

Sample:

* download sample module (see below)
* edit sample module workflow Python script
* downlad this workflow
* run this workflow, select 'RV: Sample Module' workflow, enter 'sample' as filename and tap on Conver button
* download sample module usage (see below)
* run sample module usage workflow, which does use 'sample.py' module created during previous steps

Sample module:

http://www.editorial-workflows.com/workflow/5794198980657152/aoF_bd47DIo

Sample module usage:

http://www.editorial-workflows.com/workflow/5268983267721216/yIi95Xmz_SY

Check RV: Module Manager [1] workflow to manage installed modules.

[1] http://www.editorial-workflows.com/workflow/5842870892232704/uJ-jxXqWZlc

Shared by: @robertvojta

Comments: Comment Feed (RSS)

There are no comments yet.

+ Add Comment

Workflow Preview
Run Python Script ?
Source Code
#coding: utf-8
import workflow
import json
import os
import editor
import console
import ui

def installed_workflows():
	"""Sequence of locally installed workflows (JSON from Commands.edcmd)"""
	path = os.path.join(editor.get_workflows_path(), 'Commands.edcmd')
	if not os.path.exists(path):
		return []
		
	workflows = []
	with open(path, 'r') as file:
		workflows = json.load(file)
		
	return workflows
	
	
def workflow_data_path(workflow):
	return os.path.join(editor.get_workflows_path(), workflow['filename'])
	
	
def is_convertible_to_module(workflow):
	"""Return True if workflow does contain exactly one Run Python Script action otherwise False"""
	path = workflow_data_path(workflow)
	if not os.path.exists(path):	
		return False

	with open(path, 'r') as file:
		data = json.load(file)
	
	if data.get('actions', None) == None:
		return False

	actions = data.get('actions')
	
	script_actions = [x for x in actions if x['class'] == 'WorkflowActionRunScript']
	if len(script_actions) != 1:
		return False
						
	script_action = script_actions[0]
	if script_action.get('parameters', None) == None:
		return False
		
	parameters = script_action.get('parameters')
	return parameters.get('script', None) != None
	
	
def convert_workflow_to_module(workflow, filename):
	print 'Converting \'%s\' workflow to module' % workflow['title']
	if os.path.splitext(filename)[1] != '.py':
		filename = filename + '.py'
		
	dir = os.path.join(os.path.expanduser('~/Documents'), 'site-packages')
	if not os.path.exists(dir):
		print 'Creating site-packages directory'
		os.mkdir(dir)
		
	print 'Getting workflow script ...'
	data_path = workflow_data_path(workflow)
	with open(data_path, 'r') as file:
		data = json.load(file)	
		
	actions = data['actions']	
	script_actions = [x for x in actions if x['class'] == 'WorkflowActionRunScript']
	script = script_actions[0]['parameters']['script']
		
	path = os.path.join(dir, filename)
	print 'Writing module ...'
	with open(path, 'w') as file:
		file.write(script)
		
	print 'Done, you can now \'import %s\'' % os.path.splitext(filename)[0]
		
	
class WorkflowPickerView(ui.View):
	def __init__(self, workflows):
		self.workflows = workflows
		self.name = 'Select Workflow'
		
		ds = ui.ListDataSource([x['title'] for x in workflows])
		ds.action = self.did_select_workflow
		
		self.tableview = ui.TableView()
		self.tableview.frame = self.bounds
		self.tableview.flex = 'WH'
		self.tableview.data_source = ds
		self.tableview.delegate = ds
		self.add_subview(self.tableview)
		
		cancel_item = ui.ButtonItem(title='Cancel', action=self.cancel)
		self.left_button_items = [cancel_item]
		
	def cancel(self, sender):
		self.navigation_view.close()
		
	def did_select_workflow(self, sender):
		workflow = self.workflows[sender.selected_row]
		view = ModuleNameView(workflow)
		self.navigation_view.push_view(view)
		
		
class ModuleNameView(ui.View):
	def __init__(self, workflow):
		self.workflow = workflow
		self.name = 'Module Name'
		
		self.label = ui.Label()
		self.label.frame = ( 6, 6, self.bounds[3] - 12, 32)
		self.label.flex = 'W'
		self.label.text = 'Enter module file name'
		self.add_subview(self.label)
		
		self.textfield = ui.TextField()
		self.textfield.frame = ( 6, 46, self.bounds[3] - 12, 32 )
		self.textfield.flex = 'W'
		self.textfield.delegate = self
		self.add_subview(self.textfield)
		
		title = self.workflow['title']
		module_prefix = 'Module: '
		if title.startswith(module_prefix):
			self.textfield.text = title[len(module_prefix):]
		
		convert_item = ui.ButtonItem(title='Convert', action=self.convert)
		self.right_button_items = [convert_item]
		
		self.textfield.begin_editing()
				
	def textfield_should_return(self, textfield):
		valid, _ = self.validate_module_filename()
		if valid:
			textfield.end_editing()
			self.convert(None)
			return True			
		return False
		
	def module_filename(self):
		return self.textfield.text.strip()
		
	def validate_module_filename(self):
		filename = self.module_filename()
		if len(filename) == 0:
			console.hud_alert('Enter filename', 'error', 1.0)
			return (False, filename)
		return (True, filename)
		
	@ui.in_background
	def convert(self, sender):
		valid, filename = self.validate_module_filename()
		if not valid:
			return
			
		self.navigation_view.close()
		convert_workflow_to_module(self.workflow, filename)


def main():
	convertible_workflows = [x for x in installed_workflows() if is_convertible_to_module(x)]
	if len(convertible_workflows) == 0:
		console.alert('Error', 'No convertible workflows found. Convertible workflow must contain exactly one Run Python Script action.', 'OK')
		workflow.stop()

	picker = WorkflowPickerView(convertible_workflows)
	nav = ui.NavigationView(picker)
	nav.present(style='sheet', hide_title_bar=True)
	
	
main()