Editorial Workflows

RV: Forums New Discussion

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: Allows you to start new discussion at omz:software Forums. Either in Pythonista or Editorial forum with appropriately groups.

Editor text is used.

Privacy - Workflow asks for your username/password. Credentials are not stored anywhere. They are used to obtain auth cookie (generated mess) only. Auth cookie is stored in iOS keychain and restored next time you'll try to start new discussion. To delete auth cookie from iOS keychain run this workflow and tap on Logout button in navigation bar.

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 editor
import requests
import console
import requests
import keychain
import ui

#
# Requests settings
#
BASE_URL   	= 'https://omz-forums.appspot.com'
LOGIN_URL   = '%s/login' % BASE_URL
COOKIE_NAME = 'auth'

#
# Keychain settings
#
KEYCHAIN_SERVICE = 'omz:software Forums'
KEYCHAIN_ACCOUNT = 'Cookie'

#
# Forums Settings
#
FORUM_TITLES = [
	'Editorial',
	'Pythonista'
]

FORUM_CATEGORIES = [
	[ 'General', 'Workflows', 'Questions' ],
	[ 'General', 'Share Code', 'Questions' ]
]

FORUM_POST_URL = [
	'/editorial/new',
	'/pythonista/new'                  
]

FORUM_HIDDEN_PARAMS = [
	{
	 	'forum' : 'editorial'
	},
	{
	 	'forum' : 'pythonista'
	}
]
	
#
# Return auth cookie from iOS keychain. Login dialog appears if not set.
# Cookie is stored in iOS keychain upon successful login is returned.
#
def login():
	cookie = keychain.get_password(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT)
	if not cookie is None:
		return cookie

	while cookie is None:
		(username, password) = console.login_alert('omz:software Forums','Your credentials will not be stored on this device and are used to obtain authorization cookie only.', '', '', 'Login')
	
		params = {}
		params['redirect'] = ''
		params['username'] = username
		params['password'] = password
	
		console.show_activity()
		response = requests.request('POST', LOGIN_URL, params=params, allow_redirects=True)
		console.hide_activity()
	
		if response.status_code == 200:
			cookie = response.cookies.get(COOKIE_NAME, None)
			if not cookie is None:
				keychain.set_password(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, cookie)
				return cookie
			
		console.hud_alert('Failed to login, try again', 'error')

#
# UI Elements
#
UI_FORUM_CONTROL    = 'forumSegmentedcontrol'
UI_CATEGORY_CONTROL = 'categorySegmentedcontrol'
UI_TITLE_FIELD      = 'titleTextfield'

#
# UI
#
class DiscussionView(ui.View):
	def __init__(self):
		self.cookie = None
		self.text = None
		self.name = 'Start Discussion'
		
	# Initial UI setup
	def did_load(self):
		self.title_text_field = self[UI_TITLE_FIELD]
		self.forum_segmented_control = self[UI_FORUM_CONTROL]
		self.category_segmented_control = self[UI_CATEGORY_CONTROL]
		
		self.title_text_field.delegate = self
		self.title_text_field.clear_button_mode = 'editing'
		
		self.forum_segmented_control.action = self.update_categories
				
		self.init_segmented_controls()
		self.title_text_field.begin_editing()
		
		self.cancel_item = ui.ButtonItem(title='Cancel', action=self.cancel)
		self.logout_item = ui.ButtonItem(title='Logout', action=self.logout)
		self.post_item = ui.ButtonItem(title='Post', action=self.post)
		self.left_button_items = [ self.cancel_item, self.logout_item ]
		self.right_button_items = [ self.post_item ]
		
	# User interaction
	def cancel(self,sender):
		self.navigation_view.close()
		
	# Initial segmented controls content		
	def init_segmented_controls(self):
		self.forum_segmented_control.segments = FORUM_TITLES
		self.forum_segmented_control.selected_index = 0
		self.update_categories(self.forum_segmented_control)			
		
	# Called when forum segmented control selected index was changed	
	def update_categories(self, forum_segmented_control):
		index = forum_segmented_control.selected_index
		self.category_segmented_control.segments = FORUM_CATEGORIES[index]
		self.category_segmented_control.selected_index = 0
		
	# Called when you hit Enter key when editing title textfield	
	def textfield_should_return(self,textfield):
		if len(textfield.text) == 0:
			return False
			
		self.post(textfield)
		return True	

	# Return discussion text with added footer		
	def discussion_text(self):
		return '%s\n\n-- \nDiscussion started with [RV: Forums New Discussion workflow](http://www.editorial-workflows.com/workflow/5858454442868736/n1ho-qD_CQs)' % self.text
				
	# UI Post button action			
	def post(self, sender):
		if self.is_form_valid() == False:
			console.hud_alert('Title not filled', 'error')
			return

		forum_index = self.forum_segmented_control.selected_index
		category_index = self.category_segmented_control.selected_index
		
		post_url = '%s%s' % ( BASE_URL, FORUM_POST_URL[forum_index] )
		
		params = FORUM_HIDDEN_PARAMS[forum_index].copy()			
		params['title'] = self.title_text_field.text
		params['category'] = FORUM_CATEGORIES[forum_index][category_index]
		params['text'] = self.discussion_text()
				
		cookies = {}
		cookies[COOKIE_NAME] = self.cookie

		self.set_controls_enabled(False)
		console.show_activity()
		response = requests.post(post_url, data=params, cookies=cookies)
		console.hide_activity()
		self.set_controls_enabled(True)
		
		failed = True
		if response.status_code == 200:
			# Feel free to come up with better check
			if '"/logout"' in response.text and '"/profile"' in response.text:
				failed = False
			
		if failed:
			console.hud_alert('Failed to start discussion', 'error')
		else:
			console.hud_alert('Discussion started', 'success')
								
		self.navigation_view.close()
		
	# Helper to disable/enable all UI controls				
	def set_controls_enabled(self,enabled):
		self.category_segmented_control.enabled = enabled
		self.forum_segmented_control.enabled = enabled
		self.title_text_field.enabled = enabled
		self.cancel_item.enabled = enabled
		self.post_item.enabled = enabled
		self.logout_item.enabled = enabled
					
	# UI Logout button action							
	def logout(self, sender):
		keychain.delete_password(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT)
		self.navigation_view.close()
		
	# Form validation helper	
	def is_form_valid(self):
		return len(self.title_text_field.text) > 0

#
# Main
#
path = editor.get_path()
if path is None:
	console.hud_alert('Open some file first', 'error')
	workflow.stop()

text = editor.get_text()
if len(text) == 0:
	console.hud_alert('Write some text first', 'error')
	workflow.stop()	                 

cookie = login()
if cookie is None or len(cookie) == 0:
	console.hud_alert('Authorization failed, please, try again.', 'error')
	workflow.stop()

view = ui.load_view()
view.cookie = cookie
view.text = text

navigation = ui.NavigationView(view)
navigation.present(style='sheet', hide_title_bar=True)