-
Notifications
You must be signed in to change notification settings - Fork 319
Extending Scumblr
Scumblr can be extended in a variety of ways including adding new workflows and new search providers. These capabilities will be discussed in this section.
Scumblr uses the Workflowable gem (www.github.com/netflix/workflowable) to allow defining flexible workflows for actioning results. This section will give a brief overview of workflows. For more information about setting up and defining workflows, see the Workflowable wiki.
In Scumblr, results can be assigned one or more workflows. This is done by adding a workflow flag from the Result view page (as discussed in the Workflow Flags section above). Once a workflow flag has been added, the result can be moved through the various phases from the result view page.
This section will give a brief overview of the concepts used by the Workflowable gem.
Workflow: A process, generally with multiple, ordered stages
Stage: A state within the process
Initial stage: The state the workflow starts in
Action: A function that gets run as part of adding a workflow to an item or moving between stages
Before action: An action that gets run when transitioning into a specific stage
After action: An action that gets run when transitioning out of a specific stage
Global action: An action that gets run when between any stage, including moving into the initial stage (i.e. when a result is first flagged)
In order to use workflows, we first need to create one. This can be done from the Workflowable admin page (available at /workflowable or from the Admin menu). Please see the workflowable wiki for detailed instructions on setting up a workflow.
Once the workflow has been setup from the Workflowable admin page, we also need to create a Workflow Flag that can be used in Scumblr. This can be done from the Flag admin page (in the admin menu).
Workflowable allow defining custom actions that can be run when flagging a result with a workflow and/or when moving between stages. These actions are developed as classes and need to conform to the API defined by workflowable (see the Workflowable wiki). Action classes should be stored in the lib/workflowable/actions folder.
You will need to have already created the workflow through the workflowable admin page. Once this is complete, go to the Flag admin page and click "New Flag". Here you can choose a name for the workflow (which will be used in Scumblr), a description for the workflow, and add any subscribers who, if Scumblr is setup to send email, will receive notifications when a result is flagged for this workflow. You will additionally need to choose the workflow to associate with the flag by choosing it from the dropdown box. This box is populated based on the workflows created in the workflowable admin page.
Once the flag has been created it is ready to be used in Scumbr. See the "Workflow Flags" section above for instructions on how to assign and use workflows from the result view page.
It is possible to define new search providers that are capable of searching for and identifying results. This is done by implemnting a class that conform to the search provider API and placing the provider file in lib/providers. All search providers should be a subclass of SearchProvider::Provider.
A search provider generally needs to implement 4 functions:
self.provider_name: This function allow Scumblr to retrieve and present a readable name for the provider
self.options: This function allow defined what options can/should be passed into the provider. These options are defined when creating the Search
initialize(query, options={}): This function is often overridden in order to retrieve an access token from the configuration or otherwise setup the provider
run: This function performs the search and returns the results
Parameters: None
Return Value: String
This simple function returns the provider name when called Scumblr needs to get the human readable name for the provider. For example SeachProvider::AppStore.provider_name will return "Apple Store Search"
Parameters: None
Return Value: options (hash)
This function will return a hash that defines which options can/should be passed in when running a search. Options are defined when an individual search is created.
key: (symbol) A key used to identify the option value. Each option must have a unique key
value: (hash) This will contain information about the option:
value[:name] (string) The name of the option
value[:description] (string) A description of the option
value[:requred] (boolean) Is the option required
{
:results=>{name: "Max results (200)", description: "Specifiy the number of results to retrieve", required: false},
:require_all_terms=>{name: "Require all terms", description: "If set to \"true\" will ensure all search terms contained in result", required: false}
}
If self.options returns this hash, the provider will have two optional options that can be defined when creating a search: "Max results (200)" and "Require all terms"
Parameters: query (string), options (hash, optional)
Return Value: None
The default initializer will set the query to @query and the options to @options. These values (@query, @options) can be accessed from the run function. If the initializer is overridden, the overriding function can call "super" to setup these values, or overriding function can setup the appropriate values for the run function itself.
This function is often used to pull API keys or other credentials from the config file. If using the convention used for the out of the box search providers, this data should be put in config/initializers/scumbr.rb and would be accessed using:
Rails.configuration.try(:<OPTION NAME>)
Parameters: None
Return Value: results (array of results hashes)
The run function should perform the search and return any identified results. If using the default initalizer, the query to search will be stored in @query and the options in @options. Options can be accessed using the same key as that used in the options hash. So, for example, if the options hash defined an options ":results", this value would be retrieved using @options[:results]
title: (string) The title of the result
url: (string) The url for the result
domain: (string) The result's domain
metadata: (hash) An (optional) hash of additional metadata to store with the result
[
{title: "Netflix", url: "http://www.netlfix.com", domain: "www.netflix.com", metadata: {priority: 1}
{title: "Netflix Blog", url: "http://blog.netlfix.com/page1", domain: "blog.netflix.com", metadata: {priority: 2}
]
This example includes 2 results: one for the Netflix main site and one for the Netflix Blog. These results would be imported into Scumbr, if not previously identified.
Below is a simple sample of a search provider class. This class will not perform a search, but should provide guidence on what a Search Provider class should look like:
class SearchProvider::FakeSearch < SearchProvider::Provider
def self.provider_name
"Fake Search"
end
def self.options
{
:max_result=>{name: "Max Results", description: "The maximum number of results to retrieve", required: false}
}
end
def initialize(query, options={})
super
@access_token = Rails.configuration.try(:simple_search_token)
end
def run
if(@access_token.blank?)
Rails.logger.error "Unable to run Simple Search. Please define an access key as simple_search_token in the Scumblr initializer."
return
end
# RUN SEARCH HERE
# Fake results
result = [
{title: "Netflix", url: "http://www.netlfix.com", domain: "www.netflix.com", metadata: {priority: 1}
{title: "Netflix Blog", url: "http://blog.netlfix.com/page1", domain: "blog.netflix.com", metadata: {priority: 2}
]
return results
end
end